Quote bat script command line
This commit is contained in:
@@ -416,3 +416,22 @@ fn env_empty() {
|
|||||||
let p = Command::new("cmd").args(&["/C", "exit 0"]).env_clear().spawn();
|
let p = Command::new("cmd").args(&["/C", "exit 0"]).env_clear().spawn();
|
||||||
assert!(p.is_ok());
|
assert!(p.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See issue #91991
|
||||||
|
#[test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn run_bat_script() {
|
||||||
|
let tempdir = crate::sys_common::io::test::tmpdir();
|
||||||
|
let script_path = tempdir.join("hello.cmd");
|
||||||
|
|
||||||
|
crate::fs::write(&script_path, "@echo Hello, %~1!").unwrap();
|
||||||
|
let output = Command::new(&script_path)
|
||||||
|
.arg("fellow Rustaceans")
|
||||||
|
.stdout(crate::process::Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap()
|
||||||
|
.wait_with_output()
|
||||||
|
.unwrap();
|
||||||
|
assert!(output.status.success());
|
||||||
|
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "Hello, fellow Rustaceans!");
|
||||||
|
}
|
||||||
|
|||||||
@@ -704,6 +704,19 @@ fn make_command_line(prog: &OsStr, args: &[Arg], force_quotes: bool) -> io::Resu
|
|||||||
// Encode the command and arguments in a command line string such
|
// Encode the command and arguments in a command line string such
|
||||||
// that the spawned process may recover them using CommandLineToArgvW.
|
// that the spawned process may recover them using CommandLineToArgvW.
|
||||||
let mut cmd: Vec<u16> = Vec::new();
|
let mut cmd: Vec<u16> = Vec::new();
|
||||||
|
|
||||||
|
// CreateFileW has special handling for .bat and .cmd files, which means we
|
||||||
|
// need to add an extra pair of quotes surrounding the whole command line
|
||||||
|
// so they are properly passed on to the script.
|
||||||
|
// See issue #91991.
|
||||||
|
let is_batch_file = Path::new(prog)
|
||||||
|
.extension()
|
||||||
|
.map(|ext| ext.eq_ignore_ascii_case("cmd") || ext.eq_ignore_ascii_case("bat"))
|
||||||
|
.unwrap_or(false);
|
||||||
|
if is_batch_file {
|
||||||
|
cmd.push(b'"' as u16);
|
||||||
|
}
|
||||||
|
|
||||||
// Always quote the program name so CreateProcess doesn't interpret args as
|
// Always quote the program name so CreateProcess doesn't interpret args as
|
||||||
// part of the name if the binary wasn't found first time.
|
// part of the name if the binary wasn't found first time.
|
||||||
append_arg(&mut cmd, prog, Quote::Always)?;
|
append_arg(&mut cmd, prog, Quote::Always)?;
|
||||||
@@ -715,6 +728,9 @@ fn make_command_line(prog: &OsStr, args: &[Arg], force_quotes: bool) -> io::Resu
|
|||||||
};
|
};
|
||||||
append_arg(&mut cmd, arg, quote)?;
|
append_arg(&mut cmd, arg, quote)?;
|
||||||
}
|
}
|
||||||
|
if is_batch_file {
|
||||||
|
cmd.push(b'"' as u16);
|
||||||
|
}
|
||||||
return Ok(cmd);
|
return Ok(cmd);
|
||||||
|
|
||||||
fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, quote: Quote) -> io::Result<()> {
|
fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, quote: Quote) -> io::Result<()> {
|
||||||
|
|||||||
Reference in New Issue
Block a user