-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Description
On Unix, the Debug impl for Command prints the command using quotes around each argument, e.g.
"ls" "-la" "\"foo \""
The use of spaces as a delimiter suggests that the output is suitable to be passed to a shell. While it's debatable whether users should be depending on any specific debug representation, in practice, at least rustc itself uses it for user-facing output (when passing -Z print-link-args
).
There are two problems with this:
-
It's insecure! The quoting is performed, via the
Debug
impl forCStr
, byascii::escape_default
, whose escaping rules arechosen with a bias toward producing literals that are legal in a variety of languages, including C++11 and similar C-family languages.
However, this does not include escaping the characters $, `, and !, which have a special meaning within double quotes in Unix shell syntax. So, for example:
let mut cmd = Command::new("foo"); cmd.arg("`echo 123`"); println!("{:?}", cmd);
prints
"foo" "`echo 123`"
but if you run that in a shell, it won't produce the same behavior as the original command.
-
It's noisy. In a long command line like those produced by
-Z print-link-args
, most arguments don't contain any characters that need to be quoted or escaped, and the output is long enough without unnecessary quotes.
Cargo uses the shell-escape
crate for this purpose; perhaps that code can be copied into libstd.