diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-02 12:35:04 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-02 13:15:37 +0200 |
commit | 216913c290fd2b88b744c04c0a2ef21fd1410ba9 (patch) | |
tree | 906139aa9c6d05a091c55ab83d1bf547fe839f31 /shell/ash_test | |
parent | e84212f8346741a2d4a04b40639c44fe519cf5a7 (diff) | |
download | busybox-w32-216913c290fd2b88b744c04c0a2ef21fd1410ba9.tar.gz busybox-w32-216913c290fd2b88b744c04c0a2ef21fd1410ba9.tar.bz2 busybox-w32-216913c290fd2b88b744c04c0a2ef21fd1410ba9.zip |
ash: parser: Add syntax stack for recursive parsing
This closes 10821.
Upstream patch:
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 9 Mar 2018 00:14:02 +0800
parser: Add syntax stack for recursive parsing
Without a stack of syntaxes we cannot correctly these two cases
together:
"${a#'$$'}"
"${a#"${b-'$$'}"}"
A recursive parser also helps in some other corner cases such
as nested arithmetic expansion with paratheses.
This patch adds a syntax stack allocated from the stack using
alloca. As a side-effect this allows us to remove the naked
backslashes for patterns within double-quotes, which means that
EXP_QPAT also has to go.
This patch also fixes removes any backslashes that precede right
braces when they are present within a parameter expansion context,
and backslashes that precede double quotes within inner double
quotes inside a parameter expansion in a here-document context.
The idea of a recursive parser is based on a patch by Harald van
Dijk.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
var_bash3, var_bash4 and var_bash6 tests are updated
with the output given by bash-4.3.43
With this patch, the following tests now pass for ash:
dollar_repl_slash_bash2.tests
squote_in_varexp2.tests
squote_in_varexp.tests
var_bash4.tests
function old new delta
readtoken1 2615 2874 +259
synstack_push - 54 +54
evalvar 574 571 -3
rmescapes 330 310 -20
subevalvar 1279 1258 -21
argstr 1146 1107 -39
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/4 up/down: 313/-83) Total: 230 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash_test')
-rw-r--r-- | shell/ash_test/ash-arith/arith_nested1.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-arith/arith_nested1.tests | 1 | ||||
-rw-r--r-- | shell/ash_test/ash-quoting/squote_in_varexp3.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-quoting/squote_in_varexp3.tests | 1 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_bash3.right | 4 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_bash4.right | 16 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_bash6.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_bash6.tests | 2 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_bash7.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_bash7.tests | 1 |
10 files changed, 18 insertions, 12 deletions
diff --git a/shell/ash_test/ash-arith/arith_nested1.right b/shell/ash_test/ash-arith/arith_nested1.right new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/shell/ash_test/ash-arith/arith_nested1.right | |||
@@ -0,0 +1 @@ | |||
1 | |||
diff --git a/shell/ash_test/ash-arith/arith_nested1.tests b/shell/ash_test/ash-arith/arith_nested1.tests new file mode 100755 index 000000000..28571b833 --- /dev/null +++ b/shell/ash_test/ash-arith/arith_nested1.tests | |||
@@ -0,0 +1 @@ | |||
echo $(( ( $((1)) ) )) | |||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp3.right b/shell/ash_test/ash-quoting/squote_in_varexp3.right new file mode 100644 index 000000000..223b7836f --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp3.right | |||
@@ -0,0 +1 @@ | |||
B | |||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp3.tests b/shell/ash_test/ash-quoting/squote_in_varexp3.tests new file mode 100755 index 000000000..028a88fd9 --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp3.tests | |||
@@ -0,0 +1 @@ | |||
x=\'B; echo "${x#\'}" | |||
diff --git a/shell/ash_test/ash-vars/var_bash3.right b/shell/ash_test/ash-vars/var_bash3.right index a97c850ea..8899d981c 100644 --- a/shell/ash_test/ash-vars/var_bash3.right +++ b/shell/ash_test/ash-vars/var_bash3.right | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 a041#c | 1 | 1 a041#c |
2 | 2 a041#c | 2 | 2 a041#c |
3 | 3 a\041#c | 3 | 3 a041#c |
4 | 4 a\041#c | 4 | 4 a\041#c |
5 | 5 a\041#c | 5 | 5 a\041#c |
6 | 6 a\041#c | 6 | 6 a\041#c |
@@ -17,4 +17,4 @@ | |||
17 | 17 a\tc | 17 | 17 a\tc |
18 | 18 a\tc | 18 | 18 a\tc |
19 | 19 atc | 19 | 19 atc |
20 | 20 a\tc | 20 | 20 atc |
diff --git a/shell/ash_test/ash-vars/var_bash4.right b/shell/ash_test/ash-vars/var_bash4.right index 0ef1bf661..9067e58e6 100644 --- a/shell/ash_test/ash-vars/var_bash4.right +++ b/shell/ash_test/ash-vars/var_bash4.right | |||
@@ -3,26 +3,26 @@ Replace str: _\\_\z_ | |||
3 | Pattern: single backslash and star: "replace literal star" | 3 | Pattern: single backslash and star: "replace literal star" |
4 | Unquoted: a_\_z_b\*c | 4 | Unquoted: a_\_z_b\*c |
5 | Unquoted =: a_\_z_b\*c | 5 | Unquoted =: a_\_z_b\*c |
6 | Quoted: a_\_\z_b\*c | 6 | Quoted: a_\_z_b\*c |
7 | Quoted =: a_\_\z_b\*c | 7 | Quoted =: a_\_z_b\*c |
8 | Pattern: double backslash and star: "replace backslash and everything after it" | 8 | Pattern: double backslash and star: "replace backslash and everything after it" |
9 | Unquoted: a*b_\_z_ | 9 | Unquoted: a*b_\_z_ |
10 | Unquoted =: a*b_\_z_ | 10 | Unquoted =: a*b_\_z_ |
11 | Quoted: a*b_\_\z_ | 11 | Quoted: a*b_\_z_ |
12 | Quoted =: a*b_\_\z_ | 12 | Quoted =: a*b_\_z_ |
13 | 13 | ||
14 | Source: a\bc | 14 | Source: a\bc |
15 | Replace str: _\\_\z_ | 15 | Replace str: _\\_\z_ |
16 | Pattern: single backslash and b: "replace b" | 16 | Pattern: single backslash and b: "replace b" |
17 | Unquoted: a\_\_z_c | 17 | Unquoted: a\_\_z_c |
18 | Unquoted =: a\_\_z_c | 18 | Unquoted =: a\_\_z_c |
19 | Quoted: a\_\_\z_c | 19 | Quoted: a\_\_z_c |
20 | Quoted =: a\_\_\z_c | 20 | Quoted =: a\_\_z_c |
21 | Pattern: double backslash and b: "replace backslash and b" | 21 | Pattern: double backslash and b: "replace backslash and b" |
22 | Unquoted: a_\_z_c | 22 | Unquoted: a_\_z_c |
23 | Unquoted =: a_\_z_c | 23 | Unquoted =: a_\_z_c |
24 | Quoted: a_\_\z_c | 24 | Quoted: a_\_z_c |
25 | Quoted =: a_\_\z_c | 25 | Quoted =: a_\_z_c |
26 | 26 | ||
27 | Source: a\bc | 27 | Source: a\bc |
28 | Replace str: _\\_\z_ (as variable $s) | 28 | Replace str: _\\_\z_ (as variable $s) |
diff --git a/shell/ash_test/ash-vars/var_bash6.right b/shell/ash_test/ash-vars/var_bash6.right index 63fc23df8..115ff8b04 100644 --- a/shell/ash_test/ash-vars/var_bash6.right +++ b/shell/ash_test/ash-vars/var_bash6.right | |||
@@ -1,5 +1,5 @@ | |||
1 | Expected Actual | 1 | Expected Actual |
2 | a*z : a*z | 2 | a*z : a*z |
3 | \z : \z | 3 | z : z |
4 | a1z a2z: a1z a2z | 4 | a1z a2z: a1z a2z |
5 | z : z | 5 | z : z |
diff --git a/shell/ash_test/ash-vars/var_bash6.tests b/shell/ash_test/ash-vars/var_bash6.tests index cf2e4f020..686834177 100755 --- a/shell/ash_test/ash-vars/var_bash6.tests +++ b/shell/ash_test/ash-vars/var_bash6.tests | |||
@@ -3,7 +3,7 @@ | |||
3 | >a1z; >a2z; | 3 | >a1z; >a2z; |
4 | echo 'Expected' 'Actual' | 4 | echo 'Expected' 'Actual' |
5 | v='a bz'; echo 'a*z :' "${v/a*z/a*z}" | 5 | v='a bz'; echo 'a*z :' "${v/a*z/a*z}" |
6 | v='a bz'; echo '\z :' "${v/a*z/\z}" | 6 | v='a bz'; echo 'z :' "${v/a*z/\z}" |
7 | v='a bz'; echo 'a1z a2z:' ${v/a*z/a*z} | 7 | v='a bz'; echo 'a1z a2z:' ${v/a*z/a*z} |
8 | v='a bz'; echo 'z :' ${v/a*z/\z} | 8 | v='a bz'; echo 'z :' ${v/a*z/\z} |
9 | rm a1z a2z | 9 | rm a1z a2z |
diff --git a/shell/ash_test/ash-vars/var_bash7.right b/shell/ash_test/ash-vars/var_bash7.right new file mode 100644 index 000000000..223b7836f --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash7.right | |||
@@ -0,0 +1 @@ | |||
B | |||
diff --git a/shell/ash_test/ash-vars/var_bash7.tests b/shell/ash_test/ash-vars/var_bash7.tests new file mode 100755 index 000000000..c4ce03f7f --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash7.tests | |||
@@ -0,0 +1 @@ | |||
x=AB; echo "${x#$'\x41'}" | |||