Repository navigation
Commit 210adf1
authored
Fix Bash parsing that hides commands: continuations, CR, and word # (#243)
* Remove Bash line continuations before reading an expansion
Bash removes a backslash-newline pair before it splits tokens, except in
single quotes, $'...', a comment, and a heredoc body. The lexer read
"$\<newline>(cmd)" as literal text, so cmd ran with no occurrence.
Every lookahead that reads the second character of a multi-character
construct now skips line continuations through one helper
(BashLineContinuation): $, $(, ${, $name, $', operators, here-doc
operators, and descriptor targets. Later readers of authored text
(redirect operators, word-expansion facts, command words, option
spelling) use the same rule. A split $(( marker, a continuation in an
expanding heredoc body or delimiter, and $'...' with a continuation fail
closed.
* Add tests that kill the surviving continuation mutants
* Pin the substitution scan with a quoted inner substitution
* Remove a dead arithmetic-marker guard that a mutant exposed
* Prepare ShellSyntaxTree 0.4.0-beta.22
* Fail closed on a carriage return in Bash code
Bash reads CR as a word character and backslash + CR as an escaped CR.
The lexer read CR as a line end and backslash + CRLF as a continuation,
so 'echo a\<CR><LF>touch x' and 'echo a<CR># ; touch x' hid 'touch'.
A CR outside quotes, comments, and heredoc bodies now makes the source
unparseable, and so does backslash + CR in double quotes. Comments end
only at LF, and a heredoc line with a trailing CR is not its delimiter.
* Take a Bash inline option value from the decoded word
The value argument of '--name=value' came from the authored text after
'=' or, with an escape, from the whole word. 'curl --data=@p\.json' gave
'--data=@p.json' and 'curl --data=\a""' gave '--data=a'. The value is now
the part of the decoded word (or of each proved value) after the option
and its '='. Anything else is Unknown.
* Pin a CR comment in a substitution and computed inline values
* Document the carriage-return and inline-value changes
* Record the beta.22 comparison numbers
* Use LF in a multi-line Bash test source on every platform
* Fix the #243 review: word '#', reserved words, assignment tildes
- A '#' starts a comment only when it begins a new word. After a quoted
part, $(...), or $((...)) it is word text, as in Bash, so
'echo "a"# ; touch x' shows 'touch'.
- Reserved words, keywords, and literal checks read the spelling without
line continuations, so 't\<LF>ime touch x' fails closed like 'time'.
- In an assignment-shaped word (name= or name+=), a '~' after the first
'=' or after ':' expands from HOME, as Bash does outside POSIX mode.
'~user', '~+', and a word whose start is not visible give Unknown. A
here-string keeps the text.
* Add bash-verified tests for the #243 review findings
Includes a generated check: a '#' at every point of 13 seeds must match
the commands that Bash runs (logged, nothing real runs) or fail closed.
The Bash oracle helpers move to a shared BashOracle test class.
* Pin the tilde state after an escape, an expansion, or a continuation
* Pin a continuation before an unprovable assignment tilde
* Read (( and ;; across a line continuation
The ((...)) gate and the ;; case terminator compared raw offsets, so
'(\<LF>(ls))' parsed as two subshells that run 'ls'. Bash removes the
continuation and reads an arithmetic command, which fails closed here.
Found by checking that no continuation variant of an unparseable
source parses.
* Document the #243 review fixes
* Record the final beta.22 comparison numbers
* Expand an assignment-word tilde only in proved non-POSIX Bash
Round 2 of the #243 review. A '~' after '=' or ':' of an
assignment-shaped word now expands only in the submitted source (not a
decoded sh -c or bash -c child), in FreshNonInteractiveNoStartup mode,
with a launch-proved HOME. Everywhere else the value is Unknown. POSIX
mode and dash keep the text, and the other modes can inherit POSIX mode.
A subscripted name (a[0]=~/x) gives Unknown. A real assignment keeps its
leading tilde in every mode.
* Document the assignment-word tilde gate
* Record the round-2 comparison numbers1 parent d197ba3 commit 210adf1
29 files changed
Lines changed: 2769 additions & 364 deletions
File tree
- src/ShellSyntaxTree
- Internal
- Bash
- Lexing
- Parsing
- Parsing
- Resolving
- tests/ShellSyntaxTree.Tests
- Corpus/bash
- Lexing
- Parsing
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
14 | 24 | | |
15 | 25 | | |
16 | 26 | | |
17 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
18 | 30 | | |
19 | 31 | | |
20 | 32 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
1 | 35 | | |
2 | 36 | | |
3 | 37 | | |
| |||
0 commit comments