mirror of
https://github.com/postgres/postgres.git
synced 2025-07-31 22:04:40 +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:
@ -1,7 +1,7 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* plpython.c - python as a procedural language for PostgreSQL
|
* 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 */
|
/* some utility functions */
|
||||||
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 char *PLy_strdup(const char *);
|
static char *PLy_strdup(const char *);
|
||||||
static void PLy_free(void *);
|
static void PLy_free(void *);
|
||||||
|
|
||||||
@ -2900,35 +2897,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);
|
||||||
|
|
||||||
|
initStringInfo(&emsg);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
bool success;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
emsg = PLy_vprintf(fmt, ap);
|
success = appendStringInfoVA(&emsg, fmt, ap);
|
||||||
va_end(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 *
|
||||||
@ -2940,8 +2946,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
|
||||||
@ -2973,7 +2979,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);
|
||||||
@ -2990,49 +2997,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 */
|
||||||
@ -3050,18 +3015,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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
PLy_strdup(const char *str)
|
PLy_strdup(const char *str)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user