]> granicus.if.org Git - postgresql/blobdiff - src/interfaces/libpq/pqexpbuffer.c
Fix typo in comment.
[postgresql] / src / interfaces / libpq / pqexpbuffer.c
index b510eab2be03d51c2231e0d05e4c4d6b8ee62d01..09f064ffb0a8381b10916f5bf7f70784c5622e79 100644 (file)
  * a usable vsnprintf(), then a copy of our own implementation of it will
  * be linked into libpq.
  *
- * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.8 2001/01/24 19:43:31 momjian Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.22 2006/03/05 15:59:10 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 
-#include "postgres.h"
+#include "postgres_fe.h"
+
+#include <limits.h>
+
 #include "pqexpbuffer.h"
 
 #ifdef WIN32
-#include <stdarg.h>
-#include <stdio.h>
 #include "win32.h"
 #endif
 
@@ -71,8 +72,9 @@ initPQExpBuffer(PQExpBuffer str)
        }
 }
 
-/*------------------------
+/*
  * destroyPQExpBuffer(str);
+ *
  *             free()s both the data buffer and the PQExpBufferData.
  *             This is the inverse of createPQExpBuffer().
  */
@@ -86,7 +88,7 @@ destroyPQExpBuffer(PQExpBuffer str)
        }
 }
 
-/*------------------------
+/*
  * termPQExpBuffer(str)
  *             free()s the data buffer but not the PQExpBufferData itself.
  *             This is the inverse of initPQExpBuffer().
@@ -104,7 +106,7 @@ termPQExpBuffer(PQExpBuffer str)
        str->len = 0;
 }
 
-/*------------------------
+/*
  * resetPQExpBuffer
  *             Reset a PQExpBuffer to empty
  */
@@ -119,7 +121,7 @@ resetPQExpBuffer(PQExpBuffer str)
        }
 }
 
-/*------------------------
+/*
  * enlargePQExpBuffer
  * Make sure there is enough space for 'needed' more bytes in the buffer
  * ('needed' does not include the terminating null).
@@ -132,20 +134,38 @@ 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 */
 
        /*
-        * We don't want to allocate just a little more space with each
-        * append; for efficiency, double the buffer size each time it
-        * overflows. Actually, we might need to more than double it if
-        * 'needed' is big...
+        * We don't want to allocate just a little more space with each append;
+        * for efficiency, double the buffer size each time it overflows.
+        * Actually, we might need to more than double it if 'needed' is big...
         */
        newlen = (str->maxlen > 0) ? (2 * str->maxlen) : 64;
        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)
        {
@@ -156,7 +176,7 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
        return 0;
 }
 
-/*------------------------
+/*
  * printfPQExpBuffer
  * Format text data under the control of fmt (an sprintf-like format string)
  * and insert it into str.     More space is allocated to str if necessary.
@@ -174,11 +194,10 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
 
        for (;;)
        {
-               /*----------
-                * Try to format the given string into the available space;
-                * but if there's hardly any space, don't bother trying,
-                * just fall through to enlarge the buffer first.
-                *----------
+               /*
+                * Try to format the given string into the available space; but if
+                * there's hardly any space, don't bother trying, just fall through to
+                * enlarge the buffer first.
                 */
                if (str->maxlen > str->len + 16)
                {
@@ -193,7 +212,7 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
                         * actually stored, but at least one returns -1 on failure. Be
                         * conservative about believing whether the print worked.
                         */
-                       if (nprinted >= 0 && nprinted < avail - 1)
+                       if (nprinted >= 0 && nprinted < (int) avail - 1)
                        {
                                /* Success.  Note nprinted does not include trailing null. */
                                str->len += nprinted;
@@ -206,7 +225,7 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
        }
 }
 
-/*------------------------
+/*
  * appendPQExpBuffer
  *
  * Format text data under the control of fmt (an sprintf-like format string)
@@ -223,11 +242,10 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
 
        for (;;)
        {
-               /*----------
-                * Try to format the given string into the available space;
-                * but if there's hardly any space, don't bother trying,
-                * just fall through to enlarge the buffer first.
-                *----------
+               /*
+                * Try to format the given string into the available space; but if
+                * there's hardly any space, don't bother trying, just fall through to
+                * enlarge the buffer first.
                 */
                if (str->maxlen > str->len + 16)
                {
@@ -242,7 +260,7 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
                         * actually stored, but at least one returns -1 on failure. Be
                         * conservative about believing whether the print worked.
                         */
-                       if (nprinted >= 0 && nprinted < avail - 1)
+                       if (nprinted >= 0 && nprinted < (int) avail - 1)
                        {
                                /* Success.  Note nprinted does not include trailing null. */
                                str->len += nprinted;
@@ -255,7 +273,7 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
        }
 }
 
-/*------------------------
+/*
  * appendPQExpBufferStr
  * Append the given string to a PQExpBuffer, allocating more space
  * if necessary.
@@ -266,7 +284,7 @@ appendPQExpBufferStr(PQExpBuffer str, const char *data)
        appendBinaryPQExpBuffer(str, data, strlen(data));
 }
 
-/*------------------------
+/*
  * appendPQExpBufferChar
  * Append a single byte to str.
  * Like appendPQExpBuffer(str, "%c", ch) but much faster.
@@ -302,8 +320,8 @@ appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
        str->len += datalen;
 
        /*
-        * Keep a trailing null in place, even though it's probably useless
-        * for binary data...
+        * Keep a trailing null in place, even though it's probably useless for
+        * binary data...
         */
        str->data[str->len] = '\0';
 }