Repository navigation
fix(core): keep the portable shell scanner linear in argument count - #59163
LeizhenZhang wants to merge 1 commit into
Conversation
Each word re-walked the precommand chain and copied every earlier operand to classify printf, set and declare arguments, so one command with many arguments took quadratic time. The builtin lookup now resumes where it stopped and reads each operand once. printf with 32000 operands drops from about 7.7 s to about 35 ms.
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
There was a problem hiding this comment.
Looks good. I compared the base and PR scanners directly. The quadratic cases from #59165 drop from 0.6–10.8 s to 8–31 ms. A differential check of 450k random bash/zsh/posix scans (precommand chains, exec -a, --, printf -v/print -v, set -A/+A, declare option clusters, separators and subshells) gave no differences. bun test test/shell-scan/ passes, and so does tsc through typecheck:tsc (the typecheck script itself fails on base and PR alike with Script not found "check", a local tooling issue). The cached lookup state is safe because state.words is only appended to within a command, and the cache is reset in finishBashCommand. The new time-limit tests run in about 10–30 ms against a 500 ms limit, so they shouldn't be flaky.
Public API is unchanged (internal scanner only).
Fixes #59165
Issue for this PR
Closes #59165
Type of change
What does this PR do?
ShellScan.scanclassified each word by walking the precommand chain again and copying every earlier operand forprintf,setanddeclare. A command with many arguments therefore took quadratic time. Words only grow within a command, so the builtin lookup now resumes where it stopped, and each operand is read once into a few flags (dash option,[EFin]option,set -A,printf -v,print -v). The decisions are the same as before. Only the work per word changes.How did you verify your code works?
test/shell-scan/adversarial.test.ts(printf and set with 32000 operands, declare with 8000 options, 8000 chainedcommandwords). On dev they take 8290, 6893, 1401 and 1073 ms and fail the 500 ms budget. With the fix all pass.bun test test/shell-scan/(2861 pass), the shell-parse and tool-shell tests (272 pass), corebun run typecheck, oxlint and prettier on the touched files.Checklist
Added by the opencode bot (AI-generated).
Fixes #59165