mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +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 {
|
match component {
|
||||||
Component::Prefix(..) => unreachable!(),
|
Component::Prefix(..) => unreachable!(),
|
||||||
Component::RootDir => {
|
Component::RootDir => {
|
||||||
ret.push(component.as_os_str());
|
ret.push(Component::RootDir);
|
||||||
}
|
}
|
||||||
Component::CurDir => {}
|
Component::CurDir => {}
|
||||||
Component::ParentDir => {
|
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) => {
|
Component::Normal(c) => {
|
||||||
ret.push(c);
|
ret.push(c);
|
||||||
@ -856,9 +863,43 @@ fn exclude_from_time_machine(path: &Path) {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::join_paths;
|
use super::join_paths;
|
||||||
|
use super::normalize_path;
|
||||||
use super::write;
|
use super::write;
|
||||||
use super::write_atomic;
|
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]
|
#[test]
|
||||||
fn write_works() {
|
fn write_works() {
|
||||||
let original_contents = "[dependencies]\nfoo = 0.1.0";
|
let original_contents = "[dependencies]\nfoo = 0.1.0";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user