From 02409a48137f1f63e8738be0c7f772e8dbdfd8b6 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 14 May 2004 00:20:38 +0000
Subject: [PATCH] Propagate enlargeStringInfo() fixes into the equivalent code
 in pqexpbuffer.c.  While a client-side failure doesn't seem like a security
 issue, it's still a bug.

---
 src/interfaces/libpq/pqexpbuffer.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/interfaces/libpq/pqexpbuffer.c b/src/interfaces/libpq/pqexpbuffer.c
index 0396f7a6b37..6aef4cf94de 100644
--- a/src/interfaces/libpq/pqexpbuffer.c
+++ b/src/interfaces/libpq/pqexpbuffer.c
@@ -17,13 +17,15 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.16 2003/11/29 19:52:12 pgsql Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.17 2004/05/14 00:20:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres_fe.h"
 
+#include <limits.h>
+
 #include "pqexpbuffer.h"
 
 #ifdef WIN32
@@ -132,7 +134,18 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
 	size_t		newlen;
 	char	   *newdata;
 
+	/*
+	 * Guard against ridiculous "needed" values, which can occur if we're
+	 * fed bogus data.  Without this, we can get an overflow or infinite
+	 * loop in the following.
+	 */
+	if (needed >= ((size_t) INT_MAX - str->len))
+		return 0;
+
 	needed += str->len + 1;		/* total space required now */
+
+	/* Because of the above test, we now have needed <= INT_MAX */
+
 	if (needed <= str->maxlen)
 		return 1;				/* got enough space already */
 
@@ -146,6 +159,14 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
 	while (needed > newlen)
 		newlen = 2 * newlen;
 
+	/*
+	 * Clamp to INT_MAX in case we went past it.  Note we are assuming
+	 * here that INT_MAX <= UINT_MAX/2, else the above loop could
+	 * overflow.  We will still have newlen >= needed.
+	 */
+	if (newlen > (size_t) INT_MAX)
+		newlen = (size_t) INT_MAX;
+
 	newdata = (char *) realloc(str->data, newlen);
 	if (newdata != NULL)
 	{
-- 
GitLab