From 18b458530c31b7f6c5e6a721919fbd8573daf61d Mon Sep 17 00:00:00 2001 From: Mykhailo Chalyi Date: Tue, 2 Jun 2026 09:08:37 +0000 Subject: [PATCH 1/2] fix(ci): use integration test binary for cat/tac spec tests in drift workflow --- .github/workflows/coreutils-args-drift.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coreutils-args-drift.yml b/.github/workflows/coreutils-args-drift.yml index 9b61ee7b7..c5169c977 100644 --- a/.github/workflows/coreutils-args-drift.yml +++ b/.github/workflows/coreutils-args-drift.yml @@ -176,7 +176,7 @@ jobs: - name: Run cat/tac spec tests working-directory: bashkit - run: cargo test -p bashkit --test spec_tests bash_spec_tests + run: cargo test -p bashkit --test integration bash_spec_tests # Body-drift gate: rebuild the matching uutils binaries from the # *same* tree the args codegen ran against, then run the From e294406c3cc9fbff67f36bafab2beff9a42cd33c Mon Sep 17 00:00:00 2001 From: Mykhailo Chalyi Date: Tue, 2 Jun 2026 09:58:14 +0000 Subject: [PATCH 2/2] test(fuzz): add regression tests for arithmetic_fuzz null-byte crash inputs Records the two libfuzzer crash artifacts found on May 28 and Jun 1 2026 (crash-b972... and crash-f87f...) as non-panic regression tests. The inputs contain embedded null bytes in arithmetic/command-substitution context; crashing was only reproduced under libfuzzer's sanitizer+smaller- stack configuration. Tests ensure the interpreter never panics on these inputs. --- .../integration/byte_range_panic_tests.rs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/crates/bashkit/tests/integration/byte_range_panic_tests.rs b/crates/bashkit/tests/integration/byte_range_panic_tests.rs index 8e0aa55b7..b87dd62eb 100644 --- a/crates/bashkit/tests/integration/byte_range_panic_tests.rs +++ b/crates/bashkit/tests/integration/byte_range_panic_tests.rs @@ -79,3 +79,49 @@ async fn array_slice_huge_length_no_panic() { // Should not panic — either Ok with clamped slice or a graceful error. let _ = result; } + +/// Regression: arithmetic_fuzz crash (Jun 1 2026) — null bytes inside +/// arithmetic context with command substitution caused a panic. +/// Artifact: crash-f87fe9f09e5a5a307ed625dfc86d1003031c70ae +#[tokio::test] +async fn arith_fuzz_crash_null_bytes_cmdsub_shopt() { + // Raw bytes: )&)h$,\n\0\0$(shopt\t8\t\t\0$\0\0(shop\0t + let input_bytes: &[u8] = b")&)h$,\n\x00\x00$(shopt\t8\t\t\x00$\x00\x00(shop\x00t"; + let input = String::from_utf8_lossy(input_bytes); + let script = format!("echo $(({input})) 2>/dev/null"); + let mut bash = Bash::builder() + .limits( + ExecutionLimits::new() + .max_commands(100) + .max_function_depth(10) + .max_subst_depth(5) + .max_stdout_bytes(4096) + .max_stderr_bytes(4096) + .timeout(std::time::Duration::from_millis(500)), + ) + .build(); + let _ = bash.exec(&script).await; +} + +/// Regression: arithmetic_fuzz crash (May 28 2026) — null bytes and SOH in +/// arithmetic context with array subscript substitution caused a panic. +/// Artifact: crash-b9727354157e9576ec4380c5febb7168f8c1d999 +#[tokio::test] +async fn arith_fuzz_crash_null_bytes_array_subscript() { + // Raw bytes: \x01\0$(b=[${?\0Range\x01"e {D$PWD + let input_bytes: &[u8] = b"\x01\x00$(b=[${?\x00Range\x01\"e {D$PWD"; + let input = String::from_utf8_lossy(input_bytes); + let script = format!("echo $(({input})) 2>/dev/null"); + let mut bash = Bash::builder() + .limits( + ExecutionLimits::new() + .max_commands(100) + .max_function_depth(10) + .max_subst_depth(5) + .max_stdout_bytes(4096) + .max_stderr_bytes(4096) + .timeout(std::time::Duration::from_millis(500)), + ) + .build(); + let _ = bash.exec(&script).await; +}