diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2007-11-23 01:46:58 +0000 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2007-11-23 01:46:58 +0000 |
commit | 5a0270a403e6192dcb195e80f6559516e7d9449f (patch) | |
tree | c964646064d23a2ffed6c71d27b9adf65c45cd57 | |
parent | d3786c0458ef96294c83bef3bb8a8cc55f865000 (diff) | |
download | postgresql-5a0270a403e6192dcb195e80f6559516e7d9449f.tar.gz |
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.
-rw-r--r-- | src/pl/plpython/plpython.c | 99 |
1 files changed, 26 insertions, 73 deletions
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index f17b86b945..6a7ceedbf3 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.90.2.2 2007/10/15 15:53:12 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.90.2.3 2007/11/23 01:46:58 alvherre Exp $ * ********************************************************************* */ @@ -197,11 +197,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 *); @@ -2874,35 +2871,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 * @@ -2914,8 +2920,8 @@ PLy_traceback(int *xlevel) PyObject *eob, *vob = NULL; char *vstr, - *estr, - *xstr = NULL; + *estr; + StringInfoData xstr; /* * get the current exception @@ -2947,7 +2953,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); @@ -2964,49 +2971,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 */ @@ -3024,18 +2989,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) { |