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
