Fix one-byte buffer overrun in contrib/test_parser.

The original coding examined the next character before verifying that
there *is* a next character.  In the worst case with the input buffer
right up against the end of memory, this would result in a segfault.

Problem spotted by Paul Guyot; this commit extends his patch to fix an
additional case.  In addition, make the code a tad more readable by not
overloading the usage of *tlen.
This commit is contained in:
Tom Lane 2012-01-09 19:56:27 -05:00
parent 743ed082ac
commit 89b3c6cc8b
1 changed files with 10 additions and 9 deletions

View File

@ -73,31 +73,32 @@ testprs_getlexeme(PG_FUNCTION_ARGS)
ParserState *pst = (ParserState *) PG_GETARG_POINTER(0); ParserState *pst = (ParserState *) PG_GETARG_POINTER(0);
char **t = (char **) PG_GETARG_POINTER(1); char **t = (char **) PG_GETARG_POINTER(1);
int *tlen = (int *) PG_GETARG_POINTER(2); int *tlen = (int *) PG_GETARG_POINTER(2);
int startpos = pst->pos;
int type; int type;
*tlen = pst->pos;
*t = pst->buffer + pst->pos; *t = pst->buffer + pst->pos;
if ((pst->buffer)[pst->pos] == ' ') if (pst->pos < pst->len &&
(pst->buffer)[pst->pos] == ' ')
{ {
/* blank type */ /* blank type */
type = 12; type = 12;
/* go to the next non-white-space character */ /* go to the next non-space character */
while ((pst->buffer)[pst->pos] == ' ' && while (pst->pos < pst->len &&
pst->pos < pst->len) (pst->buffer)[pst->pos] == ' ')
(pst->pos)++; (pst->pos)++;
} }
else else
{ {
/* word type */ /* word type */
type = 3; type = 3;
/* go to the next white-space character */ /* go to the next space character */
while ((pst->buffer)[pst->pos] != ' ' && while (pst->pos < pst->len &&
pst->pos < pst->len) (pst->buffer)[pst->pos] != ' ')
(pst->pos)++; (pst->pos)++;
} }
*tlen = pst->pos - *tlen; *tlen = pst->pos - startpos;
/* we are finished if (*tlen == 0) */ /* we are finished if (*tlen == 0) */
if (*tlen == 0) if (*tlen == 0)