diff mbox series

input: Eat rest of line upon reset

Message ID Y7O9+cQuuAwo4HtG@gondor.apana.org.au (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show
Series input: Eat rest of line upon reset | expand

Commit Message

Herbert Xu Jan. 3, 2023, 5:32 a.m. UTC
On Tue, Jan 03, 2023 at 09:53:23AM +0800, Herbert Xu wrote:
>
> This is broken.  What if we already read a newline just before
> the syntax error (e.g., synexpect(TDO))?
> 
> This needs to be dealt with in the input layer.

This works for me:

---8<---
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.

Reported-by: наб <nabijaczleweli@nabijaczleweli.xyz> 
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff mbox series

Patch

diff --git a/src/input.c b/src/input.c
index dfe2fd6..e72eae7 100644
--- a/src/input.c
+++ b/src/input.c
@@ -77,6 +77,7 @@  INCLUDE <stdio.h>
 INCLUDE <unistd.h>
 INCLUDE "input.h"
 INCLUDE "error.h"
+INCLUDE "syntax.h"
 
 INIT {
 	basepf.nextc = basepf.buf = basebuf;
@@ -85,9 +86,11 @@  INIT {
 
 RESET {
 	/* clear input buffer */
-	basepf.lleft = basepf.nleft = 0;
-	basepf.unget = 0;
 	popallfiles();
+	basepf.unget = 0;
+	while (basepf.lastc[0] != '\n' &&
+	       basepf.lastc[0] != PEOF)
+		pgetc();
 }
 
 FORKRESET {