Rollup merge of #108218 - ChrisDenton:cmd-escape, r=cuviper
Windows: Quote more batch file arguments Make sure to always quote batch file arguments that contain command prompt special characters. Additionally add `/d` command line parameter to disable any autorun scripts that may change the way variable expansion works. This makes it more consistent across systems and may help avoid surprises. ## Background Info [`CreateProcess`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw) with the `lpApplicationName` set can only be used to run `.exe` files and not script files such as `.bat`. However, for historical reasons, we do have special handling so that `.bat` files will be correctly run with `cmd.exe` as the application. In Windows, command line arguments are passed as a single string (not an array). Applications can parse this string however they like but most follow the standard MSVC C/C++ convention. But `cmd.exe` uses different argument parsing rules to other Windows programs (because it emulates old DOS). This PR aims to help smooth over some of the differences. r? libs
This commit is contained in:
commit
c4a4bce695
@ -270,7 +270,7 @@ pub(crate) fn make_bat_command_line(
|
|||||||
// It is necessary to surround the command in an extra pair of quotes,
|
// It is necessary to surround the command in an extra pair of quotes,
|
||||||
// hence the trailing quote here. It will be closed after all arguments
|
// hence the trailing quote here. It will be closed after all arguments
|
||||||
// have been added.
|
// have been added.
|
||||||
let mut cmd: Vec<u16> = "cmd.exe /c \"".encode_utf16().collect();
|
let mut cmd: Vec<u16> = "cmd.exe /d /c \"".encode_utf16().collect();
|
||||||
|
|
||||||
// Push the script name surrounded by its quote pair.
|
// Push the script name surrounded by its quote pair.
|
||||||
cmd.push(b'"' as u16);
|
cmd.push(b'"' as u16);
|
||||||
@ -290,6 +290,15 @@ pub(crate) fn make_bat_command_line(
|
|||||||
// reconstructed by the batch script by default.
|
// reconstructed by the batch script by default.
|
||||||
for arg in args {
|
for arg in args {
|
||||||
cmd.push(' ' as u16);
|
cmd.push(' ' as u16);
|
||||||
|
// Make sure to always quote special command prompt characters, including:
|
||||||
|
// * Characters `cmd /?` says require quotes.
|
||||||
|
// * `%` for environment variables, as in `%TMP%`.
|
||||||
|
// * `|<>` pipe/redirect characters.
|
||||||
|
const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
|
||||||
|
let force_quotes = match arg {
|
||||||
|
Arg::Regular(arg) if !force_quotes => arg.bytes().iter().any(|c| SPECIAL.contains(c)),
|
||||||
|
_ => force_quotes,
|
||||||
|
};
|
||||||
append_arg(&mut cmd, arg, force_quotes)?;
|
append_arg(&mut cmd, arg, force_quotes)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user