Skip to content

fix(builtins): return, unset -v and read reject bad arguments - #2613

Merged
chaliy merged 1 commit into
mainfrom
claude/builtin-arg-validation
Oct 8, 2026
Merged

chaliy merged 1 commit into
mainfrom
claude/builtin-arg-validation

Conversation

@chaliy

@chaliy chaliy commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

Four builtin argument checks bash makes and bashkit did not:

  • return outside a function or a sourced script reports and exits 2, and the script carries on
  • return N inside a sourced script is source's status
  • unset -v insists the name is one it could have assigned; plain unset and unset -f still take any word
  • read -t and read -n report a non-numeric argument instead of ignoring the option

Why

The return case is the one that bites. A stray top-level return — left over
from editing, or in a file meant to be sourced and run directly instead — ended
the whole run with status 0. The script looked like it succeeded while most of
it never ran.

Before / After

return
echo "rc=$?"
echo after
output status
bash 5.2 bash: return: can only \return' from a function or sourced scripton stderr, thenrc=2, after` 0
bashkit before (nothing — the script stopped here) 0
bashkit after same as bash 0
printf 'echo in\nreturn 4\necho no\n' > s.sh
. ./s.sh; echo "rc=$?"
output
bash 5.2 in, rc=4
bashkit before in, rc=0
bashkit after in, rc=4
call bash 5.2 bashkit before bashkit after
unset -v 'arr[' unset: `arr[': not a valid identifier, 1 (silent), 0 same as bash, 1
unset 'arr[' 0 0 0
unset -v 'a[0]' removes the element, 0 same same
read -t abc x read: abc: invalid timeout specification, 1 (silent), 0 same as bash, 1
read -n abc x read: abc: invalid number, 1 (silent), 0 same as bash, 1

Risk

Low. return inside a function and read -n 3 are covered by new tests and
unchanged. The interpreter gained a source_depth counter so return can tell
a sourced script from a top-level one; a frame that only carries top-level
positional parameters (bashkit script.sh a b) does not make return legal,
which is what bash does.

read -d with no argument still exits 1 rather than bash's 2-with-usage; that
is a separate gap and not touched here.

Checklist

  • cargo test -p bashkit --lib (2916 passed)
  • cargo test -p bashkit --test integration (1360 passed)
  • 9 new spec cases and 9 integration tests, verified against bash 5.2
  • bash_comparison differential tests against real bash
  • cargo clippy -p bashkit --all-targets -- -D warnings
  • cargo fmt --all --check
  • cargo test -p bashkit-cli (56 passed)
  • just check-okf
  • Stack probe: 1900 KB, inside the two-MiB TM-DOS-020 budget
  • Knowledge updated (log.md)

https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA


Generated by Claude Code

`return` at the top level ended the script with status 0 instead of
reporting a usage error, so a stray `return` silently truncated a run.
`return N` inside a sourced script lost its status. `unset -v` accepted
names it could never have assigned, and `read -t`/`-n` ignored a
non-numeric argument instead of failing.

Claude-Session: https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA
@chaliy chaliy self-assigned this Oct 7, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 7, 2026 •

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 956b99b Commit Preview URL

Branch Preview URL
Oct 07 2026, 11:53 PM

@chaliy
chaliy merged commit bb2165b into main Oct 8, 2026
44 checks passed
@chaliy
chaliy deleted the claude/builtin-arg-validation branch October 8, 2026 01:19
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