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.
This commit is contained in:
Tom Lane 2004-05-14 00:20:38 +00:00
parent 0ec80be435
commit 02409a4813

View File

@ -17,13 +17,15 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 "postgres_fe.h"
#include <limits.h>
#include "pqexpbuffer.h" #include "pqexpbuffer.h"
#ifdef WIN32 #ifdef WIN32
@ -132,7 +134,18 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
size_t newlen; size_t newlen;
char *newdata; 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 */ needed += str->len + 1; /* total space required now */
/* Because of the above test, we now have needed <= INT_MAX */
if (needed <= str->maxlen) if (needed <= str->maxlen)
return 1; /* got enough space already */ return 1; /* got enough space already */
@ -146,6 +159,14 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
while (needed > newlen) while (needed > newlen)
newlen = 2 * 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); newdata = (char *) realloc(str->data, newlen);
if (newdata != NULL) if (newdata != NULL)
{ {