From e3fce282b5d507b8105c26543b079bc279da4000 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 9 Jan 2012 19:56:27 -0500
Subject: [PATCH] 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.
---
 contrib/test_parser/test_parser.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/contrib/test_parser/test_parser.c b/contrib/test_parser/test_parser.c
index da4f9be781..ac06abbcc9 100644
--- a/contrib/test_parser/test_parser.c
+++ b/contrib/test_parser/test_parser.c
@@ -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)
-- 
2.40.0