Skip to content

Commit

Permalink
Move Windows path test function to test code
Browse files Browse the repository at this point in the history
  • Loading branch information
eholk committed Aug 3, 2022
1 parent d03530f commit e9c7544
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 57 deletions.
3 changes: 3 additions & 0 deletions crates/cargo-test-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
51 changes: 51 additions & 0 deletions crates/cargo-test-support/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
56 changes: 0 additions & 56 deletions src/cargo/util/restricted_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,59 +97,3 @@ pub fn is_windows_reserved_path(path: &Path) -> bool {
pub fn is_glob_pattern<T: AsRef<str>>(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
}
2 changes: 1 addition & 1 deletion tests/testsuite/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit e9c7544

Please sign in to comment.