Skip to content

Commit 40bef0d

Browse files
committed
fix: improve Windows path normalization by stripping trailing slashes
1 parent 171669f commit 40bef0d

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

crates/pet-fs/src/path.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,24 @@ fn normalize_case_windows(path: &Path) -> Option<PathBuf> {
7272

7373
// Convert back to PathBuf
7474
let os_string = OsString::from_wide(&buffer);
75-
let result = PathBuf::from(os_string);
75+
let mut result_str = os_string.to_string_lossy().to_string();
7676

7777
// Remove UNC prefix if original path didn't have it
7878
// GetLongPathNameW may add \\?\ prefix in some cases
79-
let result_str = result.to_string_lossy();
8079
let original_has_unc = path.to_string_lossy().starts_with(r"\\?\");
81-
8280
if result_str.starts_with(r"\\?\") && !original_has_unc {
83-
Some(PathBuf::from(result_str.trim_start_matches(r"\\?\")))
84-
} else {
85-
Some(result)
81+
result_str = result_str.trim_start_matches(r"\\?\").to_string();
82+
}
83+
84+
// Strip trailing path separators to match canonicalize behavior
85+
// (but keep the root like "C:\")
86+
while result_str.len() > 3
87+
&& (result_str.ends_with('\\') || result_str.ends_with('/'))
88+
{
89+
result_str.pop();
8690
}
91+
92+
Some(PathBuf::from(result_str))
8793
}
8894

8995
// Resolves symlinks to the real file.
@@ -291,4 +297,26 @@ mod tests {
291297
"Should not add UNC prefix"
292298
);
293299
}
300+
301+
#[test]
302+
#[cfg(windows)]
303+
fn test_norm_case_windows_strips_trailing_slash() {
304+
// norm_case should strip trailing slashes to match canonicalize behavior
305+
let path_with_slash = PathBuf::from("C:\\Windows\\");
306+
let result = norm_case(&path_with_slash);
307+
assert!(
308+
!result.to_string_lossy().ends_with('\\'),
309+
"Should strip trailing backslash, got: {:?}",
310+
result
311+
);
312+
313+
// But root paths like C:\ should keep their slash
314+
let root_path = PathBuf::from("C:\\");
315+
let root_result = norm_case(&root_path);
316+
assert!(
317+
root_result.to_string_lossy().ends_with('\\'),
318+
"Root path should keep trailing backslash, got: {:?}",
319+
root_result
320+
);
321+
}
294322
}

0 commit comments

Comments
 (0)