]> granicus.if.org Git - postgresql/commitdiff
Fix buggy usage of vsnprintf in PL/Python by removing it altogether, instead
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 23 Nov 2007 01:46:34 +0000 (01:46 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 23 Nov 2007 01:46:34 +0000 (01:46 +0000)
relying on stringinfo.c.  This fixes a problem reported by Marko Kreen, but I
didn't use his patch, per subsequent discussion.

src/pl/plpython/plpython.c

index 80ce24caef7f2932de0e0bec81462a5cd7cbfc15..2b6e49d47beb758247e72f1fc6e5b1dc64aeca9d 100644 (file)
@@ -1,7 +1,7 @@
 /**********************************************************************
  * plpython.c - python as a procedural language for PostgreSQL
  *
- *     $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.104 2007/11/15 21:14:46 momjian Exp $
+ *     $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.105 2007/11/23 01:46:34 alvherre Exp $
  *
  *********************************************************************
  */
@@ -210,11 +210,8 @@ static char *PLy_procedure_name(PLyProcedure *);
 /* some utility functions */
 static void PLy_elog(int, const char *,...);
 static char *PLy_traceback(int *);
-static char *PLy_vprintf(const char *fmt, va_list ap);
-static char *PLy_printf(const char *fmt,...);
 
 static void *PLy_malloc(size_t);
-static void *PLy_realloc(void *, size_t);
 static char *PLy_strdup(const char *);
 static void PLy_free(void *);
 
@@ -2900,35 +2897,44 @@ PLy_exception_set(PyObject * exc, const char *fmt,...)
 static void
 PLy_elog(int elevel, const char *fmt,...)
 {
-       va_list         ap;
-       char       *xmsg,
-                          *emsg;
+       char       *xmsg;
        int                     xlevel;
+       StringInfoData emsg;
 
        xmsg = PLy_traceback(&xlevel);
 
-       va_start(ap, fmt);
-       emsg = PLy_vprintf(fmt, ap);
-       va_end(ap);
+       initStringInfo(&emsg);
+       for (;;)
+       {
+               va_list         ap;
+               bool            success;
+
+               va_start(ap, fmt);
+               success = appendStringInfoVA(&emsg, fmt, ap);
+               va_end(ap);
+               if (success)
+                       break;
+               enlargeStringInfo(&emsg, emsg.maxlen);
+       }
 
        PG_TRY();
        {
                ereport(elevel,
-                               (errmsg("plpython: %s", emsg),
+                               (errmsg("plpython: %s", emsg.data),
                                 (xmsg) ? errdetail("%s", xmsg) : 0));
        }
        PG_CATCH();
        {
-               PLy_free(emsg);
+               pfree(emsg.data);
                if (xmsg)
-                       PLy_free(xmsg);
+                       pfree(xmsg);
                PG_RE_THROW();
        }
        PG_END_TRY();
 
-       PLy_free(emsg);
+       pfree(emsg.data);
        if (xmsg)
-               PLy_free(xmsg);
+               pfree(xmsg);
 }
 
 static char *
@@ -2940,8 +2946,8 @@ PLy_traceback(int *xlevel)
        PyObject   *eob,
                           *vob = NULL;
        char       *vstr,
-                          *estr,
-                          *xstr = NULL;
+                          *estr;
+       StringInfoData xstr;
 
        /*
         * get the current exception
@@ -2973,7 +2979,8 @@ PLy_traceback(int *xlevel)
         * Assert() be more appropriate?
         */
        estr = eob ? PyString_AsString(eob) : "Unknown Exception";
-       xstr = PLy_printf("%s: %s", estr, vstr);
+       initStringInfo(&xstr);
+       appendStringInfo(&xstr, "%s: %s", estr, vstr);
 
        Py_DECREF(eob);
        Py_XDECREF(vob);
@@ -2990,49 +2997,7 @@ PLy_traceback(int *xlevel)
                *xlevel = ERROR;
 
        Py_DECREF(e);
-       return xstr;
-}
-
-static char *
-PLy_printf(const char *fmt,...)
-{
-       va_list         ap;
-       char       *emsg;
-
-       va_start(ap, fmt);
-       emsg = PLy_vprintf(fmt, ap);
-       va_end(ap);
-       return emsg;
-}
-
-static char *
-PLy_vprintf(const char *fmt, va_list ap)
-{
-       size_t          blen;
-       int                     bchar,
-                               tries = 2;
-       char       *buf;
-
-       blen = strlen(fmt) * 2;
-       if (blen < 256)
-               blen = 256;
-       buf = PLy_malloc(blen * sizeof(char));
-
-       while (1)
-       {
-               bchar = vsnprintf(buf, blen, fmt, ap);
-               if (bchar > 0 && bchar < blen)
-                       return buf;
-               if (tries-- <= 0)
-                       break;
-               if (blen > 0)
-                       blen = bchar + 1;
-               else
-                       blen *= 2;
-               buf = PLy_realloc(buf, blen);
-       }
-       PLy_free(buf);
-       return NULL;
+       return xstr.data;
 }
 
 /* python module code */
@@ -3050,18 +3015,6 @@ PLy_malloc(size_t bytes)
        return ptr;
 }
 
-static void *
-PLy_realloc(void *optr, size_t bytes)
-{
-       void       *nptr = realloc(optr, bytes);
-
-       if (nptr == NULL)
-               ereport(FATAL,
-                               (errcode(ERRCODE_OUT_OF_MEMORY),
-                                errmsg("out of memory")));
-       return nptr;
-}
-
 static char *
 PLy_strdup(const char *str)
 {