ash: parser: Fix parameter expansion inside inner double quotes
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 2 Apr 2018 19:00:59 +0000 (21:00 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 2 Apr 2018 19:00:59 +0000 (21:00 +0200)
Upstream email:

    parser: Fix parameter expansion inside inner double quotes

    The parsing of parameter expansion inside inner double quotes
    breaks because we never look for ENDVAR while innerdq is true.

            echo "${x#"${x+''}"''}

    This patch fixes it by pushing the syntax stack if innerdq is
    true and we enter a new parameter expansion.

    This patch also fixes a corner case where a bad substitution error
    occurs within arithmetic expansion.

Reported-by: Denys Vlasenko <vda.linux@googlemail.com>
    Fixes: ab1cecb40478 (" parser: Add syntax stack for recursive...")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
function                                             old     new   delta
readtoken1                                          2880    2898     +18

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c
shell/ash_test/ash-quoting/quote_in_varexp1.right [new file with mode: 0644]
shell/ash_test/ash-quoting/quote_in_varexp1.tests [new file with mode: 0755]

index d82eba15f7b0018fc8aef52528c9ea10cbc30681..ed1a4416c20f2878baf9782db8aff5dcd99d049b 100644 (file)
@@ -12467,10 +12467,12 @@ parsesub: {
                        pungetc();
                }
 
-               if (newsyn == ARISYNTAX && subtype > VSNORMAL)
+               if (newsyn == ARISYNTAX)
                        newsyn = DQSYNTAX;
 
-               if (newsyn != synstack->syntax) {
+               if ((newsyn != synstack->syntax || synstack->innerdq)
+                && subtype != VSNORMAL
+               ) {
                        synstack_push(&synstack,
                                synstack->prev ?: alloca(sizeof(*synstack)),
                                newsyn);
diff --git a/shell/ash_test/ash-quoting/quote_in_varexp1.right b/shell/ash_test/ash-quoting/quote_in_varexp1.right
new file mode 100644 (file)
index 0000000..99a0aea
--- /dev/null
@@ -0,0 +1,2 @@
+''
+Ok:0
diff --git a/shell/ash_test/ash-quoting/quote_in_varexp1.tests b/shell/ash_test/ash-quoting/quote_in_varexp1.tests
new file mode 100755 (executable)
index 0000000..1b97b05
--- /dev/null
@@ -0,0 +1,2 @@
+x="''''"; echo "${x#"${x+''}"''}"
+echo Ok:$?