ash: parser: Do not push token back before parseheredoc
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 22 Feb 2020 16:26:23 +0000 (17:26 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 22 Feb 2020 16:26:23 +0000 (17:26 +0100)
Upstream commit:

    Date: Mon, 19 Nov 2018 18:43:58 +0800
    parser: Do not push token back before parseheredoc

    When we read the first token in list() we use peektoken instead
    of readtoken as the following code needs to use the same token
    again.  However, this is wrong when we're in a here-document as
    it will clobber the saved token without resetting the tokpushback
    flag.

    This patch fixes it by doing the tokpushback after parseheredoc
    and setting lasttoken again if parseheredoc was called.

Reported-by: Ron Yorston <rmy@frippery.org>
    Fixes: 7c245aa8ed33 ("[PARSER] Simplify EOF/newline handling in...")
    Fixes: ee5cbe9fd6bc ("[SHELL] Optimize dash -c "command" to avoid a fork")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Tested-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c

index 83cac3fb0a5eb315bacc52a6930829a717a298ba..5fb67c0fa18f316f23ec8643b24e328a05b9c3dc 100644 (file)
@@ -11607,7 +11607,7 @@ list(int nlflag)
 
        n1 = NULL;
        for (;;) {
 
        n1 = NULL;
        for (;;) {
-               switch (peektoken()) {
+               switch (readtoken()) {
                case TNL:
                        if (!(nlflag & 1))
                                break;
                case TNL:
                        if (!(nlflag & 1))
                                break;
@@ -11618,9 +11618,12 @@ list(int nlflag)
                        if (!n1 && (nlflag & 1))
                                n1 = NODE_EOF;
                        parseheredoc();
                        if (!n1 && (nlflag & 1))
                                n1 = NODE_EOF;
                        parseheredoc();
+                       tokpushback++;
+                       lasttoken = TEOF;
                        return n1;
                }
 
                        return n1;
                }
 
+               tokpushback++;
                checkkwd = CHKNL | CHKKWD | CHKALIAS;
                if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
                        return n1;
                checkkwd = CHKNL | CHKKWD | CHKALIAS;
                if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
                        return n1;