From e8b7371a237451cdc73547b27311fd8d5078521f Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 5 Mar 2022 17:57:12 +0000 Subject: [PATCH 1/2] Unix `path::absolute`: Fix leading "." component Testing leading `.` and `..` components were missing from the unix tests. --- library/std/src/path/tests.rs | 5 +++++ library/std/src/sys/unix/path.rs | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 8e51433094a69..435e84f8ceff6 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1719,6 +1719,11 @@ fn test_unix_absolute() { assert_eq!(absolute("///a/b/c").unwrap(), Path::new("/a/b/c")); assert_eq!(absolute("/a/b/c/").unwrap(), Path::new("/a/b/c/")); assert_eq!(absolute("/a/./b/../c/.././..").unwrap(), Path::new("/a/b/../c/../..")); + + // Test leading `.` and `..` components + let curdir = crate::env::current_dir().unwrap(); + assert_eq!(absolute("./a").unwrap().as_os_str(), curdir.join("a").as_os_str()); + assert_eq!(absolute("../a").unwrap().as_os_str(), curdir.join("../a").as_os_str()); // return /pwd/../a } #[test] diff --git a/library/std/src/sys/unix/path.rs b/library/std/src/sys/unix/path.rs index 6d6f4c8b8dc63..a98a69e2db8e1 100644 --- a/library/std/src/sys/unix/path.rs +++ b/library/std/src/sys/unix/path.rs @@ -28,7 +28,8 @@ pub(crate) fn absolute(path: &Path) -> io::Result { // See 4.13 Pathname Resolution, IEEE Std 1003.1-2017 // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 - let mut components = path.components(); + // Get the components, skipping the redundant leading "." component if it exists. + let mut components = path.strip_prefix(".").unwrap_or(path).components(); let path_os = path.as_os_str().bytes(); let mut normalized = if path.is_absolute() { From 0421af9a4626638c71d59feebd7a35136d53bfb9 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 5 Mar 2022 17:58:08 +0000 Subject: [PATCH 2/2] Use `as_os_str` to compare exact paths --- library/std/src/path/tests.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 435e84f8ceff6..6e863787b7f39 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1710,15 +1710,18 @@ fn test_unix_absolute() { let relative = "a/b"; let mut expected = crate::env::current_dir().unwrap(); expected.push(relative); - assert_eq!(absolute(relative).unwrap(), expected); + assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str()); // Test how components are collected. - assert_eq!(absolute("/a/b/c").unwrap(), Path::new("/a/b/c")); - assert_eq!(absolute("/a//b/c").unwrap(), Path::new("/a/b/c")); - assert_eq!(absolute("//a/b/c").unwrap(), Path::new("//a/b/c")); - assert_eq!(absolute("///a/b/c").unwrap(), Path::new("/a/b/c")); - assert_eq!(absolute("/a/b/c/").unwrap(), Path::new("/a/b/c/")); - assert_eq!(absolute("/a/./b/../c/.././..").unwrap(), Path::new("/a/b/../c/../..")); + assert_eq!(absolute("/a/b/c").unwrap().as_os_str(), Path::new("/a/b/c").as_os_str()); + assert_eq!(absolute("/a//b/c").unwrap().as_os_str(), Path::new("/a/b/c").as_os_str()); + assert_eq!(absolute("//a/b/c").unwrap().as_os_str(), Path::new("//a/b/c").as_os_str()); + assert_eq!(absolute("///a/b/c").unwrap().as_os_str(), Path::new("/a/b/c").as_os_str()); + assert_eq!(absolute("/a/b/c/").unwrap().as_os_str(), Path::new("/a/b/c/").as_os_str()); + assert_eq!( + absolute("/a/./b/../c/.././..").unwrap().as_os_str(), + Path::new("/a/b/../c/../..").as_os_str() + ); // Test leading `.` and `..` components let curdir = crate::env::current_dir().unwrap();