Skip to content

fix(parser): treat do/done as words inside for/select in-list#2123

Merged
chaliy merged 1 commit into
mainfrom
claude/friendly-einstein-4twqu4
Jun 24, 2026
Merged

fix(parser): treat do/done as words inside for/select in-list#2123
chaliy merged 1 commit into
mainfrom
claude/friendly-einstein-4twqu4

Conversation

@chaliy

@chaliy chaliy commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Problem

The nightly differential proptest (multi_statement_matches_bash) went red on 2026-06-24 (run 28076841758) with the minimal failing input:

for a in do; do echo $a; done
Bashkit: ""   Bash: "do\n"

Root cause

Reserved words (do, done, in, …) are keywords only in command position. Inside a for/select in list they are ordinary words until a list terminator (; or newline). The word-list parser broke the loop on the first Word("do"), so the list parsed as empty and the loop produced no output.

Fix

Remove the special-case do break in both the for and select word-list loops (crates/bashkit/src/parser/mod.rs). The list now ends only at ;/newline/non-word, matching bash. This also makes for a in done; …, multi reserved-word lists, etc. parse correctly.

Tests

Added for_in_reserved_word_tests.rs covering the reproducer plus bash-parity cases. Verified output matches real bash exactly:

script bash & bashkit
for a in do; do echo $a; done do
for a in do done then in; do echo $a; done do/done/then/in
for a in done\ndo echo $a; done done
for a in 1 2 3; do echo $a; done 1/2/3

Note: full cargo test could not run in the authoring sandbox (egress policy blocks the jiter git dep pinned via [patch.crates-io]); the change was verified through a standalone harness against the real bashkit crate and against real bash. CI provides the authoritative check.


Generated by Claude Code

Reserved words (do, done, in, ...) are only keywords in command
position. Inside a `for`/`select` `in` list they are ordinary words
until a list terminator (`;` or newline). The parser broke the
word-list loop on the first `do`, so `for a in do; do echo $a; done`
parsed an empty list and produced no output instead of `do`.

Found by the nightly differential proptest (multi_statement_matches_bash).
Adds for_in_reserved_word_tests.rs covering the reproducer and bash parity.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit f916f88 Commit Preview URL

Branch Preview URL
Jun 24 2026, 09:16 AM

@chaliy chaliy merged commit 2a3a327 into main Jun 24, 2026
35 checks passed
@chaliy chaliy deleted the claude/friendly-einstein-4twqu4 branch June 24, 2026 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant