diff options
| author | bors <bors@rust-lang.org> | 2017-06-06 08:38:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-06-06 08:38:50 +0000 |
| commit | 9006db1fb0a543f927398b86cf4475ad3ec332da (patch) | |
| tree | 8cf9dfa1d75771d110424599dafe62880f6e1319 /src/libstd/sys/windows | |
| parent | 17f493fffc4e7b7a4110d2528e9f1272470dda10 (diff) | |
| parent | 02955f508e577d104bcd0f6b8b92e7a7b4657708 (diff) | |
| download | rust-9006db1fb0a543f927398b86cf4475ad3ec332da.tar.gz rust-9006db1fb0a543f927398b86cf4475ad3ec332da.zip | |
Auto merge of #42436 - ollie27:win_spawn_name, r=alexcrichton
Always quote program name in Command::spawn on Windows
[`CreateProcess`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425.aspx) 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/windows')
| -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}\"" ); } } |
