99 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
1010 * Portions Copyright (c) 1994, Regents of the University of California
1111 *
12- * $PostgreSQL: pgsql/src/backend/lib/stringinfo.c,v 1.37 2003/11/29 22:39:42 pgsql Exp $
12+ * $PostgreSQL: pgsql/src/backend/lib/stringinfo.c,v 1.38 2004/05/11 20:07:26 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
1616#include "postgres.h"
1717
1818#include "lib/stringinfo.h"
19+ #include "utils/memutils.h"
1920
2021
2122/*
@@ -220,7 +221,20 @@ enlargeStringInfo(StringInfo str, int needed)
220221{
221222int newlen ;
222223
224+ /*
225+ * Guard against ridiculous "needed" values, which can occur if we're
226+ * fed bogus data. Without this, we can get an overflow or infinite
227+ * loop in the following.
228+ */
229+ if (needed < 0 ||
230+ ((Size )needed ) >= (MaxAllocSize - (Size )str -> len ))
231+ elog (ERROR ,"invalid string enlargement request size %d" ,
232+ needed );
233+
223234needed += str -> len + 1 ;/* total space required now */
235+
236+ /* Because of the above test, we now have needed <= MaxAllocSize */
237+
224238if (needed <=str -> maxlen )
225239return ;/* got enough space already */
226240
@@ -234,6 +248,14 @@ enlargeStringInfo(StringInfo str, int needed)
234248while (needed > newlen )
235249newlen = 2 * newlen ;
236250
251+ /*
252+ * Clamp to MaxAllocSize in case we went past it. Note we are assuming
253+ * here that MaxAllocSize <= INT_MAX/2, else the above loop could
254+ * overflow. We will still have newlen >= needed.
255+ */
256+ if (newlen > (int )MaxAllocSize )
257+ newlen = (int )MaxAllocSize ;
258+
237259str -> data = (char * )repalloc (str -> data ,newlen );
238260
239261str -> maxlen = newlen ;