Backport the following from master:

   <9121510> ash: add test for issue with here document
   <6bd2fab> Revert "ash: fix a SEGV case in an invalid heredoc"
   <c0e0076> ash: simplify EOF/newline handling in list parser

Reported-by: Natanael Copa <[email protected]>
Signed-off-by: Ron Yorston <[email protected]>
---
 shell/ash.c                               | 72 +++++++++++++------------------
 shell/ash_test/ash-heredoc/heredoc2.right |  2 +
 shell/ash_test/ash-heredoc/heredoc2.tests |  7 +++
 3 files changed, 39 insertions(+), 42 deletions(-)
 create mode 100644 shell/ash_test/ash-heredoc/heredoc2.right
 create mode 100755 shell/ash_test/ash-heredoc/heredoc2.tests

diff --git a/shell/ash.c b/shell/ash.c
index 256e933..753eacf 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -10516,7 +10516,7 @@ static union node *andor(void);
 static union node *pipeline(void);
 static union node *parse_command(void);
 static void parseheredoc(void);
-static char nexttoken_ends_list(void);
+static int peektoken(void);
 static int readtoken(void);
 
 static union node *
@@ -10525,11 +10525,27 @@ list(int nlflag)
        union node *n1, *n2, *n3;
        int tok;
 
-       checkkwd = CHKNL | CHKKWD | CHKALIAS;
-       if (nlflag == 2 && nexttoken_ends_list())
-               return NULL;
        n1 = NULL;
        for (;;) {
+               switch (peektoken()) {
+               case TNL:
+                       if (!(nlflag & 1))
+                               break;
+                       parseheredoc();
+                       return n1;
+
+               case TEOF:
+                       if (!n1 && (nlflag & 1))
+                               n1 = NODE_EOF;
+                       parseheredoc();
+                       return n1;
+               }
+
+               checkkwd = CHKNL | CHKKWD | CHKALIAS;
+               if (nlflag == 2 && tokname_array[peektoken()][0])
+                       return n1;
+               nlflag |= 2;
+
                n2 = andor();
                tok = readtoken();
                if (tok == TBACKGND) {
@@ -10555,37 +10571,15 @@ list(int nlflag)
                        n1 = n3;
                }
                switch (tok) {
+               case TNL:
+               case TEOF:
+                       tokpushback = 1;
+                       /* fall through */
                case TBACKGND:
                case TSEMI:
-                       tok = readtoken();
-                       /* fall through */
-               case TNL:
-                       if (tok == TNL) {
-                               parseheredoc();
-                               if (nlflag == 1)
-                                       return n1;
-                       } else {
-                               tokpushback = 1;
-                       }
-                       checkkwd = CHKNL | CHKKWD | CHKALIAS;
-                       if (nexttoken_ends_list()) {
-                               /* Testcase: "<<EOF; then <W".
-                                * It used to segfault w/o this check:
-                                */
-                               if (heredoclist) {
-                                       raise_error_unexpected_syntax(-1);
-                               }
-                               return n1;
-                       }
                        break;
-               case TEOF:
-                       if (heredoclist)
-                               parseheredoc();
-                       else
-                               pungetc();              /* push back EOF on 
input */
-                       return n1;
                default:
-                       if (nlflag == 1)
+                       if ((nlflag & 1))
                                raise_error_unexpected_syntax(-1);
                        tokpushback = 1;
                        return n1;
@@ -11955,14 +11949,14 @@ readtoken(void)
        return t;
 }
 
-static char
-nexttoken_ends_list(void)
+static int
+peektoken(void)
 {
        int t;
 
        t = readtoken();
        tokpushback = 1;
-       return tokname_array[t][0];
+       return t;
 }
 
 /*
@@ -11972,18 +11966,12 @@ nexttoken_ends_list(void)
 static union node *
 parsecmd(int interact)
 {
-       int t;
-
        tokpushback = 0;
+       checkkwd = 0;
+       heredoclist = 0;
        doprompt = interact;
        setprompt_if(doprompt, doprompt);
        needprompt = 0;
-       t = readtoken();
-       if (t == TEOF)
-               return NODE_EOF;
-       if (t == TNL)
-               return NULL;
-       tokpushback = 1;
        return list(1);
 }
 
diff --git a/shell/ash_test/ash-heredoc/heredoc2.right 
b/shell/ash_test/ash-heredoc/heredoc2.right
new file mode 100644
index 0000000..a486f1a
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc2.right
@@ -0,0 +1,2 @@
+bar
+bar
diff --git a/shell/ash_test/ash-heredoc/heredoc2.tests 
b/shell/ash_test/ash-heredoc/heredoc2.tests
new file mode 100755
index 0000000..6d9ccb6
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc2.tests
@@ -0,0 +1,7 @@
+foo () {
+cat <<EOF && { echo "$1" ; }
+$1
+EOF
+}
+
+foo "bar"
-- 
2.5.0

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to