Skip to content

fix: parse command-position assignments correctly#1427

Merged
afadesigns merged 2 commits into
mainfrom
fix/command-position-assignment
Jun 25, 2026
Merged

fix: parse command-position assignments correctly#1427
afadesigns merged 2 commits into
mainfrom
fix/command-position-assignment

Conversation

@afadesigns

Copy link
Copy Markdown
Owner

What: a name=value after && / || or in a pipeline is now parsed as an assignment, not a command.

Why: the single-command parser captured it as a command whose name was the variable, with =value as an argument. A variable named for a builtin was mis-flagged as that builtin -- [[ cond ]] && test=$(x) drew the test-command katas, timeout=-t$2 drew the timeout kata, seq=$mac drew the seq katas. Assignment katas also missed these, so a real fpath=($fpath $dir) append after && went unreported.

How: reshapeCommandAssignment converts the fully-parsed command node into an = InfixExpression when it is a lone glued =value argument. It runs after the command is parsed, so it never changes token consumption -- the caller's cursor is untouched, which is what makes it safe where an early re-parse desynced the dispatch loop. The env-prefixed form (FOO=bar cmd) and the spaced form (cd =$x) stay commands.

Corpus effect: 10 false positives removed across 8 lines (variables named test/seq/timeout/GEOMETRY_PROMPT assigned in a logical chain); one real array append now reported. Parser-error sweep stays 402/0; fix-corpus and full suite green.

Tests: TestParseCommandPositionAssignment (parser), TestCommandPositionAssignmentNotMisflagged and TestCommandPositionAssignmentKeepsRealCommands (katas).

Severity: false positives removed, one false negative closed.

A `name=value` after `&&` / `||` or in a pipeline is an assignment,
but the single-command parser captured it as a command whose name was
the variable, with `=value` as an argument. A variable named for a
builtin was then mis-flagged as that builtin: `[[ cond ]] && test=$(x)`
drew the test-command katas, `timeout=-t$2` drew the timeout kata, and
`seq=$mac` drew the seq katas. Assignment katas also missed these, so a
real `fpath=($fpath $dir)` append after `&&` went unreported.

reshapeCommandAssignment converts the fully-parsed command node into an
`=` InfixExpression when it is a lone glued `=value` argument. It runs
after the command is parsed, so it never changes token consumption --
the caller's cursor is untouched, which is what makes it safe where an
early re-parse desynced the dispatch loop. The env-prefixed form
(`FOO=bar cmd`) and the spaced form (`cd =$x`) stay commands.

Corpus effect: 10 false positives removed across 8 lines (variables
named test/seq/timeout/GEOMETRY_PROMPT assigned in a logical chain);
one real array append now reported. Parser-error sweep stays 402/0.

Signed-off-by: afadesigns <afadesign.official@gmail.com>
@github-actions github-actions Bot added ci CI/CD and workflow changes test Adding or correcting tests area/parser pkg/lexer + pkg/parser + pkg/ast area/katas pkg/katas — detection logic labels Jun 25, 2026
redteamx
redteamx previously approved these changes Jun 25, 2026

@redteamx redteamx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on review.

A fuzzed input can leave a nil expression in a concatenated argument's
part slice. reshapeCommandAssignment dereferenced `Parts[1]` for a token
when building a multi-part assignment RHS, panicking on such input.

Use the concatenation's own token for position and bail out of the
reshape entirely when any part is nil, so a malformed command stays the
SimpleCommand it parsed as. Seed the parser fuzzer with command-position
assignment forms, including a truncated one.

Signed-off-by: afadesigns <afadesign.official@gmail.com>

@redteamx redteamx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on review.

@afadesigns afadesigns merged commit c961834 into main Jun 25, 2026
19 checks passed
@afadesigns afadesigns deleted the fix/command-position-assignment branch June 25, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/katas pkg/katas — detection logic area/parser pkg/lexer + pkg/parser + pkg/ast ci CI/CD and workflow changes test Adding or correcting tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants