diff mbox series

input: Fix pungetc on PEOF

Message ID ZmVlYHu-Vs_srGX-@gondor.apana.org.au (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show
Series input: Fix pungetc on PEOF | expand

Commit Message

Herbert Xu June 9, 2024, 8:18 a.m. UTC
Calling pungetc upon PEOF must cause the next pgetc call to return
PEOF.  This was broken by the multi-byte pungetc patch.  Fix it by
adding the EOF logic to pgetc.

Note that pungetn will always disregard the PEOF.

Fixes: 2c92409145d0 ("input: Allow MB_LEN_MAX calls to pungetc")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
 src/input.c | 32 ++++++++++++++------------------
 src/input.h |  8 +++++---
 2 files changed, 19 insertions(+), 21 deletions(-)
diff mbox series

Patch

diff --git a/src/input.c b/src/input.c
index 8f8c173..6388b83 100644
--- a/src/input.c
+++ b/src/input.c
@@ -224,15 +224,13 @@  static int __pgetc(void)
 	if (parsefile->unget) {
 		long unget = -(long)(unsigned)parsefile->unget--;
 
-		if (parsefile->nleft < 0)
-			return preadbuffer();
-
 		return parsefile->nextc[unget];
 	}
 
-	if (--parsefile->nleft >= 0)
+	if (parsefile->nleft > 0) {
+		parsefile->nleft--;
 		c = (signed char)*parsefile->nextc++;
-	else
+	} else
 		c = preadbuffer();
 
 	return c;
@@ -372,8 +370,11 @@  static int preadbuffer(void)
 		popstring();
 		return __pgetc();
 	}
-	if (parsefile->buf == NULL)
+	if (parsefile->eof & 2) {
+eof:
+		parsefile->eof = 3;
 		return PEOF;
+	}
 	flushall();
 
 	q = parsefile->nextc;
@@ -394,7 +395,7 @@  again:
 			if (!IS_DEFINED_SMALL && nr > 0)
 				goto save;
 			INTON;
-			return PEOF;
+			goto eof;
 		}
 	}
 
@@ -477,7 +478,8 @@  void pungetn(int n)
 void
 pungetc(void)
 {
-	pungetn(1);
+	pungetn(1 - (parsefile->eof & 1));
+	parsefile->eof &= ~1;
 }
 
 /*
@@ -575,8 +577,6 @@  setinputfd(int fd, int push)
 		toppf = parsefile;
 	parsefile->fd = fd;
 	parsefile->nextc = parsefile->buf = ckmalloc(IBUFSIZ);
-	input_set_lleft(parsefile, parsefile->nleft = 0);
-	plinno = 1;
 }
 
 
@@ -591,8 +591,7 @@  setinputstring(char *string)
 	pushfile();
 	parsefile->nextc = string;
 	parsefile->nleft = strlen(string);
-	parsefile->buf = NULL;
-	plinno = 1;
+	parsefile->eof = 2;
 	INTON;
 }
 
@@ -609,12 +608,10 @@  pushfile(void)
 	struct parsefile *pf;
 
 	pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
+	memset(pf, 0, sizeof(*pf));
 	pf->prev = parsefile;
+	pf->linno = 1;
 	pf->fd = -1;
-	pf->strpush = NULL;
-	pf->spfree = NULL;
-	pf->basestrpush.prev = NULL;
-	pf->unget = 0;
 	parsefile = pf;
 }
 
@@ -639,8 +636,7 @@  popfile(void)
 
 	if (pf->fd >= 0)
 		close(pf->fd);
-	if (pf->buf)
-		ckfree(pf->buf);
+	ckfree(pf->buf);
 	if (parsefile->spfree)
 		freestrings(parsefile->spfree);
 	while (pf->strpush) {
diff --git a/src/input.h b/src/input.h
index af1c1be..706ac73 100644
--- a/src/input.h
+++ b/src/input.h
@@ -79,9 +79,7 @@  struct parsefile {
 	int linno;		/* current line */
 	int fd;			/* file descriptor (or -1 if string) */
 	int nleft;		/* number of chars left in this line */
-#ifndef SMALL
-	int lleft;		/* number of chars left in this buffer */
-#endif
+	int eof;		/* do not read again once we hit EOF */
 	char *nextc;		/* next char in buffer */
 	char *buf;		/* input buffer */
 	struct strpush *strpush; /* for pushing strings at this level */
@@ -90,6 +88,10 @@  struct parsefile {
 	/* Delay freeing so we can stop nested aliases. */
 	struct strpush *spfree;
 
+#ifndef SMALL
+	int lleft;		/* number of chars left in this buffer */
+#endif
+
 	/* Number of outstanding calls to pungetc. */
 	int unget;
 };