summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2007-11-23 01:46:58 +0000
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2007-11-23 01:46:58 +0000
commit5a0270a403e6192dcb195e80f6559516e7d9449f (patch)
treec964646064d23a2ffed6c71d27b9adf65c45cd57
parentd3786c0458ef96294c83bef3bb8a8cc55f865000 (diff)
downloadpostgresql-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.c99
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)
{