Use lexiclean
crate for lexical path cleaning
I moved all the lexical path cleaning functionality into a separate crate, so it can be used by other projects. type: reform
This commit is contained in:
parent
323434d0aa
commit
134c241ae7
|
@ -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 <casey@rodarmor.com>_
|
||||
- :art: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Use `lexiclean` crate for lexical path cleaning - _Casey Rodarmor <casey@rodarmor.com>_
|
||||
- :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 <casey@rodarmor.com>_
|
||||
- :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 <casey@rodarmor.com>_
|
||||
- :wrench: [`c22df5a08326`](https://github.com/casey/intermodal/commit/c22df5a083265b03abd5531b1f5b2aad60aa68cd) Don't commit man pages - _Casey Rodarmor <casey@rodarmor.com>_
|
||||
- :wrench: [`4d67d3a10d17`](https://github.com/casey/intermodal/commit/4d67d3a10d17db3c63af092a936eb5994ee107b1) Don't commit the book - _Casey Rodarmor <casey@rodarmor.com>_
|
||||
|
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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("./", ".");
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user