You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(lexer): the permission lexer is blind to # comments — an apostrophe in a comment masks a later $(...) and collapses segment splitting #4029
The permission-path lexer tracks quote state straight through # comment text. An unbalanced apostrophe inside a comment — # it's fine, # don't, # we're done — opens a single-quote state that never closes, which masks everything after it from contains_unattestable_construct and collapses split_compound_command into a single segment.
Consequence: a command whose first segment matches an allow rule can carry an arbitrary trailing statement, including a live $(...), and the whole thing reads as one allowed segment.
This is latent on develop today, because develop declines to rewrite these blocks and so asserts nothing — the host does its own check. It is not latent for any change that widens rewrite coverage. PR #2781 is the demonstration: with its bundle rewriting, the same input produces permissionDecision: "allow".
Mechanism
src/discover/lexer.rs toggles in_single / in_double / in_backtick on every quote byte it sees, with no notion that a # at a word boundary starts a comment that runs to end of line. contains_unattestable_construct and split_compound_command both inherit that.
Reproduction
Build develop (d0c29851) and a rewriter that acts on multi-line blocks (e.g. the #2781 head, 2c89559a), with only Bash(ls:*) and Bash(cat:*) allowed:
Removing only the apostrophe (# fine) drops the allow, which isolates quote-state masking as the mechanism. A backtick substitution (curl \echo http://x\``) reaches the same end.
Suggested direction
Make the comment rule explicit in the shared quote/escape state machine: a # that is at the start of input or preceded by whitespace, and is not inside a quote, starts a comment that runs to the next newline; no byte inside it updates quote state, and it is never a segment or operator boundary.
That is one change in the shared lexer, and it also closes the statement-loss class in #2781 (a comment ending in &/| being read as a line continuation).
Permission lexer's quote-state tracking ignores # comments, so an unbalanced apostrophe inside a comment can mask a trailing $(...)/backtick substitution and collapse compound-command segment splitting into one allowed segment; fix by making #-to-EOL comment recognition explicit in the shared lexer state machine.
📁 Relevant files
src/discover/lexer.rs
Triaged automatically by wshm · This is an automated analysis, not a human review.
Activity
rtk-wshm-sync-bot commentedon Sep 13, 2026
🔍 Automated Triage
bughighSummary
Permission lexer's quote-state tracking ignores
#comments, so an unbalanced apostrophe inside a comment can mask a trailing$(...)/backtick substitution and collapse compound-command segment splitting into one allowed segment; fix by making#-to-EOL comment recognition explicit in the shared lexer state machine.📁 Relevant files
src/discover/lexer.rsTriaged automatically by wshm · This is an automated analysis, not a human review.