summary refs log tree commit diff
path: root/library/std/src/process.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/process.rs')
-rw-r--r--library/std/src/process.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 4a7f5d8e0be..b98ed05c394 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -88,6 +88,47 @@
 //! assert_eq!(b"test", output.stdout.as_slice());
 //! ```
 //!
+//! # Windows argument splitting
+//!
+//! On Unix systems arguments are passed to a new process as an array of strings
+//! but on Windows arguments are passed as a single commandline string and it's
+//! up to the child process to parse it into an array. Therefore the parent and
+//! child processes must agree on how the commandline string is encoded.
+//!
+//! Most programs use the standard C run-time `argv`, which in practice results
+//! in consistent argument handling. However some programs have their own way of
+//! parsing the commandline string. In these cases using [`arg`] or [`args`] may
+//! result in the child process seeing a different array of arguments then the
+//! parent process intended.
+//!
+//! Two ways of mitigating this are:
+//!
+//! * Validate untrusted input so that only a safe subset is allowed.
+//! * Use [`raw_arg`] to build a custom commandline. This bypasses the escaping
+//!   rules used by [`arg`] so should be used with due caution.
+//!
+//! `cmd.exe` and `.bat` use non-standard argument parsing and are especially
+//! vulnerable to malicious input as they may be used to run arbitrary shell
+//! commands. Untrusted arguments should be restricted as much as possible.
+//! For examples on handling this see [`raw_arg`].
+//!
+//! ### Bat file special handling
+//!
+//! On Windows, `Command` uses the Windows API function [`CreateProcessW`] to
+//! spawn new processes. An undocumented feature of this function is that,
+//! when given a `.bat` file as the application to run, it will automatically
+//! convert that into running `cmd.exe /c` with the bat file as the next argument.
+//!
+//! For historical reasons Rust currently preserves this behaviour when using
+//! [`Command::new`], and escapes the arguments according to `cmd.exe` rules.
+//! Due to the complexity of `cmd.exe` argument handling, it might not be
+//! possible to safely escape some special chars, and using them will result
+//! in an error being returned at process spawn. The set of unescapeable
+//! special chars might change between releases.
+//!
+//! Also note that running `.bat` scripts in this way may be removed in the
+//! future and so should not be relied upon.
+//!
 //! [`spawn`]: Command::spawn
 //! [`output`]: Command::output
 //!
@@ -97,6 +138,12 @@
 //!
 //! [`Write`]: io::Write
 //! [`Read`]: io::Read
+//!
+//! [`arg`]: Command::arg
+//! [`args`]: Command::args
+//! [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg
+//!
+//! [`CreateProcessW`]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
 
 #![stable(feature = "process", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
@@ -611,6 +658,22 @@ impl Command {
     /// escaped characters, word splitting, glob patterns, variable substitution, etc.
     /// have no effect.
     ///
+    /// <div class="warning">
+    ///
+    /// On Windows use caution with untrusted inputs. Most applications use the
+    /// standard convention for decoding arguments passed to them. These are safe to use with `arg`.
+    /// However some applications, such as `cmd.exe` and `.bat` files, use a non-standard way of decoding arguments
+    /// and are therefore vulnerable to malicious input.
+    /// In the case of `cmd.exe` this is especially important because a malicious argument can potentially run arbitrary shell commands.
+    ///
+    /// See [Windows argument splitting][windows-args] for more details
+    /// or [`raw_arg`] for manually implementing non-standard argument encoding.
+    ///
+    /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg
+    /// [windows-args]: crate::process#windows-argument-splitting
+    ///
+    /// </div>
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -641,6 +704,22 @@ impl Command {
     /// escaped characters, word splitting, glob patterns, variable substitution, etc.
     /// have no effect.
     ///
+    /// <div class="warning">
+    ///
+    /// On Windows use caution with untrusted inputs. Most applications use the
+    /// standard convention for decoding arguments passed to them. These are safe to use with `args`.
+    /// However some applications, such as `cmd.exe` and `.bat` files, use a non-standard way of decoding arguments
+    /// and are therefore vulnerable to malicious input.
+    /// In the case of `cmd.exe` this is especially important because a malicious argument can potentially run arbitrary shell commands.
+    ///
+    /// See [Windows argument splitting][windows-args] for more details
+    /// or [`raw_arg`] for manually implementing non-standard argument encoding.
+    ///
+    /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg
+    /// [windows-args]: crate::process#windows-argument-splitting
+    ///
+    /// </div>
+    ///
     /// # Examples
     ///
     /// Basic usage: