[PATCH v2 2/3] parser: synerror: explicitly consume the entire invalid line

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Interactively, sh_error() doesn't terminate, so
  echo "|$(printf %10000s)echo bug" | sh -i
would read the first 8KiB, see that it's invalid, then jump back to the
parser, which would then read and execute the rest of the line as-if
it were the next line.

The fix for this is to explicitly consume the rest of the invalid line,
so that the next line observed is /actually/ the next line.

This is difficult to trigger accidentally right now, since we consume
the entire icanon line buffer at once (provided it's <8k, which it
~always is interactively), so we always observe one line at a time,
but the next patch would make even "| echo bug" blow up.

Imported-from: https://github.com/hvdijk/gwsh/commit/d279523041c1c380d64b6dec7760feba20bbf6b5
---
 src/parser.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/parser.c b/src/parser.c
index 8a06b9e..35fdbc3 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -761,6 +761,13 @@ static void nlnoprompt(void)
 	needprompt = doprompt;
 }
 
+static void
+skipline(void)
+{
+	int c;
+	while ((c = pgetc()) != '\n' && c != PEOF);
+}
+
 
 /*
  * Read the next input token.
@@ -798,7 +805,7 @@ xxreadtoken(void)
 		case ' ': case '\t':
 			continue;
 		case '#':
-			while ((c = pgetc()) != '\n' && c != PEOF);
+			skipline();
 			pungetc();
 			continue;
 		case '\n':
@@ -1526,6 +1533,12 @@ STATIC void
 synerror(const char *msg)
 {
 	errlinno = plinno;
+
+	/* If we see a syntax error in a command, read the rest of the
+	 * line now before reporting the error. This ensures we get error
+	 * reporting that does not depend on buffering details. */
+	skipline();
+
 	sh_error("Syntax error: %s", msg);
 	/* NOTREACHED */
 }
-- 
2.30.2

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux