diff options
Diffstat (limited to 'ext/node_resolver/path.rs')
-rw-r--r-- | ext/node_resolver/path.rs | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/ext/node_resolver/path.rs b/ext/node_resolver/path.rs index 8c33285db..ece270cd9 100644 --- a/ext/node_resolver/path.rs +++ b/ext/node_resolver/path.rs @@ -13,8 +13,31 @@ pub trait PathClean<T> { impl PathClean<PathBuf> for PathBuf { fn clean(&self) -> PathBuf { + fn is_clean_path(path: &Path) -> bool { + let path = path.to_string_lossy(); + let mut current_index = 0; + while let Some(index) = path[current_index..].find("\\.") { + let trailing_index = index + current_index + 2; + let mut trailing_chars = path[trailing_index..].chars(); + match trailing_chars.next() { + Some('.') => match trailing_chars.next() { + Some('/') | Some('\\') | None => { + return false; + } + _ => {} + }, + Some('/') | Some('\\') => { + return false; + } + _ => {} + } + current_index = trailing_index; + } + true + } + let path = path_clean::PathClean::clean(self); - if cfg!(windows) && path.to_string_lossy().contains("..\\") { + if cfg!(windows) && !is_clean_path(&path) { // temporary workaround because path_clean::PathClean::clean is // not good enough on windows let mut components = Vec::new(); @@ -105,6 +128,20 @@ pub fn strip_unc_prefix(path: PathBuf) -> PathBuf { mod test { #[cfg(windows)] #[test] + fn test_path_clean() { + use super::*; + + run_test("C:\\test\\./file.txt", "C:\\test\\file.txt"); + run_test("C:\\test\\../other/file.txt", "C:\\other\\file.txt"); + run_test("C:\\test\\../other\\file.txt", "C:\\other\\file.txt"); + + fn run_test(input: &str, expected: &str) { + assert_eq!(PathBuf::from(input).clean(), PathBuf::from(expected)); + } + } + + #[cfg(windows)] + #[test] fn test_strip_unc_prefix() { use std::path::PathBuf; |