[git commit branch/1_24_stable] ash: simplify EOF/newline handling in list parser

Mike Frysinger vapier at gentoo.org
Tue Mar 22 22:21:45 UTC 2016


commit: https://git.busybox.net/busybox/commit/?id=c1565a04f2d422f24b3331d57ceb384c7dc2933e
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/1_24_stable

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 at alpinelinux.org>
Signed-off-by: Ron Yorston <rmy at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
Signed-off-by: Mike Frysinger <vapier at gentoo.org>
(cherry picked from commit c0e007663d30f83b0e5e074db34dcffaa8915e99)
---
 shell/ash.c | 63 ++++++++++++++++++++++++++++---------------------------------
 1 file changed, 29 insertions(+), 34 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index 48b7c4f..13ce99e 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);
 }
 


More information about the busybox-cvs mailing list