mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Auto merge of #14750 - epage:normalize, r=weihanglo
fix(util): Respect all `..`s in `normalize_path` ### What does this PR try to resolve? The fact that `normalize_path` was only designed for absolute paths bit us when working out #14497 and so I decided to make sure it worked. The other alternative I considered was having it assert that the path was absolute. Since I did try out the assert and Cargo tests hit it, this likely fixes something but I haven't dug through to be able to say what. ### How should we test and review this PR? ### Additional information
This commit is contained in:
commit
2fcc3755a3
@ -94,11 +94,18 @@ pub fn normalize_path(path: &Path) -> PathBuf {
|
||||
match component {
|
||||
Component::Prefix(..) => unreachable!(),
|
||||
Component::RootDir => {
|
||||
ret.push(component.as_os_str());
|
||||
ret.push(Component::RootDir);
|
||||
}
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
ret.pop();
|
||||
if ret.ends_with(Component::ParentDir) {
|
||||
ret.push(Component::ParentDir);
|
||||
} else {
|
||||
let popped = ret.pop();
|
||||
if !popped && !ret.has_root() {
|
||||
ret.push(Component::ParentDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
Component::Normal(c) => {
|
||||
ret.push(c);
|
||||
@ -856,9 +863,43 @@ fn exclude_from_time_machine(path: &Path) {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::join_paths;
|
||||
use super::normalize_path;
|
||||
use super::write;
|
||||
use super::write_atomic;
|
||||
|
||||
#[test]
|
||||
fn test_normalize_path() {
|
||||
let cases = &[
|
||||
("", ""),
|
||||
(".", ""),
|
||||
(".////./.", ""),
|
||||
("/", "/"),
|
||||
("/..", "/"),
|
||||
("/foo/bar", "/foo/bar"),
|
||||
("/foo/bar/", "/foo/bar"),
|
||||
("/foo/bar/./././///", "/foo/bar"),
|
||||
("/foo/bar/..", "/foo"),
|
||||
("/foo/bar/../..", "/"),
|
||||
("/foo/bar/../../..", "/"),
|
||||
("foo/bar", "foo/bar"),
|
||||
("foo/bar/", "foo/bar"),
|
||||
("foo/bar/./././///", "foo/bar"),
|
||||
("foo/bar/..", "foo"),
|
||||
("foo/bar/../..", ""),
|
||||
("foo/bar/../../..", ".."),
|
||||
("../../foo/bar", "../../foo/bar"),
|
||||
("../../foo/bar/", "../../foo/bar"),
|
||||
("../../foo/bar/./././///", "../../foo/bar"),
|
||||
("../../foo/bar/..", "../../foo"),
|
||||
("../../foo/bar/../..", "../.."),
|
||||
("../../foo/bar/../../..", "../../.."),
|
||||
];
|
||||
for (input, expected) in cases {
|
||||
let actual = normalize_path(std::path::Path::new(input));
|
||||
assert_eq!(actual, std::path::Path::new(expected), "input: {input}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_works() {
|
||||
let original_contents = "[dependencies]\nfoo = 0.1.0";
|
||||
|
Loading…
x
Reference in New Issue
Block a user