From 22ee26b925f0c93b3539efd2e195af74bdf34fac Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 29 Jul 2020 12:27:45 -0600 Subject: [PATCH] Cast to uschar when storing a char in an int that will be used as an index (#88) * Cast to uschar when storing a char in an int that will be used as an index. Fixes a heap underflow when the input char has the high bit set and FS is a regex. * Add regress test for underflow when RS is a regex and input is 8-bit. --- b.c | 2 +- bugs-fixed/rs_underflow.awk | 1 + bugs-fixed/rs_underflow.in | 1 + bugs-fixed/rs_underflow.ok | 1 + lex.c | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 bugs-fixed/rs_underflow.awk create mode 100644 bugs-fixed/rs_underflow.in create mode 100644 bugs-fixed/rs_underflow.ok diff --git a/b.c b/b.c index c167b50..a338d43 100644 --- a/b.c +++ b/b.c @@ -684,7 +684,7 @@ bool fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum) FATAL("stream '%.30s...' too long", buf); buf[k++] = (c = getc(f)) != EOF ? c : 0; } - c = buf[j]; + c = (uschar)buf[j]; /* assert(c < NCHARS); */ if ((ns = pfa->gototab[s][c]) != 0) diff --git a/bugs-fixed/rs_underflow.awk b/bugs-fixed/rs_underflow.awk new file mode 100644 index 0000000..4cf1702 --- /dev/null +++ b/bugs-fixed/rs_underflow.awk @@ -0,0 +1 @@ +BEGIN { RS="zx" } { print $1 } diff --git a/bugs-fixed/rs_underflow.in b/bugs-fixed/rs_underflow.in new file mode 100644 index 0000000..74c8035 --- /dev/null +++ b/bugs-fixed/rs_underflow.in @@ -0,0 +1 @@ +Ä diff --git a/bugs-fixed/rs_underflow.ok b/bugs-fixed/rs_underflow.ok new file mode 100644 index 0000000..74c8035 --- /dev/null +++ b/bugs-fixed/rs_underflow.ok @@ -0,0 +1 @@ +Ä diff --git a/lex.c b/lex.c index 0d2142c..2cd7672 100644 --- a/lex.c +++ b/lex.c @@ -148,7 +148,7 @@ static int gettok(char **pbuf, int *psz) /* get next input token */ strtod(buf, &rem); /* parse the number */ if (rem == buf) { /* it wasn't a valid number at all */ buf[1] = 0; /* return one character as token */ - retc = buf[0]; /* character is its own type */ + retc = (uschar)buf[0]; /* character is its own type */ unputstr(rem+1); /* put rest back for later */ } else { /* some prefix was a number */ unputstr(rem); /* put rest back for later */