ash: parser: Save/restore here-documents in command substitution
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 17 Feb 2020 11:11:26 +0000 (12:11 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 17 Feb 2020 11:11:26 +0000 (12:11 +0100)
Upstream comment:

    Date: Sat, 19 May 2018 02:39:42 +0800
    parser: Save/restore here-documents in command substitution

    This patch changes the parsing of here-documents within command
    substitution, both old style and new style.  In particular, the
    original here-document list is saved upon the beginning of parsing
    command substitution and restored when exiting.

    This means that here-documents outside of command substitution
    can no longer be filled by text within it and vice-versa.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c

index fbe8dd9e4b98ea6874b770f2df7872a8ab3651ee..e0ddf7198032aa91f86d172cb278e6647f42bba4 100644 (file)
@@ -12733,6 +12733,7 @@ parsebackq: {
        union node *n;
        char *str;
        size_t savelen;
+       struct heredoc *saveheredoclist;
        smallint saveprompt = 0;
 
        str = NULL;
@@ -12808,6 +12809,9 @@ parsebackq: {
        *nlpp = stzalloc(sizeof(**nlpp));
        /* (*nlpp)->next = NULL; - stzalloc did it */
 
+       saveheredoclist = heredoclist;
+       heredoclist = NULL;
+
        if (oldstyle) {
                saveprompt = doprompt;
                doprompt = 0;
@@ -12817,18 +12821,21 @@ parsebackq: {
 
        if (oldstyle)
                doprompt = saveprompt;
-       else if (readtoken() != TRP)
-               raise_error_unexpected_syntax(TRP);
+       else {
+               if (readtoken() != TRP)
+                       raise_error_unexpected_syntax(TRP);
+               setinputstring(nullstr);
+               parseheredoc();
+       }
+
+       heredoclist = saveheredoclist;
 
        (*nlpp)->n = n;
-       if (oldstyle) {
-               /*
-                * Start reading from old file again, ignoring any pushed back
-                * tokens left from the backquote parsing
-                */
-               popfile();
+       /* Start reading from old file again. */
+       popfile();
+       /* Ignore any pushed back tokens left from the backquote parsing. */
+       if (oldstyle)
                tokpushback = 0;
-       }
        while (stackblocksize() <= savelen)
                growstackblock();
        STARTSTACKSTR(out);