From 103806bdeaaf4ad60499b76ba929aa8dfbc07497 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Tue, 2 Jul 2024 19:50:39 -0500 Subject: [PATCH 1/3] Add test case demonstrating equality of paths "foo/bar" and "foobar" --- library/std/src/path/tests.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 92702b395dfe1..53a65c60b580c 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1566,6 +1566,13 @@ pub fn test_compare() { relative_from: Some("bar") ); + tc!("foo/bar", "foobar", + eq: false, + starts_with: false, + ends_with: false, + relative_from: None + ); + tc!("foo/bar/baz", "foo/bar", eq: false, starts_with: true, From 7429f39dc511b11c36e9cfd080bc0f37c42b34bd Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Tue, 2 Jul 2024 20:54:36 -0500 Subject: [PATCH 2/3] Include non-redundant separators in the hash for `Path` --- library/std/src/path.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index caae8f924d2b1..2c140c1a14f40 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3109,7 +3109,7 @@ impl Hash for Path { bytes_hashed += to_hash.len(); } - // skip over separator and optionally a following CurDir item + // Skip over separators and, optionally, a following CurDir item // since components() would normalize these away. component_start = i + 1; @@ -3117,9 +3117,22 @@ impl Hash for Path { if !verbatim { component_start += match tail { + // At the end of the path, e.g. `foo/` + [] => 0, + // At the end of the path followed by a CurDir component, e.g. `foo/.` [b'.'] => 1, + // Followed by a CurDir component, another separator, and a component e.g. `foo/./bar` [b'.', sep @ _, ..] if is_sep_byte(*sep) => 1, - _ => 0, + // Followed by another separator and a component, e.g. `foo//bar` + [sep @ _, ..] if is_sep_byte(*sep) => 1, + // Otherwise, it's a separator followed by a new component, e.g. `foo/bar` + // and we should hash the separator to distinguish from `foobar` + _ => { + let to_hash = &[b'/' as u8]; + h.write(to_hash); + bytes_hashed += to_hash.len(); + 0 + } }; } } From b70cd193591999ec5bfd581cc9d1f970ced59b36 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Tue, 2 Jul 2024 23:12:06 -0500 Subject: [PATCH 3/3] Add more test cases for path comparisons --- library/std/src/path/tests.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 53a65c60b580c..87a06a9ea9153 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1545,6 +1545,20 @@ pub fn test_compare() { relative_from: Some("") ); + tc!("foo//", "foo", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + + tc!("foo///", "foo", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + tc!("foo/.", "foo", eq: true, starts_with: true, @@ -1559,6 +1573,20 @@ pub fn test_compare() { relative_from: Some("") ); + tc!("foo/.//bar", "foo/bar", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + + tc!("foo//./bar", "foo/bar", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + tc!("foo/bar", "foo", eq: false, starts_with: true,