sanitize-filename-0.4.0/.cargo_vcs_info.json0000644000000001360000000000100144410ustar { "git": { "sha1": "c8aec7e0cb2d9b93453d3a3b53611d6d3abf6042" }, "path_in_vcs": "" }sanitize-filename-0.4.0/.gitignore000075500000000000000000000000230072674642500152470ustar 00000000000000/target **/*.rs.bk sanitize-filename-0.4.0/Cargo.lock0000644000000020240000000000100124120ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "lazy_static" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" dependencies = [ "version_check", ] [[package]] name = "regex" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" dependencies = [ "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" [[package]] name = "sanitize-filename" version = "0.4.0" dependencies = [ "lazy_static", "regex", ] [[package]] name = "version_check" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" sanitize-filename-0.4.0/Cargo.toml0000644000000016260000000000100124440ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] name = "sanitize-filename" version = "0.4.0" authors = ["Jacob Brown "] description = "A simple filename sanitizer, based on Node's sanitize-filename" readme = "README.md" keywords = ["filename", "sanitizer"] license = "MIT" repository = "https://github.com/kardeiz/sanitize-filename" [dependencies.lazy_static] version = "1" [dependencies.regex] version = "1" features = ["std", "unicode-case"] default-features = false sanitize-filename-0.4.0/Cargo.toml.orig000075500000000000000000000006640072674642500161610ustar 00000000000000[package] authors = ["Jacob Brown "] name = "sanitize-filename" version = "0.4.0" keywords = ["filename", "sanitizer"] license = "MIT" readme = "README.md" repository = "https://github.com/kardeiz/sanitize-filename" description = "A simple filename sanitizer, based on Node's sanitize-filename" [dependencies] lazy_static = "1" regex = { version = "1", default-features = false, features = ["std", "unicode-case"] } sanitize-filename-0.4.0/README.md000075500000000000000000000022620072674642500145450ustar 00000000000000# sanitize-filename A basic filename sanitizer, based on Node's [sanitize-filename](https://www.npmjs.com/package/sanitize-filename). Use like: ```rust extern crate sanitize_filename; fn main() { println!("{}", sanitize_filename::sanitize("some-user-defined/../../../string")); // prints some-user-defined......string } ``` You can also configure a few basic options: ```rust let options = sanitize_filename::Options { truncate: true, // true by default, truncates to 255 bytes windows: true, // default value depends on the OS, removes reserved names like `con` from start of strings on Windows replacement: "" // str to replace sanitized chars/strings }; let sanitized = sanitize_filename::sanitize_with_options("some-user-defined/../../../string", options); ``` Also provides a basic command line binary. Use like: ```bash cargo install sanitize-filename sanitize-filename my_filename.txt ``` ``` Pass a file name to clean to the program (also reads STDIN) FLAGS: -r, --replace Replacement characters --windows, --no-windows Whether to handle filenames for Windows --truncate, --no-truncate Whether to truncate file names to 255 bytes ``` sanitize-filename-0.4.0/src/lib.rs000075500000000000000000000151730072674642500151760ustar 00000000000000extern crate regex; #[macro_use] extern crate lazy_static; use regex::{Regex, RegexBuilder}; lazy_static! { static ref ILLEGAL_RE: Regex = Regex::new(r#"[/\?<>\\:\*\|":]"#).unwrap(); static ref CONTROL_RE: Regex = Regex::new(r#"[\x00-\x1f\x80-\x9f]"#).unwrap(); static ref RESERVED_RE: Regex = Regex::new(r#"^\.+$"#).unwrap(); static ref WINDOWS_RESERVED_RE: Regex = RegexBuilder::new(r#"(?i)^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$"#) .case_insensitive(true) .build() .unwrap(); static ref WINDOWS_TRAILING_RE: Regex = Regex::new(r#"^\.+$"#).unwrap(); } #[derive(Clone)] pub struct Options<'a> { pub windows: bool, pub truncate: bool, pub replacement: &'a str } impl<'a> Default for Options<'a> { fn default() -> Self { Options { windows: cfg!(windows), truncate: true, replacement: "" } } } pub fn sanitize>(name: S) -> String { sanitize_with_options(name, Options::default()) } pub fn sanitize_with_options>(name: S, options: Options) -> String { let Options { windows, truncate, replacement } = options; let name = name.as_ref(); let name = ILLEGAL_RE.replace_all(&name, replacement); let name = CONTROL_RE.replace_all(&name, replacement); let name = RESERVED_RE.replace(&name, replacement); let collect = |name: ::std::borrow::Cow| { if truncate && name.len() > 255 { let mut end = 255; loop { if name.is_char_boundary(end) { break; } end -= 1; } String::from(&name[..end]) } else { String::from(name) } }; if windows { let name = WINDOWS_RESERVED_RE.replace(&name, replacement); let name = WINDOWS_TRAILING_RE.replace(&name, replacement); collect(name) } else { collect(name) } } #[derive(Clone)] pub struct OptionsForCheck { pub windows: bool, pub truncate: bool, } impl Default for OptionsForCheck { fn default() -> Self { OptionsForCheck { windows: cfg!(windows), truncate: true, } } } pub fn is_sanitized>(name: S) -> bool { is_sanitized_with_options(name, OptionsForCheck::default()) } pub fn is_sanitized_with_options>(name: S, options: OptionsForCheck) -> bool { let OptionsForCheck { windows, truncate } = options; let name = name.as_ref(); if ILLEGAL_RE.is_match(&name) { return false; } if CONTROL_RE.is_match(&name) { return false; } if RESERVED_RE.is_match(&name) { return false; } if truncate && name.len() > 255 { return false; } if windows { if WINDOWS_RESERVED_RE.is_match(&name) { return false; } if WINDOWS_TRAILING_RE.is_match(&name) { return false; } } return true; } #[cfg(test)] mod tests { // From https://github.com/parshap/node-sanitize-filename/blob/master/test.js static NAMES: &'static [&'static str] = &[ "the quick brown fox jumped over the lazy dog", "résumé", "hello\u{0000}world", "hello\nworld", "semi;colon.js", ";leading-semi.js", "slash\\.js", "slash/.js", "col:on.js", "star*.js", "question?.js", "quote\".js", "singlequote'.js", "brackts.js", "p|pes.js", "plus+.js", "'five and six(); let shorter = ::std::iter::repeat('a').take(255).collect::(); assert_eq!(super::sanitize_with_options(long, options.clone()), shorter); // is_sanitized let options = super::OptionsForCheck { windows: true, truncate: true, }; for (idx, name) in NAMES.iter().enumerate() { assert_eq!(super::is_sanitized_with_options(name, options.clone()), NAMES_IS_SANITIZED[idx]); } let long = ::std::iter::repeat('a').take(300).collect::(); assert_eq!(super::is_sanitized_with_options(long, options.clone()), false); } }sanitize-filename-0.4.0/src/main.rs000075500000000000000000000030260072674642500153460ustar 00000000000000extern crate sanitize_filename; fn main() -> Result<(), ::std::io::Error> { let mut input = None; let mut set_replacement = false; let mut replacement = None; let mut truncate = None; let mut windows = None; for arg in ::std::env::args().skip(1) { if set_replacement { replacement = Some(arg); set_replacement = false; } else if arg == "-r" || arg == "--replace" { set_replacement = true; } else if arg == "--truncate" { truncate = Some(true); } else if arg == "--no-truncate" { truncate = Some(false); } else if arg == "--windows" { windows = Some(true); } else if arg == "--no-windows" { windows = Some(false); } else if arg == "-" { input = None; } else { input = Some(arg); } } let input = if let Some(input) = input { input } else { let mut buffer = String::new(); ::std::io::Read::read_to_string(&mut ::std::io::stdin(), &mut buffer)?; buffer }; let mut options = sanitize_filename::Options::default(); if let Some(ref replacement) = replacement { options.replacement = replacement; } if let Some(windows) = windows { options.windows = windows; } if let Some(truncate) = truncate { options.truncate = truncate; } let output = sanitize_filename::sanitize_with_options(input, options); println!("{}", &output); Ok(()) }