diff --git a/CHANGELOG.md b/CHANGELOG.md index 535130b..16a3c51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ Changelog UNRELEASED - 2020-04-22 ----------------------- -- :zap: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Allow positional input to `imdl torrent verify` - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ +- :art: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Use `lexiclean` crate for lexical path cleaning - _Casey Rodarmor _ +- :zap: [`323434d0aa21`](https://github.com/casey/intermodal/commit/323434d0aa21ebfda5be85ecd4a38a55ed3fec0a) Allow positional input to `imdl torrent verify` - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ - :zap: [`5ba885dbc4f2`](https://github.com/casey/intermodal/commit/5ba885dbc4f24781d6a3240ddfc0c03177b12f1e) Take input to `imdl torrent create` as positional - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ - :wrench: [`c22df5a08326`](https://github.com/casey/intermodal/commit/c22df5a083265b03abd5531b1f5b2aad60aa68cd) Don't commit man pages - _Casey Rodarmor _ - :wrench: [`4d67d3a10d17`](https://github.com/casey/intermodal/commit/4d67d3a10d17db3c63af092a936eb5994ee107b1) Don't commit the book - _Casey Rodarmor _ diff --git a/Cargo.lock b/Cargo.lock index d09eb97..f3a6353 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -499,6 +499,7 @@ dependencies = [ "ignore", "imdl-indicatif", "lazy_static", + "lexiclean", "libc", "log", "md5", @@ -560,6 +561,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lexiclean" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb11deb06ea520b5110c0841c00625ee9f3369782c9fdcf22a400105b44462b" + [[package]] name = "libc" version = "0.2.69" diff --git a/Cargo.toml b/Cargo.toml index a5fa383..9502c8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,11 @@ atty = "0.2.0" chrono = "0.4.1" console = "0.10.0" globset = "0.4.0" +ignore = "0.4.14" lazy_static = "1.4.0" +lexiclean = "0.0.0" libc = "0.2.0" log = "0.4.8" -ignore = "0.4.14" md5 = "0.7.0" open = "1.4.0" pretty_assertions = "0.6.0" diff --git a/src/common.rs b/src/common.rs index e6f162b..a799f4a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -29,6 +29,7 @@ pub(crate) use chrono::{TimeZone, Utc}; pub(crate) use globset::{Glob, GlobMatcher}; pub(crate) use ignore::WalkBuilder; pub(crate) use indicatif::{ProgressBar, ProgressStyle}; +pub(crate) use lexiclean::Lexiclean; pub(crate) use libc::EXIT_FAILURE; pub(crate) use regex::{Regex, RegexSet}; pub(crate) use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer}; @@ -59,8 +60,7 @@ pub(crate) use crate::xor_args::xor_args; // traits pub(crate) use crate::{ input_stream::InputStream, into_u64::IntoU64, into_usize::IntoUsize, invariant::Invariant, - path_ext::PathExt, platform_interface::PlatformInterface, print::Print, reckoner::Reckoner, - step::Step, + platform_interface::PlatformInterface, print::Print, reckoner::Reckoner, step::Step, }; // structs and enums diff --git a/src/env.rs b/src/env.rs index 30c51e7..759ca1f 100644 --- a/src/env.rs +++ b/src/env.rs @@ -189,7 +189,7 @@ impl Env { return Err(Error::internal("Empty path passed to resolve")); } - Ok(self.dir().join(path).clean()) + Ok(self.dir().join(path).lexiclean()) } pub(crate) fn write(&mut self, path: impl AsRef, contents: impl AsRef<[u8]>) -> Result<()> { diff --git a/src/main.rs b/src/main.rs index 46d1052..31bb9b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,7 +79,6 @@ mod mode; mod options; mod output_stream; mod output_target; -mod path_ext; mod piece_length_picker; mod piece_list; mod platform; diff --git a/src/path_ext.rs b/src/path_ext.rs deleted file mode 100644 index 7d259fc..0000000 --- a/src/path_ext.rs +++ /dev/null @@ -1,89 +0,0 @@ -use crate::common::*; - -use std::path::Component; - -pub(crate) trait PathExt { - fn clean(self) -> PathBuf; -} - -impl PathExt for &Path { - fn clean(self) -> PathBuf { - if self.components().count() <= 1 { - return self.to_owned(); - } - - let mut components = Vec::new(); - - for component in self - .components() - .filter(|component| component != &Component::CurDir) - { - if component == Component::ParentDir { - match components.last() { - Some(Component::Normal(_)) => { - components.pop(); - } - Some(Component::ParentDir) | None => components.push(component), - _ => {} - } - } else { - components.push(component); - } - } - - components.into_iter().collect() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[rustfmt::skip] - fn prefix_suffix() { - fn case(prefix: &str, suffix: &str, want: &str) { - let have = Path::new(prefix).join(Path::new(suffix)).clean(); - assert_eq!(have, Path::new(want)); - } - - { - case("/", "foo", "/foo"); - case("/", "." , "/"); - case("/", "foo/./bar", "/foo/bar"); - case("/foo/./bar", ".", "/foo/bar"); - case("/bar", "/foo", "/foo"); - case("//foo", "bar//baz", "/foo/bar/baz"); - case("/", "..", "/"); - case("/", "/..", "/"); - case("/..", "", "/"); - case("/../../../..", "../../../", "/"); - case("/.", "./", "/"); - case("/foo/../", "bar", "/bar"); - case("/foo/bar", "..", "/foo"); - case("/foo/bar/", "..", "/foo"); - } - } - - #[test] - #[rustfmt::skip] - fn simple() { - fn case(path: &str, want: &str) { - assert_eq!(Path::new(path).clean(), Path::new(want)); - } - - case("./..", ".."); - case("./././.", "."); - case("./../.", ".."); - case("..", ".."); - case("", ""); - case("foo", "foo"); - case(".", "."); - case("foo/./bar", "foo/bar"); - case("/foo", "/foo"); - case("bar//baz", "bar/baz"); - case("/..", "/"); - case("../../../", "../../.."); - case("./", "."); - } -} diff --git a/src/subcommand/torrent/create/create_content.rs b/src/subcommand/torrent/create/create_content.rs index e04fefc..ea1e5a1 100644 --- a/src/subcommand/torrent/create/create_content.rs +++ b/src/subcommand/torrent/create/create_content.rs @@ -107,7 +107,10 @@ impl CreateContent { } fn torrent_path(input: &Path, name: &str) -> PathBuf { - input.join("..").clean().join(format!("{}.torrent", name)) + input + .join("..") + .lexiclean() + .join(format!("{}.torrent", name)) } } diff --git a/src/subcommand/torrent/verify.rs b/src/subcommand/torrent/verify.rs index cc671aa..7ce04bb 100644 --- a/src/subcommand/torrent/verify.rs +++ b/src/subcommand/torrent/verify.rs @@ -70,7 +70,7 @@ impl Verify { content.clone() } else { match target { - InputTarget::Path(path) => path.join("..").join(&metainfo.info.name).clean(), + InputTarget::Path(path) => path.join("..").join(&metainfo.info.name).lexiclean(), InputTarget::Stdin => PathBuf::from(&metainfo.info.name), } };