From 3bd9bd9529373b0c273a3f4e07517f8724822dc9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Sep 2024 18:20:36 -0700 Subject: [PATCH 1/8] Fix handling of `..` paths in symlinks. When `..` appears at the end of a symlink target, but is not at the end of the full path target, don't mark the path as being expected to open a directory. This fixes the reduced testcase in bytecodealliance/wasmtime#9272. --- cap-primitives/src/fs/manually/open.rs | 9 +- tests/fs_additional.rs | 112 +++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/cap-primitives/src/fs/manually/open.rs b/cap-primitives/src/fs/manually/open.rs index 6c630fe2..0bda7514 100644 --- a/cap-primitives/src/fs/manually/open.rs +++ b/cap-primitives/src/fs/manually/open.rs @@ -314,6 +314,7 @@ impl<'start> Context<'start> { /// Push the components of `destination` onto the worklist stack. fn push_symlink_destination(&mut self, destination: PathBuf) -> io::Result<()> { + let at_end = self.components.is_empty(); let trailing_slash = path_has_trailing_slash(&destination); let trailing_dot = path_has_trailing_dot(&destination); let trailing_dotdot = destination.ends_with(Component::ParentDir); @@ -362,9 +363,11 @@ impl<'start> Context<'start> { // Record whether the new components ended with a path that implies // an open of `.` at the end of path resolution. - self.follow_with_dot |= trailing_dot | trailing_dotdot; - self.trailing_slash |= trailing_slash; - self.dir_required |= trailing_slash; + if at_end { + self.follow_with_dot |= trailing_dot | trailing_dotdot; + self.trailing_slash |= trailing_slash; + self.dir_required |= trailing_slash; + } // As an optimization, hold onto the `PathBuf` buffer for later reuse. self.reuse = destination; diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index 6e6705f9..20747f0f 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -1046,3 +1046,115 @@ fn check_metadata(std: &std::fs::Metadata, cap: &cap_std::fs::Metadata) { assert_eq!(std.blocks(), cap_std::fs::MetadataExt::blocks(cap)); } } + +/// Test that a symlink in the middle of a path containing ".." doesn't cause +/// the path to be treated as if it ends with "..". +#[test] +fn dotdot_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir("b")); + let b = check!(tmpdir.open_dir("b")); + check!(b.symlink("..", "up")); + + let path = "b/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + +/// Same as `dotdot_in_middle_of_symlink`, but use two levels of `..`. +#[test] +fn dotdot_more_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir_all("b/c")); + let b = check!(tmpdir.open_dir("b")); + check!(b.symlink("c/../..", "up")); + + let path = "b/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + +/// Same as `dotdot_more_in_middle_of_symlink`, but use a symlink that +/// doesn't end with `..`. +#[test] +fn dotdot_even_more_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.create_dir_all("b/c")); + check!(tmpdir.write("b/target", foo)); + let b = check!(tmpdir.open_dir("b")); + check!(b.symlink("c/../../b", "up")); + + let path = "b/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + +/// Similar to `dotdot_in_middle_of_symlink`, but this time the symlink to +/// `..` does happen to be the end of the path, so we need to make sure +/// the implementation doesn't just do a stack pop when it sees the `..` +/// leaving us with an `O_PATH` directory handle. +#[test] +fn dotdot_at_end_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir("b")); + let b = check!(tmpdir.open_dir("b")); + check!(b.symlink("..", "up")); + + // Do some things with `path` that might break with an `O_PATH` fd. + // On Linux, the `permissions` part doesn't because cap-std uses + // /proc/self/fd. But the `read_dir` part does. + let path = "b/up"; + + let perms = check!(tmpdir.metadata(path)).permissions(); + check!(tmpdir.set_permissions(path, perms)); + + let contents = check!(tmpdir.read_dir(path)); + for entry in contents { + let _entry = check!(entry); + } +} + +/// Like `dotdot_at_end_of_symlink`, but do everything inside a new directory, +/// so that `MaybeOwnedFile` doesn't reopen `.` which would artificially give +/// us a non-`O_PATH` fd. +#[test] +fn dotdot_at_end_of_symlink_all_inside_dir() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.create_dir("dir")); + check!(tmpdir.write("dir/target", foo)); + check!(tmpdir.create_dir("dir/b")); + let b = check!(tmpdir.open_dir("dir/b")); + check!(b.symlink("..", "up")); + + // Do some things with `path` that might break with an `O_PATH` fd. + // On Linux, the `permissions` part doesn't because cap-std uses + // /proc/self/fd. But the `read_dir` part does. + let path = "dir/b/up"; + + let perms = check!(tmpdir.metadata(path)).permissions(); + check!(tmpdir.set_permissions(path, perms)); + + let contents = check!(tmpdir.read_dir(path)); + for entry in contents { + let _entry = check!(entry); + } +} From db8708c303aa9612d84246f3f00197b1809d2171 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Sep 2024 18:28:51 -0700 Subject: [PATCH 2/8] Fix compilation on Windows. --- tests/fs_additional.rs | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index 20747f0f..e4a1b617 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -5,36 +5,28 @@ #[macro_use] mod sys_common; -use cap_std::fs::{DirBuilder, OpenOptions}; +use cap_std::fs::{Dir, DirBuilder, OpenOptions}; use cap_std::time::SystemClock; use std::io::{self, Read, Write}; use std::path::Path; use std::str; -use sys_common::io::{tmpdir, TempDir}; +use sys_common::io::tmpdir; use sys_common::symlink_supported; #[cfg(not(windows))] -fn symlink_dir, Q: AsRef>(src: P, tmpdir: &TempDir, dst: Q) -> io::Result<()> { +fn symlink_dir, Q: AsRef>(src: P, tmpdir: &Dir, dst: Q) -> io::Result<()> { tmpdir.symlink(src, dst) } #[cfg(not(windows))] -fn symlink_file, Q: AsRef>( - src: P, - tmpdir: &TempDir, - dst: Q, -) -> io::Result<()> { +fn symlink_file, Q: AsRef>(src: P, tmpdir: &Dir, dst: Q) -> io::Result<()> { tmpdir.symlink(src, dst) } #[cfg(windows)] -fn symlink_dir, Q: AsRef>(src: P, tmpdir: &TempDir, dst: Q) -> io::Result<()> { +fn symlink_dir, Q: AsRef>(src: P, tmpdir: &Dir, dst: Q) -> io::Result<()> { tmpdir.symlink_dir(src, dst) } #[cfg(windows)] -fn symlink_file, Q: AsRef>( - src: P, - tmpdir: &TempDir, - dst: Q, -) -> io::Result<()> { +fn symlink_file, Q: AsRef>(src: P, tmpdir: &Dir, dst: Q) -> io::Result<()> { tmpdir.symlink_file(src, dst) } @@ -1057,7 +1049,7 @@ fn dotdot_in_middle_of_symlink() { check!(tmpdir.write("target", foo)); check!(tmpdir.create_dir("b")); let b = check!(tmpdir.open_dir("b")); - check!(b.symlink("..", "up")); + check!(symlink_dir("..", &b, "up")); let path = "b/up/target"; let mut file = check!(tmpdir.open(path)); @@ -1075,7 +1067,7 @@ fn dotdot_more_in_middle_of_symlink() { check!(tmpdir.write("target", foo)); check!(tmpdir.create_dir_all("b/c")); let b = check!(tmpdir.open_dir("b")); - check!(b.symlink("c/../..", "up")); + check!(symlink_dir("c/../..", &b, "up")); let path = "b/up/target"; let mut file = check!(tmpdir.open(path)); @@ -1094,7 +1086,7 @@ fn dotdot_even_more_in_middle_of_symlink() { check!(tmpdir.create_dir_all("b/c")); check!(tmpdir.write("b/target", foo)); let b = check!(tmpdir.open_dir("b")); - check!(b.symlink("c/../../b", "up")); + check!(symlink_dir("c/../../b", &b, "up")); let path = "b/up/target"; let mut file = check!(tmpdir.open(path)); @@ -1115,7 +1107,7 @@ fn dotdot_at_end_of_symlink() { check!(tmpdir.write("target", foo)); check!(tmpdir.create_dir("b")); let b = check!(tmpdir.open_dir("b")); - check!(b.symlink("..", "up")); + check!(symlink_dir("..", &b, "up")); // Do some things with `path` that might break with an `O_PATH` fd. // On Linux, the `permissions` part doesn't because cap-std uses @@ -1143,7 +1135,7 @@ fn dotdot_at_end_of_symlink_all_inside_dir() { check!(tmpdir.write("dir/target", foo)); check!(tmpdir.create_dir("dir/b")); let b = check!(tmpdir.open_dir("dir/b")); - check!(b.symlink("..", "up")); + check!(symlink_dir("..", &b, "up")); // Do some things with `path` that might break with an `O_PATH` fd. // On Linux, the `permissions` part doesn't because cap-std uses From 561f49ee2a03cadd45e57431b51e0f446241a316 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Sep 2024 19:37:29 -0700 Subject: [PATCH 3/8] Add more tests, and disable some tests on Windows. --- tests/fs_additional.rs | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index e4a1b617..4fad69cb 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -1059,7 +1059,10 @@ fn dotdot_in_middle_of_symlink() { } /// Same as `dotdot_in_middle_of_symlink`, but use two levels of `..`. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] +#[cfg(not(windows))] fn dotdot_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1076,6 +1079,28 @@ fn dotdot_more_in_middle_of_symlink() { assert_eq!(data, foo); } +/// Same as `dotdot_more_in_middle_of_symlink`, but the symlink doesn't +/// include `c`. +/// +/// This fails on Windows for unknown reasons. Patches welcome. +#[test] +#[cfg(not(windows))] +fn dotdot_other_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir_all("b/c")); + let c = check!(tmpdir.open_dir("b/c")); + check!(symlink_dir("../..", &c, "up")); + + let path = "b/c/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + /// Same as `dotdot_more_in_middle_of_symlink`, but use a symlink that /// doesn't end with `..`. #[test] @@ -1095,6 +1120,25 @@ fn dotdot_even_more_in_middle_of_symlink() { assert_eq!(data, foo); } +/// Same as `dotdot_even_more_in_middle_of_symlink`, but the symlink doesn't +/// include `c`. +#[test] +fn dotdot_even_other_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.create_dir_all("b/c")); + check!(tmpdir.write("b/target", foo)); + let c = check!(tmpdir.open_dir("b/c")); + check!(symlink_dir("../../b", &c, "up")); + + let path = "b/c/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + /// Similar to `dotdot_in_middle_of_symlink`, but this time the symlink to /// `..` does happen to be the end of the path, so we need to make sure /// the implementation doesn't just do a stack pop when it sees the `..` From 82887cc69fe739b42a9e3acbaf768ef53b8625b8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 21 Sep 2024 07:15:25 -0700 Subject: [PATCH 4/8] Update CI to macos-12. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 598da3c3..ab710a62 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -201,7 +201,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - build: [stable, windows-latest, windows-2019, macos-latest, macos-11, beta, ubuntu-20.04, aarch64-ubuntu] + build: [stable, windows-latest, windows-2019, macos-latest, macos-12, beta, ubuntu-20.04, aarch64-ubuntu] include: - build: stable os: ubuntu-latest From 04c48daf6a7b10bbd9926e11da00ed2a46f0c77f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 21 Sep 2024 07:15:40 -0700 Subject: [PATCH 5/8] More testing. --- tests/fs_additional.rs | 147 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 2 deletions(-) diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index 4fad69cb..95267905 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -1058,11 +1058,29 @@ fn dotdot_in_middle_of_symlink() { assert_eq!(data, foo); } +/// Like `dotdot_in_middle_of_symlink` but with a `/.` at the end. +#[test] +fn dotdot_slashdot_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir("b")); + let b = check!(tmpdir.open_dir("b")); + check!(symlink_dir("../.", &b, "up")); + + let path = "b/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + /// Same as `dotdot_in_middle_of_symlink`, but use two levels of `..`. /// /// This fails on Windows for unknown reasons. Patches welcome. #[test] -#[cfg(not(windows))] +//#[cfg(not(windows))] fn dotdot_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1079,12 +1097,31 @@ fn dotdot_more_in_middle_of_symlink() { assert_eq!(data, foo); } +/// Like `dotdot_more_in_middle_of_symlink`, but with a `/.` at the end. +#[test] +//#[cfg(not(windows))] +fn dotdot_slashdot_more_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir_all("b/c")); + let b = check!(tmpdir.open_dir("b")); + check!(symlink_dir("c/../../.", &b, "up")); + + let path = "b/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + /// Same as `dotdot_more_in_middle_of_symlink`, but the symlink doesn't /// include `c`. /// /// This fails on Windows for unknown reasons. Patches welcome. #[test] -#[cfg(not(windows))] +//#[cfg(not(windows))] fn dotdot_other_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1101,6 +1138,25 @@ fn dotdot_other_in_middle_of_symlink() { assert_eq!(data, foo); } +/// Like `dotdot_other_in_middle_of_symlink`, but with `/.` at the end. +#[test] +//#[cfg(not(windows))] +fn dotdot_slashdot_other_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir_all("b/c")); + let c = check!(tmpdir.open_dir("b/c")); + check!(symlink_dir("../../.", &c, "up")); + + let path = "b/c/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + /// Same as `dotdot_more_in_middle_of_symlink`, but use a symlink that /// doesn't end with `..`. #[test] @@ -1120,6 +1176,24 @@ fn dotdot_even_more_in_middle_of_symlink() { assert_eq!(data, foo); } +/// Like `dotdot_even_more_in_middle_of_symlink`, but with a `/.` at the end. +#[test] +fn dotdot_slashdot_even_more_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.create_dir_all("b/c")); + check!(tmpdir.write("b/target", foo)); + let b = check!(tmpdir.open_dir("b")); + check!(symlink_dir("c/../../b/.", &b, "up")); + + let path = "b/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + /// Same as `dotdot_even_more_in_middle_of_symlink`, but the symlink doesn't /// include `c`. #[test] @@ -1139,6 +1213,24 @@ fn dotdot_even_other_in_middle_of_symlink() { assert_eq!(data, foo); } +/// Like `dotdot_even_other_in_middle_of_symlink`, but with a `/.` at the end. +#[test] +fn dotdot_slashdot_even_other_in_middle_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.create_dir_all("b/c")); + check!(tmpdir.write("b/target", foo)); + let c = check!(tmpdir.open_dir("b/c")); + check!(symlink_dir("../../b/.", &c, "up")); + + let path = "b/c/up/target"; + let mut file = check!(tmpdir.open(path)); + let mut data = Vec::new(); + check!(file.read_to_end(&mut data)); + assert_eq!(data, foo); +} + /// Similar to `dotdot_in_middle_of_symlink`, but this time the symlink to /// `..` does happen to be the end of the path, so we need to make sure /// the implementation doesn't just do a stack pop when it sees the `..` @@ -1167,6 +1259,31 @@ fn dotdot_at_end_of_symlink() { } } +/// Like `dotdot_at_end_of_symlink`, but with a `/.` at the end. +#[test] +fn dotdot_slashdot_at_end_of_symlink() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.write("target", foo)); + check!(tmpdir.create_dir("b")); + let b = check!(tmpdir.open_dir("b")); + check!(symlink_dir("../.", &b, "up")); + + // Do some things with `path` that might break with an `O_PATH` fd. + // On Linux, the `permissions` part doesn't because cap-std uses + // /proc/self/fd. But the `read_dir` part does. + let path = "b/up"; + + let perms = check!(tmpdir.metadata(path)).permissions(); + check!(tmpdir.set_permissions(path, perms)); + + let contents = check!(tmpdir.read_dir(path)); + for entry in contents { + let _entry = check!(entry); + } +} + /// Like `dotdot_at_end_of_symlink`, but do everything inside a new directory, /// so that `MaybeOwnedFile` doesn't reopen `.` which would artificially give /// us a non-`O_PATH` fd. @@ -1194,3 +1311,29 @@ fn dotdot_at_end_of_symlink_all_inside_dir() { let _entry = check!(entry); } } + +/// `dotdot_at_end_of_symlink_all_inside_dir`, but with a `/.` at the end. +#[test] +fn dotdot_slashdot_at_end_of_symlink_all_inside_dir() { + let tmpdir = tmpdir(); + + let foo = b"foo"; + check!(tmpdir.create_dir("dir")); + check!(tmpdir.write("dir/target", foo)); + check!(tmpdir.create_dir("dir/b")); + let b = check!(tmpdir.open_dir("dir/b")); + check!(symlink_dir("../.", &b, "up")); + + // Do some things with `path` that might break with an `O_PATH` fd. + // On Linux, the `permissions` part doesn't because cap-std uses + // /proc/self/fd. But the `read_dir` part does. + let path = "dir/b/up"; + + let perms = check!(tmpdir.metadata(path)).permissions(); + check!(tmpdir.set_permissions(path, perms)); + + let contents = check!(tmpdir.read_dir(path)); + for entry in contents { + let _entry = check!(entry); + } +} From 3666bb2d4521ea7a4a3798ac9bd706168cb4beac Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 21 Sep 2024 07:31:50 -0700 Subject: [PATCH 6/8] Windows flailing. --- tests/fs_additional.rs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index 95267905..be81eec0 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -1059,6 +1059,8 @@ fn dotdot_in_middle_of_symlink() { } /// Like `dotdot_in_middle_of_symlink` but with a `/.` at the end. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] fn dotdot_slashdot_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1080,7 +1082,7 @@ fn dotdot_slashdot_in_middle_of_symlink() { /// /// This fails on Windows for unknown reasons. Patches welcome. #[test] -//#[cfg(not(windows))] +//#[cfg_attr(windows, ignore)] fn dotdot_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1098,8 +1100,10 @@ fn dotdot_more_in_middle_of_symlink() { } /// Like `dotdot_more_in_middle_of_symlink`, but with a `/.` at the end. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] -//#[cfg(not(windows))] +//#[cfg_attr(windows, ignore)] fn dotdot_slashdot_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1121,7 +1125,7 @@ fn dotdot_slashdot_more_in_middle_of_symlink() { /// /// This fails on Windows for unknown reasons. Patches welcome. #[test] -//#[cfg(not(windows))] +//#[cfg_attr(windows, ignore)] fn dotdot_other_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1139,8 +1143,10 @@ fn dotdot_other_in_middle_of_symlink() { } /// Like `dotdot_other_in_middle_of_symlink`, but with `/.` at the end. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] -//#[cfg(not(windows))] +//#[cfg_attr(windows, ignore)] fn dotdot_slashdot_other_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1177,7 +1183,10 @@ fn dotdot_even_more_in_middle_of_symlink() { } /// Like `dotdot_even_more_in_middle_of_symlink`, but with a `/.` at the end. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] +//#[cfg_attr(windows, ignore)] fn dotdot_slashdot_even_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1214,7 +1223,10 @@ fn dotdot_even_other_in_middle_of_symlink() { } /// Like `dotdot_even_other_in_middle_of_symlink`, but with a `/.` at the end. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] +//#[cfg_attr(windows, ignore)] fn dotdot_slashdot_even_other_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1260,7 +1272,10 @@ fn dotdot_at_end_of_symlink() { } /// Like `dotdot_at_end_of_symlink`, but with a `/.` at the end. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] +//#[cfg_attr(windows, ignore)] fn dotdot_slashdot_at_end_of_symlink() { let tmpdir = tmpdir(); @@ -1313,7 +1328,10 @@ fn dotdot_at_end_of_symlink_all_inside_dir() { } /// `dotdot_at_end_of_symlink_all_inside_dir`, but with a `/.` at the end. +/// +/// This fails on Windows for unknown reasons. Patches welcome. #[test] +//#[cfg_attr(windows, ignore)] fn dotdot_slashdot_at_end_of_symlink_all_inside_dir() { let tmpdir = tmpdir(); From beac3cad6ed80b6ad2bc095fe0514f81808d76b8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 21 Sep 2024 08:13:59 -0700 Subject: [PATCH 7/8] Windows --- tests/fs_additional.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index be81eec0..b5238436 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -1060,7 +1060,7 @@ fn dotdot_in_middle_of_symlink() { /// Like `dotdot_in_middle_of_symlink` but with a `/.` at the end. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/.`. #[test] fn dotdot_slashdot_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1080,9 +1080,9 @@ fn dotdot_slashdot_in_middle_of_symlink() { /// Same as `dotdot_in_middle_of_symlink`, but use two levels of `..`. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/..`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1101,9 +1101,9 @@ fn dotdot_more_in_middle_of_symlink() { /// Like `dotdot_more_in_middle_of_symlink`, but with a `/.` at the end. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/.`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_slashdot_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1123,9 +1123,9 @@ fn dotdot_slashdot_more_in_middle_of_symlink() { /// Same as `dotdot_more_in_middle_of_symlink`, but the symlink doesn't /// include `c`. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/..`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_other_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1144,9 +1144,9 @@ fn dotdot_other_in_middle_of_symlink() { /// Like `dotdot_other_in_middle_of_symlink`, but with `/.` at the end. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/.`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_slashdot_other_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1184,9 +1184,9 @@ fn dotdot_even_more_in_middle_of_symlink() { /// Like `dotdot_even_more_in_middle_of_symlink`, but with a `/.` at the end. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/.`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_slashdot_even_more_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1224,9 +1224,9 @@ fn dotdot_even_other_in_middle_of_symlink() { /// Like `dotdot_even_other_in_middle_of_symlink`, but with a `/.` at the end. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/.`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_slashdot_even_other_in_middle_of_symlink() { let tmpdir = tmpdir(); @@ -1273,9 +1273,9 @@ fn dotdot_at_end_of_symlink() { /// Like `dotdot_at_end_of_symlink`, but with a `/.` at the end. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/.`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_slashdot_at_end_of_symlink() { let tmpdir = tmpdir(); @@ -1329,9 +1329,9 @@ fn dotdot_at_end_of_symlink_all_inside_dir() { /// `dotdot_at_end_of_symlink_all_inside_dir`, but with a `/.` at the end. /// -/// This fails on Windows for unknown reasons. Patches welcome. +/// Windows doesn't appear to like symlinks that end with `/.`. #[test] -//#[cfg_attr(windows, ignore)] +#[cfg_attr(windows, ignore)] fn dotdot_slashdot_at_end_of_symlink_all_inside_dir() { let tmpdir = tmpdir(); From 09637b8b6e3e3e8cfa94d93e7897d649ff5647fc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 21 Sep 2024 08:22:24 -0700 Subject: [PATCH 8/8] Fix. --- tests/fs_additional.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index b5238436..750e0d4f 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -1062,6 +1062,7 @@ fn dotdot_in_middle_of_symlink() { /// /// Windows doesn't appear to like symlinks that end with `/.`. #[test] +#[cfg_attr(windows, ignore)] fn dotdot_slashdot_in_middle_of_symlink() { let tmpdir = tmpdir();