From 150a0adc9481f4f3f1353dc9f85886ef2ef0e637 Mon Sep 17 00:00:00 2001 From: Mike Chaliy Date: Fri, 22 May 2026 09:09:18 +0000 Subject: [PATCH] fix(rg): reject empty pattern with only-matching Prevent resource-exhaustion triggered by rg -o/--only-matching with an empty pattern, which produces zero-width matches at every UTF-8 boundary and can amplify builtin output allocations before interpreter truncation. Add a parse-time check in RgOptions::parse that returns Error::Execution when --only-matching is enabled and any provided pattern is empty. --- crates/bashkit/src/builtins/rg/mod.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/crates/bashkit/src/builtins/rg/mod.rs b/crates/bashkit/src/builtins/rg/mod.rs index 92167543..a1596569 100644 --- a/crates/bashkit/src/builtins/rg/mod.rs +++ b/crates/bashkit/src/builtins/rg/mod.rs @@ -1130,6 +1130,13 @@ impl RgOptions { } opts.paths = positional; + + if opts.only_matching && opts.patterns.iter().any(|pattern| pattern.is_empty()) { + return Err(Error::Execution( + "rg: empty pattern is not allowed with --only-matching".to_string(), + )); + } + Ok(opts) } @@ -9985,6 +9992,23 @@ mod tests { assert!(!result.stdout.contains("vendor")); } + #[test] + fn test_rg_only_matching_rejects_empty_pattern() { + let args = vec![ + "-o".to_string(), + "-e".to_string(), + "".to_string(), + "/test.txt".to_string(), + ]; + match RgOptions::parse(&args) { + Err(Error::Execution(msg)) => { + assert_eq!(msg, "rg: empty pattern is not allowed with --only-matching") + } + Err(other) => panic!("unexpected error: {other}"), + Ok(_) => panic!("expected parse error"), + } + } + #[tokio::test] async fn test_rg_only_matching_and_quiet() { let only = run_rg(