Skip to content
Snippets Groups Projects
Commit 17db43b5 authored by Herbert Xu's avatar Herbert Xu
Browse files

input: Allow two consecutive calls to pungetc


The commit ef91d3d6 ([PARSER]
Handle backslash newlines properly after dollar sign) created
cases where we make two consecutive calls to pungetc.  As we
don't explicitly support that there are corner cases where you
end up with garbage input leading to undefined behaviour.

This patch adds explicit support for two consecutive calls to
pungetc.

Reported-by: default avatarJilles Tjoelker <jilles@stack.nl>
Reported-by: default avatarJuergen Daubert <jue@jue.li>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 51781428
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -102,10 +102,20 @@ RESET {
int
pgetc(void)
{
int c;
if (parsefile->unget)
return parsefile->lastc[--parsefile->unget];
if (--parsefile->nleft >= 0)
return (signed char)*parsefile->nextc++;
c = (signed char)*parsefile->nextc++;
else
return preadbuffer();
c = preadbuffer();
parsefile->lastc[1] = parsefile->lastc[0];
parsefile->lastc[0] = c;
return c;
}
 
 
Loading
Loading
@@ -194,7 +204,7 @@ static int preadbuffer(void)
#endif
char savec;
 
while (unlikely(parsefile->strpush)) {
if (unlikely(parsefile->strpush)) {
if (
parsefile->nleft == -1 &&
parsefile->strpush->ap &&
Loading
Loading
@@ -204,8 +214,7 @@ static int preadbuffer(void)
return PEOA;
}
popstring();
if (--parsefile->nleft >= 0)
return (signed char)*parsefile->nextc++;
return pgetc();
}
if (unlikely(parsefile->nleft == EOF_NLEFT ||
parsefile->buf == NULL))
Loading
Loading
@@ -290,15 +299,14 @@ again:
}
 
/*
* Undo the last call to pgetc. Only one character may be pushed back.
* Undo a call to pgetc. Only two characters may be pushed back.
* PEOF may be pushed back.
*/
 
void
pungetc(void)
{
parsefile->nleft++;
parsefile->nextc--;
parsefile->unget++;
}
 
/*
Loading
Loading
@@ -322,6 +330,8 @@ pushstring(char *s, void *ap)
sp = parsefile->strpush = &(parsefile->basestrpush);
sp->prevstring = parsefile->nextc;
sp->prevnleft = parsefile->nleft;
sp->unget = parsefile->unget;
memcpy(sp->lastc, parsefile->lastc, sizeof(sp->lastc));
sp->ap = (struct alias *)ap;
if (ap) {
((struct alias *)ap)->flag |= ALIASINUSE;
Loading
Loading
@@ -329,6 +339,7 @@ pushstring(char *s, void *ap)
}
parsefile->nextc = s;
parsefile->nleft = len;
parsefile->unget = 0;
INTON;
}
 
Loading
Loading
@@ -353,6 +364,8 @@ popstring(void)
}
parsefile->nextc = sp->prevstring;
parsefile->nleft = sp->prevnleft;
parsefile->unget = sp->unget;
memcpy(parsefile->lastc, sp->lastc, sizeof(sp->lastc));
/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
parsefile->strpush = sp->prev;
if (sp != &(parsefile->basestrpush))
Loading
Loading
@@ -439,6 +452,7 @@ pushfile(void)
pf->fd = -1;
pf->strpush = NULL;
pf->basestrpush.prev = NULL;
pf->unget = 0;
parsefile = pf;
}
 
Loading
Loading
Loading
Loading
@@ -49,6 +49,12 @@ struct strpush {
int prevnleft;
struct alias *ap; /* if push was associated with an alias */
char *string; /* remember the string since it may change */
/* Remember last two characters for pungetc. */
int lastc[2];
/* Number of outstanding calls to pungetc. */
int unget;
};
 
/*
Loading
Loading
@@ -66,6 +72,12 @@ struct parsefile {
char *buf; /* input buffer */
struct strpush *strpush; /* for pushing strings at this level */
struct strpush basestrpush; /* so pushing one is fast */
/* Remember last two characters for pungetc. */
int lastc[2];
/* Number of outstanding calls to pungetc. */
int unget;
};
 
extern struct parsefile *parsefile;
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment