Skip to content

fix(interpreter): close Oils type/hash, redirect, here-doc, shell-option and special-variable gaps - #2644

Merged
chaliy merged 2 commits into
mainfrom
claude/oils-redirect-builtins
Oct 8, 2026
Merged

chaliy merged 2 commits into
mainfrom
claude/oils-redirect-builtins

Conversation

@chaliy

@chaliy chaliy commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

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

What changed

Closes 91 more Oils spec cases in type/hash, command, redirects, here-docs, shell options and special variables. No file gains a new miss.

  • type / hash: full flag set (-a -f -P -p -t). The lookup order matches bash. A bounded command hash table (512 entries) adds hash -r -d -t -l -p and set +h, and PATH= clears the table. A non-executable file on PATH now fails with 126.
  • eval / source: accept --. source searches PATH, which shopt -u sourcepath turns off.
  • shopt, SHELLOPTS, BASHOPTS: bash 5.2's full option list with its defaults. SHELLOPTS and BASHOPTS are computed and readonly, and an exported SHELLOPTS reaches child shells. test -v and test -o now work.
  • Child shells: env -i bash gets bash's minimal environment, and /usr/bin/bash starts a real child shell. -c, -O/+O and -o/+o are parsed the way bash does.
  • Redirects:
    • A redirect target is expanded once and fails with "ambiguous redirect" when it isn't exactly one word.
    • Under 2>&1, stderr is interleaved in write order across groups, functions, scripts, eval, source and child shells.
    • 1<&2 and exec 6>&5- work.
    • N<<EOF and N<<<w on a function, script or group are visible inside it.
    • <&N on a closed fd gives "Bad file descriptor", and &> honours noclobber.
  • Special variables: $_ is tracked. $BASHPID changes in each subshell. UID, EUID and PPID are readonly. $LINENO inside for (( )) reports the for line.
  • wc: counts are padded the way GNU wc pads them.

Why

This is step 1 (fidelity) and step 5 (measurement) of the level-up roadmap: closing the largest groups of Oils misses outside the areas the BashBox work owns.

Before / After (verified)

Full Oils run, saved as scripts/oils-spec/results/oils-spec-linux-x86_64-20261008T152730Z:

Cases passed (of bash's 2692) Rate
Before (#2643) 2120 78.8%
After 2211 82.1%

Per-file misses, before → after:

File Before After
builtin-type-bash 12 0
command_ 7 0
redirect-multi 9 0
here-doc 6 0
sh-options-bash 6 0
sh-options 11 4
vars-special 11 4
redirect 7 2

Files that pass completely went from 28 to 36. The bash oracle is unchanged at 104/102.

A new regression file, redirect-and-shell-builtins.test.sh (24 cases), was checked against bash 5.2. The remaining misses are documented in limitations.md: FIFO <>, interactive-only cases, the empty-by-design startup environment, and $LINENO in a top-level (( )).

Risk

  • Security: two new threats, TM-DOS-129 (hash table growth, bounded) and TM-INJ-026 (redirect target re-expansion). TM-DOS-063 now also covers here-doc fds. Each has a test, and a refused here-doc fd now closes the fds the same command had already opened.
  • Stack: the depth_32 case needs 1,891,601 bytes, which is 3.6 KB over main and well under CI's 2 MB stack. Redirect preparation and builtin output now run in boxed futures to keep the hot path small.
  • Changed tests:
    • tm_dos_060 now uses a budget of 1, because $_ exists at startup and isn't counted.
    • ln.test.sh uses cd /tmp/, so the bash comparison maps the path to a private directory.

Checklist

  • fmt, clippy -D warnings
  • integration 1471, lib 2950, terminal 52, bashkit-cli, bash_comparison
  • just check-okf, just check-doc-links
  • knowledge (log, limitations, oils-spec, threat-model) updated

Generated by Claude Code

…ion and special-variable gaps

type/hash follow bash (flags, hashed paths, relative PATH entries, a
bounded command hash table); eval/source accept `--`; shopt knows bash
5.2's options and defaults; test gains -v/-o; SHELLOPTS/BASHOPTS are
computed readonly variables and `export SHELLOPTS` reaches child shells;
bash parses -c/-O/+O/-/-- like bash.

Redirect targets expand once (ambiguous redirect, failglob, no globbing
of quoted text); 2>&1 merges stderr in write order for groups, functions,
scripts, eval, source and child shells; 1<&2, exec N>&M-, per-command
N<<EOF fds, `<&N` on a closed fd, noclobber for &>, here-doc line
continuation. $_, $BASHPID, readonly UID/EUID/PPID, env -i startup
variables, LINENO in for (( )), GNU wc padding.

Oils spec 78.8% -> 82.1% (2120 -> 2211 of 2692), no new misses.
@chaliy chaliy self-assigned this Oct 8, 2026
@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 49217b1 Commit Preview URL

Branch Preview URL
Oct 08 2026, 03:34 PM

@chaliy
chaliy merged commit 26a3acc into main Oct 8, 2026
49 checks passed
@chaliy
chaliy deleted the claude/oils-redirect-builtins branch October 8, 2026 15:55
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