Fix one-byte buffer overrun in contrib/test_parser.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Jan 2012 00:56:27 +0000 (19:56 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Jan 2012 00:56:27 +0000 (19:56 -0500)
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.

contrib/test_parser/test_parser.c

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