diff --git a/crates/cargo-test-support/Cargo.toml b/crates/cargo-test-support/Cargo.toml index 64c1f3c5f9b..81ef1bcb703 100644 --- a/crates/cargo-test-support/Cargo.toml +++ b/crates/cargo-test-support/Cargo.toml @@ -25,5 +25,8 @@ termcolor = "1.1.2" toml_edit = { version = "0.14.3", features = ["serde", "easy", "perf"] } url = "2.2.2" +[target.'cfg(windows)'.dependencies] +winapi = "0.3" + [features] deny-warnings = [] diff --git a/crates/cargo-test-support/src/paths.rs b/crates/cargo-test-support/src/paths.rs index 29b3687969b..b1c62b99e6a 100644 --- a/crates/cargo-test-support/src/paths.rs +++ b/crates/cargo-test-support/src/paths.rs @@ -287,3 +287,54 @@ pub fn sysroot() -> String { let sysroot = String::from_utf8(output.stdout).unwrap(); sysroot.trim().to_string() } + +/// Returns true if names such as aux.* are allowed. +/// +/// Traditionally, Windows did not allow a set of file names (see `is_windows_reserved` +/// for a list). More recent versions of Windows have relaxed this restriction. This test +/// determines whether we are running in a mode that allows Windows reserved names. +#[cfg(windows)] +pub fn windows_reserved_names_are_allowed() -> bool { + use std::ffi::OsStr; + use std::os::windows::ffi::OsStrExt; + use std::ptr; + use winapi::um::fileapi::GetFullPathNameW; + + let test_file_name: Vec<_> = OsStr::new("aux.rs").encode_wide().collect(); + + let buffer_length = + unsafe { GetFullPathNameW(test_file_name.as_ptr(), 0, ptr::null_mut(), ptr::null_mut()) }; + + if buffer_length == 0 { + // This means the call failed, so we'll conservatively assume reserved names are not allowed. + return false; + } + + let mut buffer = vec![0u16; buffer_length as usize]; + + let result = unsafe { + GetFullPathNameW( + test_file_name.as_ptr(), + buffer_length, + buffer.as_mut_ptr(), + ptr::null_mut(), + ) + }; + + if result == 0 { + // Once again, conservatively assume reserved names are not allowed if the + // GetFullPathNameW call failed. + return false; + } + + // Under the old rules, a file name like aux.rs would get converted into \\.\aux, so + // we detect this case by checking if the string starts with \\.\ + // + // Otherwise, the filename will be something like C:\Users\Foo\Documents\aux.rs + let prefix: Vec<_> = OsStr::new("\\\\.\\").encode_wide().collect(); + if buffer.starts_with(&prefix) { + false + } else { + true + } +} diff --git a/src/cargo/util/restricted_names.rs b/src/cargo/util/restricted_names.rs index 16b047bd8c3..650ae233059 100644 --- a/src/cargo/util/restricted_names.rs +++ b/src/cargo/util/restricted_names.rs @@ -97,59 +97,3 @@ pub fn is_windows_reserved_path(path: &Path) -> bool { pub fn is_glob_pattern>(name: T) -> bool { name.as_ref().contains(&['*', '?', '[', ']'][..]) } - -/// Returns true if names such as aux.* are allowed. -/// -/// Traditionally, Windows did not allow a set of file names (see `is_windows_reserved` -/// for a list). More recent versions of Windows have relaxed this restriction. This test -/// determines whether we are running in a mode that allows Windows reserved names. -pub fn windows_reserved_names_are_allowed() -> bool { - #[cfg(windows)] - { - use std::ffi::OsStr; - use std::os::windows::ffi::OsStrExt; - use std::ptr; - use winapi::um::fileapi::GetFullPathNameW; - - let test_file_name: Vec<_> = OsStr::new("aux.rs").encode_wide().collect(); - - let buffer_length = unsafe { - GetFullPathNameW(test_file_name.as_ptr(), 0, ptr::null_mut(), ptr::null_mut()) - }; - - if buffer_length == 0 { - // This means the call failed, so we'll conservatively assume reserved names are not allowed. - return false; - } - - let mut buffer = vec![0u16; buffer_length as usize]; - - let result = unsafe { - GetFullPathNameW( - test_file_name.as_ptr(), - buffer_length, - buffer.as_mut_ptr(), - ptr::null_mut(), - ) - }; - - if result == 0 { - // Once again, conservatively assume reserved names are not allowed if the - // GetFullPathNameW call failed. - return false; - } - - // Under the old rules, a file name like aux.rs would get converted into \\.\aux, so - // we detect this case by checking if the string starts with \\.\ - // - // Otherwise, the filename will be something like C:\Users\Foo\Documents\aux.rs - let prefix: Vec<_> = OsStr::new("\\\\.\\").encode_wide().collect(); - if buffer.starts_with(&prefix) { - false - } else { - true - } - } - #[cfg(not(windows))] - true -} diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index 19ae6c639c7..63e384af88e 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -2011,7 +2011,7 @@ src/lib.rs fn reserved_windows_name() { // If we are running on a version of Windows that allows these reserved filenames, // skip this test. - if cargo::util::restricted_names::windows_reserved_names_are_allowed() { + if paths::windows_reserved_names_are_allowed() { return; }