From 02133dc97e28023f9f973c6f8ac2234521737ada Mon Sep 17 00:00:00 2001 From: weili <541602953@qq.com> Date: Fri, 12 Jun 2026 06:07:58 +0000 Subject: [PATCH] xargs: do not panic on empty input in replace mode In replace mode (-I/-i/--replace) xargs runs the command once per input item, so with empty input it should run nothing. Instead the final builder was still executed and `CommandBuilder::execute` indexed `extra_args[0]`, which is empty for no input, panicking with index-out-of-bounds. Treat replace mode as implying --no-run-if-empty (as GNU does) so empty input runs nothing and exits 0. --- src/xargs/mod.rs | 2 +- tests/test_xargs.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/xargs/mod.rs b/src/xargs/mod.rs index cf3638df..9679a05a 100644 --- a/src/xargs/mod.rs +++ b/src/xargs/mod.rs @@ -1159,7 +1159,7 @@ fn do_xargs(args: &[&str]) -> Result { options.exit_if_pass_char_limit, options.max_args, options.max_lines, - options.no_run_if_empty, + options.no_run_if_empty || options.replace.is_some(), ), )?; Ok(result) diff --git a/tests/test_xargs.rs b/tests/test_xargs.rs index 3faa0421..3bbe17f2 100644 --- a/tests/test_xargs.rs +++ b/tests/test_xargs.rs @@ -73,6 +73,15 @@ fn xargs_if_empty() { ucmd().args(&["--no-run-if-empty"]).succeeds().no_output(); } +#[test] +fn xargs_replace_empty_input() { + ucmd() + .args(&["-I", "{}", "echo", "hello", "{}"]) + .succeeds() + .no_output(); + ucmd().args(&["-i", "echo", "{}"]).succeeds().no_output(); +} + #[test] fn xargs_max_args() { ucmd()