aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-05-14 00:20:51 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-05-14 00:20:51 +0000
commitfedfc5d363eb54fa5f25be883a1e54d4a28ea35d (patch)
tree221b54ad26f6fca4ae925f2c9c4f0f90b8505751
parent65924e6cc6048667a6d1c0ddf33cce76881b226b (diff)
downloadpostgresql-fedfc5d363eb54fa5f25be883a1e54d4a28ea35d.tar.gz
postgresql-fedfc5d363eb54fa5f25be883a1e54d4a28ea35d.zip
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.
-rw-r--r--src/interfaces/libpq/pqexpbuffer.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/interfaces/libpq/pqexpbuffer.c b/src/interfaces/libpq/pqexpbuffer.c
index 195f6cfd6b9..27b99a279ba 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
*
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.15 2003/08/04 02:40:20 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.15.4.1 2004/05/14 00:20:51 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)
{