mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
More robust extension checking
This commit is contained in:
committed by
Pietro Albini
parent
f54dd915b0
commit
bcd7ff18d6
@@ -14,7 +14,7 @@
|
||||
#[macro_use]
|
||||
pub mod compat;
|
||||
|
||||
mod api;
|
||||
pub mod api;
|
||||
|
||||
pub mod alloc;
|
||||
pub mod args;
|
||||
|
||||
@@ -279,11 +279,24 @@ pub fn spawn(
|
||||
None
|
||||
};
|
||||
let program = resolve_exe(&self.program, || env::var_os("PATH"), child_paths)?;
|
||||
// Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
|
||||
let is_batch_file = matches!(
|
||||
program.len().checked_sub(5).and_then(|i| program.get(i..)),
|
||||
Some([46, 98 | 66, 97 | 65, 116 | 84, 0] | [46, 99 | 67, 109 | 77, 100 | 68, 0])
|
||||
);
|
||||
let has_bat_extension = |program: &[u16]| {
|
||||
matches!(
|
||||
// Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
|
||||
program.len().checked_sub(4).and_then(|i| program.get(i..)),
|
||||
Some([46, 98 | 66, 97 | 65, 116 | 84] | [46, 99 | 67, 109 | 77, 100 | 68])
|
||||
)
|
||||
};
|
||||
let is_batch_file = if path::is_verbatim(&program) {
|
||||
has_bat_extension(&program[..program.len() - 1])
|
||||
} else {
|
||||
super::fill_utf16_buf(
|
||||
|buffer, size| unsafe {
|
||||
// resolve the path so we can test the final file name.
|
||||
c::GetFullPathNameW(program.as_ptr(), size, buffer, ptr::null_mut())
|
||||
},
|
||||
|program| has_bat_extension(program),
|
||||
)?
|
||||
};
|
||||
let (program, mut cmd_str) = if is_batch_file {
|
||||
(
|
||||
command_prompt()?,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
use crate::io;
|
||||
use crate::path::{Path, PathBuf, Prefix};
|
||||
use crate::ptr;
|
||||
use crate::sys::api::utf16;
|
||||
use crate::sys::pal::{c, fill_utf16_buf, os2path, to_u16s};
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -20,6 +21,10 @@ pub fn is_verbatim_sep(b: u8) -> bool {
|
||||
b == b'\\'
|
||||
}
|
||||
|
||||
pub fn is_verbatim(path: &[u16]) -> bool {
|
||||
path.starts_with(utf16!(r"\\?\")) || path.starts_with(utf16!(r"\??\"))
|
||||
}
|
||||
|
||||
/// Returns true if `path` looks like a lone filename.
|
||||
pub(crate) fn is_file_name(path: &OsStr) -> bool {
|
||||
!path.as_encoded_bytes().iter().copied().any(is_sep_byte)
|
||||
|
||||
@@ -32,7 +32,9 @@ fn parent() {
|
||||
let bat2 = String::from(bat.to_str().unwrap());
|
||||
bat.set_file_name("windows-bat-args3.bat");
|
||||
let bat3 = String::from(bat.to_str().unwrap());
|
||||
let bat = [bat1.as_str(), bat2.as_str(), bat3.as_str()];
|
||||
bat.set_file_name("windows-bat-args1.bat .. ");
|
||||
let bat4 = String::from(bat.to_str().unwrap());
|
||||
let bat = [bat1.as_str(), bat2.as_str(), bat3.as_str(), bat4.as_str()];
|
||||
|
||||
check_args(&bat, &["a", "b"]).unwrap();
|
||||
check_args(&bat, &["c is for cat", "d is for dog"]).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user