From 1a8aa96b7fb488cf6306900eda417deb51188f99 Mon Sep 17 00:00:00 2001 From: David Knaack Date: Thu, 24 Feb 2022 00:32:35 +0100 Subject: [PATCH] fix(windows): avoid verbatim paths (#3638) --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + clippy.toml | 2 ++ src/context.rs | 27 +++++++++++++++++++++------ src/modules/directory.rs | 6 +++--- src/modules/pulumi.rs | 4 ++-- 6 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13bcc7ca..ca2fa0fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,6 +496,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" +[[package]] +name = "dunce" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" + [[package]] name = "easy-parallel" version = "3.2.0" @@ -1605,6 +1611,7 @@ dependencies = [ "clap", "clap_complete", "directories-next", + "dunce", "gethostname", "git2", "indexmap", diff --git a/Cargo.toml b/Cargo.toml index 0bbbeb47..e17b51fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ chrono = "0.4.19" clap = { version = "3.1.0", features = ["derive", "cargo", "unicode"] } clap_complete = "3.1.0" directories-next = "2.0.0" +dunce = "1.0.2" gethostname = "0.2.2" git2 = { version = "0.13.25", default-features = false } indexmap = { version = "1.8.0", features = ["serde"] } diff --git a/clippy.toml b/clippy.toml index 394d9b4c..4715dab3 100644 --- a/clippy.toml +++ b/clippy.toml @@ -3,4 +3,6 @@ disallowed-methods = [ "std::process::Command::new", # Setting environment variables can cause issues with non-rust code "std::env::set_var", + # use `dunce` to avoid UNC/verbatim paths, where possible + "std::fs::canonicalize", ] diff --git a/src/context.rs b/src/context.rs index d0910066..952b48a1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -137,9 +137,9 @@ impl<'a> Context<'a> { } // Canonicalize the current path to resolve symlinks, etc. - // NOTE: On Windows this converts the path to extended-path syntax. + // NOTE: On Windows this may convert the path to extended-path syntax. let current_dir = Context::expand_tilde(path); - let current_dir = current_dir.canonicalize().unwrap_or(current_dir); + let current_dir = dunce::canonicalize(¤t_dir).unwrap_or(current_dir); let logical_dir = logical_path; let root_config = config @@ -734,10 +734,8 @@ mod tests { assert_ne!(context.current_dir, context.logical_dir); - let expected_current_dir = path_actual - .join("yyy") - .canonicalize() - .expect("canonicalize"); + let expected_current_dir = + dunce::canonicalize(path_actual.join("yyy")).expect("canonicalize"); assert_eq!(expected_current_dir, context.current_dir); let expected_logical_dir = test_path; @@ -787,4 +785,21 @@ mod tests { let expected_logical_dir = test_path; assert_eq!(expected_logical_dir, context.logical_dir); } + + #[cfg(windows)] + #[test] + fn strip_extended_path_prefix() { + let test_path = Path::new(r"\\?\C:\").to_path_buf(); + let context = Context::new_with_shell_and_path( + Properties::default(), + Shell::Unknown, + Target::Main, + test_path.clone(), + test_path, + ); + + let expected_path = Path::new(r"C:\"); + + assert_eq!(&context.current_dir, expected_path); + } } diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 50cbfe4e..ddbe8588 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -364,8 +364,8 @@ mod tests { fs::create_dir_all(&src_dir)?; init_repo(&repo_dir)?; - let src_variations = [src_dir.clone(), src_dir.canonicalize().unwrap()]; - let repo_variations = [repo_dir.clone(), repo_dir.canonicalize().unwrap()]; + let src_variations = [src_dir.clone(), dunce::canonicalize(src_dir).unwrap()]; + let repo_variations = [repo_dir.clone(), dunce::canonicalize(repo_dir).unwrap()]; for src_dir in &src_variations { for repo_dir in &repo_variations { let output = contract_repo_path(src_dir, repo_dir); @@ -1590,7 +1590,7 @@ mod tests { #[test] #[cfg(windows)] fn windows_trims_extended_unc_path_prefix() { - // Under Windows, path canonicalization returns UNC paths using extended-path prefixes `\\?\UNC\` + // Under Windows, path canonicalization may return UNC paths using extended-path prefixes `\\?\UNC\` // We expect this prefix to be trimmed before being rendered. let unc_path = Path::new(r"\\?\UNC\server\share\a\b\c"); diff --git a/src/modules/pulumi.rs b/src/modules/pulumi.rs index fdd6dd5f..7329008d 100644 --- a/src/modules/pulumi.rs +++ b/src/modules/pulumi.rs @@ -270,7 +270,7 @@ mod tests { fn render_valid_paths() -> io::Result<()> { use io::Write; let dir = tempfile::tempdir()?; - let root = std::fs::canonicalize(dir.path())?; + let root = dunce::canonicalize(dir.path())?; let mut yaml = File::create(root.join("Pulumi.yml"))?; yaml.write_all("name: starship\nruntime: nodejs\ndescription: A thing\n".as_bytes())?; yaml.sync_all()?; @@ -337,7 +337,7 @@ mod tests { fn partial_login() -> io::Result<()> { use io::Write; let dir = tempfile::tempdir()?; - let root = std::fs::canonicalize(dir.path())?; + let root = dunce::canonicalize(dir.path())?; let mut yaml = File::create(root.join("Pulumi.yml"))?; yaml.write_all("name: starship\nruntime: nodejs\ndescription: A thing\n".as_bytes())?; yaml.sync_all()?;