1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-28 05:21:27 +03:00

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.
This commit is contained in:
Alvaro Herrera 2007-11-23 01:47:12 +00:00
parent d4becb639d
commit 4bf3801d59

View File

@ -29,7 +29,7 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.4 2006/02/20 20:10:41 neilc Exp $ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.5 2007/11/23 01:47:12 alvherre Exp $
* *
********************************************************************* *********************************************************************
*/ */
@ -48,6 +48,7 @@
#include "commands/trigger.h" #include "commands/trigger.h"
#include "executor/spi.h" #include "executor/spi.h"
#include "fmgr.h" #include "fmgr.h"
#include "lib/stringinfo.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "tcop/tcopprot.h" #include "tcop/tcopprot.h"
@ -204,11 +205,8 @@ static char *PLy_procedure_name(PLyProcedure *);
*/ */
static void PLy_elog(int, const char *,...); static void PLy_elog(int, const char *,...);
static char *PLy_traceback(int *); 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_malloc(size_t);
static void *PLy_realloc(void *, size_t);
static void PLy_free(void *); static void PLy_free(void *);
/* sub handlers for functions and triggers /* sub handlers for functions and triggers
@ -2478,35 +2476,44 @@ PLy_exception_set(PyObject * exc, const char *fmt,...)
static void static void
PLy_elog(int elevel, const char *fmt,...) PLy_elog(int elevel, const char *fmt,...)
{ {
va_list ap; char *xmsg;
char *xmsg,
*emsg;
int xlevel; int xlevel;
StringInfoData emsg;
xmsg = PLy_traceback(&xlevel); xmsg = PLy_traceback(&xlevel);
va_start(ap, fmt); initStringInfo(&emsg);
emsg = PLy_vprintf(fmt, ap); for (;;)
va_end(ap); {
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(); PG_TRY();
{ {
ereport(elevel, ereport(elevel,
(errmsg("plpython: %s", emsg), (errmsg("plpython: %s", emsg.data),
(xmsg) ? errdetail("%s", xmsg) : 0)); (xmsg) ? errdetail("%s", xmsg) : 0));
} }
PG_CATCH(); PG_CATCH();
{ {
PLy_free(emsg); pfree(emsg.data);
if (xmsg) if (xmsg)
PLy_free(xmsg); pfree(xmsg);
PG_RE_THROW(); PG_RE_THROW();
} }
PG_END_TRY(); PG_END_TRY();
PLy_free(emsg); pfree(emsg.data);
if (xmsg) if (xmsg)
PLy_free(xmsg); pfree(xmsg);
} }
static char * static char *
@ -2518,8 +2525,8 @@ PLy_traceback(int *xlevel)
PyObject *eob, PyObject *eob,
*vob = NULL; *vob = NULL;
char *vstr, char *vstr,
*estr, *estr;
*xstr = NULL; StringInfoData xstr;
/* /*
* get the current exception * get the current exception
@ -2551,7 +2558,8 @@ PLy_traceback(int *xlevel)
* Assert() be more appropriate? * Assert() be more appropriate?
*/ */
estr = eob ? PyString_AsString(eob) : "Unknown Exception"; 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_DECREF(eob);
Py_XDECREF(vob); Py_XDECREF(vob);
@ -2568,49 +2576,7 @@ PLy_traceback(int *xlevel)
*xlevel = ERROR; *xlevel = ERROR;
Py_DECREF(e); Py_DECREF(e);
return xstr; return xstr.data;
}
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;
} }
/* python module code /* python module code
@ -2632,18 +2598,6 @@ PLy_malloc(size_t bytes)
return ptr; 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;
}
/* define this away /* define this away
*/ */
static void static void