From 2f6302b91531fc82467c55c44ccfb0e2d700a0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=B1=AA?= <504595380@qq.com> Date: Mon, 24 Feb 2025 19:27:13 +0800 Subject: [PATCH] fix #840: resolve supports paths starting with .. (#845) * fix i840 * add test * fix cr --- modules/llrt_path/src/lib.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/modules/llrt_path/src/lib.rs b/modules/llrt_path/src/lib.rs index bc8ccf9855..955b35463d 100644 --- a/modules/llrt_path/src/lib.rs +++ b/modules/llrt_path/src/lib.rs @@ -386,6 +386,11 @@ where let mut index_stack = Vec::with_capacity(16); + // Remove the trailing sep: /a/b// -> /a/b + if ends_with_sep(&result) && result.len() > 1 { + result.truncate(result.len() - 1); + } + for part in parts { let mut part_ref: &str = part.as_ref(); let mut start = 0; @@ -434,9 +439,12 @@ where let end = find_next_separator(&part_ref[start..]).map_or(part_ref.len(), |i| i + start); match &part_ref[start..end] { ".." => { - empty = false; if let Some(last_index) = index_stack.pop() { result.truncate(last_index); + } else if empty { + if let Some(last_index) = find_last_sep(&result) { + result.truncate(last_index); + } } }, "" | "." => { @@ -444,9 +452,11 @@ where }, sub_part => { let len = result.len(); + if !result.ends_with(sep) && !result.is_empty() { + result.push(sep); + } result.push_str(sub_part); result.push(sep); - empty = false; index_stack.push(len); }, } @@ -749,6 +759,22 @@ mod tests { resolve_path(["/foo/bar", "/..", "baz"].iter()).unwrap(), prefix.clone() + &"/baz".replace('/', MAIN_SEPARATOR_STR) ); // Parent dir with absolute path + + assert_eq!( + resolve_path(["../foo"].iter()).unwrap(), + std::env::current_dir() + .unwrap() + .parent() + .unwrap() + .join("foo".replace('/', MAIN_SEPARATOR_STR)) + .to_string_lossy() + .to_string() + ); // Start with .. + + assert_eq!( + resolve_path(["../".repeat(32)].iter()).unwrap(), + prefix.clone() + ); // Many .. } #[test]