From 1a4517a200fe16850a567922544eafb356b59c23 Mon Sep 17 00:00:00 2001 From: Fernando Dingler Date: Wed, 21 Oct 2026 05:16:21 +0000 Subject: [PATCH] fix: apply max_input to the whole multiline input --- src/exec.rs | 5 ++++- tests/shell_integration.rs | 39 ++++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/exec.rs b/src/exec.rs index 1c9a853..f309453 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -149,7 +149,10 @@ async fn run_script( /// Execute a full input line. `proc` is the shell's process — cd modifies it. /// Returns (exit_code, should_exit). pub async fn execute(os: Arc, proc: &mut Process, input: &str) -> (i32, bool) { - let result = if input.contains('\n') { + let result = if proc.max_input > 0 && input.len() > proc.max_input { + proc.err_msg("strands-shell: input too large"); + (1, false) + } else if input.contains('\n') { execute_sourced(os.clone(), proc, input).await } else { execute_with_reader(os.clone(), proc, input, &mut |_| None).await diff --git a/tests/shell_integration.rs b/tests/shell_integration.rs index 24739e4..c3a57a6 100644 --- a/tests/shell_integration.rs +++ b/tests/shell_integration.rs @@ -4075,6 +4075,26 @@ fn builder_max_input() { })); } +#[test] +fn max_input_applies_to_whole_multiline_input() { + let (rt, local) = rt(); + rt.block_on(local.run_until(async { + let mut shell = Shell::builder().max_input(16).build().unwrap(); + // Each line is under the limit, but the whole input is not + let out = shell.run("echo aaaa\necho bbbb\necho cccc").await; + assert_eq!( + (out.status, out.stdout.as_str(), out.stderr.as_str()), + (1, "", "strands-shell: input too large\n") + ); + // Multiline input within the limit still runs + let out = shell.run("echo a\necho b").await; + assert_eq!( + (out.status, out.stdout.as_str(), out.stderr.as_str()), + (0, "a\nb\n", "") + ); + })); +} + #[test] fn builder_max_file_size() { let (rt, local) = rt(); @@ -4250,17 +4270,24 @@ fn max_output_truncates_subst() { fn max_input_in_subst() { let (rt, local) = rt(); rt.block_on(local.run_until(async { - // The top-level command is `cat <