From 558c9270c4b25121342e192aca96185140ed164f Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvherre@alvh.no-ip.org> Date: Fri, 23 Nov 2007 01:46:34 +0000 Subject: [PATCH] Fix buggy usage of vsnprintf in PL/Python by removing it altogether, instead 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 | 99 ++++++++++---------------------------- 1 file changed, 26 insertions(+), 73 deletions(-) diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index 80ce24caef7..2b6e49d47be 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -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) { -- GitLab