7
High
// The Bug
How BurntSushi/ripgrep#3222 fixed path traversal in compressed file search — why decompression commands need argument separators to prevent option injection.
// Root Cause
In `crates/cli/src/decompress.rs`, the decompression command was built as:
```rust
let mut cmd = Command::new(&decomp_cmd.bin);
cmd.args(&decomp_cmd.args);
// path added later without separator
cmd.arg(path);
```
If `path` is `--help`, the decompression tool (e.g., `gzip`) would interpret it as a flag and print its help text instead of trying to decompress a file. Worse, a path like `--verbose` could alter the tool's behavior.
```rust
let mut cmd = Command::new(&decomp_cmd.bin);
cmd.args(&decomp_cmd.args);
// path added later without separator
cmd.arg(path);
```
If `path` is `--help`, the decompression tool (e.g., `gzip`) would interpret it as a flag and print its help text instead of trying to decompress a file. Worse, a path like `--verbose` could alter the tool's behavior.
// The Fix
Diff showing the exact changes made to fix the bug.
@@ -180,6 +180,7 @@ impl DecompressionMatcher {
if let Some(i) = self.globs.matches(path).into_iter().next_back() {
let decomp_cmd = &self.commands[i];
let mut cmd = Command::new(&decomp_cmd.bin);
+ cmd.arg("--");
cmd.args(&decomp_cmd.args);
return Some(cmd);
}
@@ -301,6 +301,7 @@ impl<W: WriteColor> SearchWorker<W> {
let bin = self.config.preprocessor.as_ref().unwrap();
let mut cmd = std::process::Command::new(bin);
+ cmd.arg("--");
cmd.arg(path).stdin(Stdio::from(File::open(path)?));