From c1f64144b3f3c73e3e7b5d439d73dfe2352ae57c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 26 Aug 2022 10:50:22 -0400 Subject: [PATCH] fs-mistrust: Try to handle verbatim prefixes in test. We have a test that tries to check that our outputs are the same as those from `std::fs::canonicalize`. But on Windows, they aren't: There, `canonicalize` also puts path prefixes into a "Verbatim" form. This patch tries to replicate that behavior for the test only. If we find that it's unreliable, though, our best bet is probably to revise or disable this check on Windows, rather than chasing compatibility with `GetFinalPathNameByHandle`. Should fix part of #557. --- crates/fs-mistrust/src/walk.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/fs-mistrust/src/walk.rs b/crates/fs-mistrust/src/walk.rs index 2d67a5d5f..f5b0916e3 100644 --- a/crates/fs-mistrust/src/walk.rs +++ b/crates/fs-mistrust/src/walk.rs @@ -405,6 +405,36 @@ mod test { } } + /// Helper: change the prefix on `path` (if any) to a verbatim prefix. + /// + /// We do this to match the output of `fs::canonicalize` on Windows, for + /// testing. + /// + /// If this function proves to be hard-to-maintain, we should consider + /// alternative ways of testing what it provides. + fn make_prefix_verbatim(path: PathBuf) -> PathBuf { + let mut components = path.components(); + if let Some(std::path::Component::Prefix(prefix)) = components.next() { + use std::path::Prefix as P; + let verbatim = match prefix.kind() { + P::UNC(server, share) => { + let mut p = OsString::from(r"\\?\UNC\"); + p.push(server); + p.push("/"); + p.push(share); + p + } + P::Disk(disk) => format!(r"\\?\{}:", disk as char).into(), + _ => return path, // original prefix is fine. + }; + let mut newpath = PathBuf::from(verbatim); + newpath.extend(components.map(|c| c.as_os_str())); + newpath + } else { + path // nothing to do. + } + } + #[test] fn simple_path() { let d = testing::Dir::new(); @@ -448,6 +478,7 @@ mod test { assert_eq!(so_far, p); } let (canonical, rest) = r.into_result(); + let canonical = make_prefix_verbatim(canonical); assert_eq!(canonical, d.path("a/b/c").canonicalize().unwrap()); assert!(rest.is_none());