[PATCH] input: Eat rest of line upon reset

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

 



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@xxxxxxxxxxxxxxxxxx> 
Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>

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 {
-- 
Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt



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

  Powered by Linux