aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorGravatar Ron Yorston <rmy@pobox.com>2015-10-29 11:30:55 +0000
committerGravatar Mike Frysinger <vapier@gentoo.org>2016-03-22 18:21:45 -0400
commitc1565a04f2d422f24b3331d57ceb384c7dc2933e (patch)
tree9b568a3d57fc4f834072a06fb38420a6ba862556 /shell
parentacad7392ee734ec286f0ae2b2e4550b5b4f49c10 (diff)
downloadbusybox-c1565a04f2d422f24b3331d57ceb384c7dc2933e.tar.gz
busybox-c1565a04f2d422f24b3331d57ceb384c7dc2933e.tar.bz2
ash: simplify EOF/newline handling in list parser
Processing of here documents in ash has had a couple of breakages which are now the subject of tests. This commit should fix both. It is based on the following commit in dash git by Herbert Xu: <7c245aa> [PARSER] Simplify EOF/newline handling in list parser (See git://git.kernel.org/pub/scm/utils/dash/dash.git) Reported-by: Natanael Copa <ncopa@alpinelinux.org> Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org> (cherry picked from commit c0e007663d30f83b0e5e074db34dcffaa8915e99)
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c63
1 files changed, 29 insertions, 34 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 48b7c4f3f..13ce99ed6 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -10518,7 +10518,7 @@ static union node *andor(void);
static union node *pipeline(void);
static union node *parse_command(void);
static void parseheredoc(void);
-static char peektoken(void);
+static int peektoken(void);
static int readtoken(void);
static union node *
@@ -10527,11 +10527,27 @@ list(int nlflag)
union node *n1, *n2, *n3;
int tok;
- checkkwd = CHKNL | CHKKWD | CHKALIAS;
- if (nlflag == 2 && peektoken())
- 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) {
@@ -10557,30 +10573,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 (peektoken())
- 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;
@@ -11950,14 +11951,14 @@ readtoken(void)
return t;
}
-static char
+static int
peektoken(void)
{
int t;
t = readtoken();
tokpushback = 1;
- return tokname_array[t][0];
+ return t;
}
/*
@@ -11967,18 +11968,12 @@ peektoken(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);
}