[PATCH 2/2 1.24] ash: backport fix for here document issues
Ron Yorston
rmy at pobox.com
Fri Mar 18 11:32:37 UTC 2016
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 <ncopa at alpinelinux.org>
Signed-off-by: Ron Yorston <rmy at pobox.com>
---
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
More information about the busybox
mailing list