diff options
| author | Oliver Middleton <olliemail27@gmail.com> | 2017-06-04 21:47:24 +0100 |
|---|---|---|
| committer | Oliver Middleton <olliemail27@gmail.com> | 2017-06-04 21:47:24 +0100 |
| commit | 7afcf51fe4f635ff4e864ee13085397b41880fa6 (patch) | |
| tree | f8498827dc96cd05f6c448a23d404469f64f0a04 /src/libstd/sys | |
| parent | 0da9721ab49d80bf74208e94a891b12c4a248507 (diff) | |
| download | rust-7afcf51fe4f635ff4e864ee13085397b41880fa6.tar.gz rust-7afcf51fe4f635ff4e864ee13085397b41880fa6.zip | |
Always quote program name in Command::spawn on Windows
`CreateProcess` will interpret args as part of the binary name if it
doesn't find the binary using just the unquoted name. For example if
`foo.exe` doesn't exist, `Command::new("foo").arg("bar").spawn()` will
try to launch `foo bar.exe` which is clearly not desired.
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/windows/process.rs | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index dfbc1b581ee..0bd0ce73138 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -427,20 +427,22 @@ fn make_command_line(prog: &OsStr, args: &[OsString]) -> io::Result<Vec<u16>> { // Encode the command and arguments in a command line string such // that the spawned process may recover them using CommandLineToArgvW. let mut cmd: Vec<u16> = Vec::new(); - append_arg(&mut cmd, prog)?; + // Always quote the program name so CreateProcess doesn't interpret args as + // part of the name if the binary wasn't found first time. + append_arg(&mut cmd, prog, true)?; for arg in args { cmd.push(' ' as u16); - append_arg(&mut cmd, arg)?; + append_arg(&mut cmd, arg, false)?; } return Ok(cmd); - fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr) -> io::Result<()> { + fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, force_quotes: bool) -> io::Result<()> { // If an argument has 0 characters then we need to quote it to ensure // that it actually gets passed through on the command line or otherwise // it will be dropped entirely when parsed on the other end. ensure_no_nuls(arg)?; let arg_bytes = &arg.as_inner().inner.as_inner(); - let quote = arg_bytes.iter().any(|c| *c == b' ' || *c == b'\t') + let quote = force_quotes || arg_bytes.iter().any(|c| *c == b' ' || *c == b'\t') || arg_bytes.is_empty(); if quote { cmd.push('"' as u16); @@ -526,7 +528,7 @@ mod tests { assert_eq!( test_wrapper("prog", &["aaa", "bbb", "ccc"]), - "prog aaa bbb ccc" + "\"prog\" aaa bbb ccc" ); assert_eq!( @@ -539,15 +541,15 @@ mod tests { ); assert_eq!( test_wrapper("echo", &["a b c"]), - "echo \"a b c\"" + "\"echo\" \"a b c\"" ); assert_eq!( test_wrapper("echo", &["\" \\\" \\", "\\"]), - "echo \"\\\" \\\\\\\" \\\\\" \\" + "\"echo\" \"\\\" \\\\\\\" \\\\\" \\" ); assert_eq!( test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]), - "\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}" + "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\"" ); } } |
