Skip to content

Commit 558c927

Browse files
committed
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.
1 parent d8e8a49 commit 558c927

File tree

1 file changed

+26
-73
lines changed

1 file changed

+26
-73
lines changed

src/pl/plpython/plpython.c

Lines changed: 26 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**********************************************************************
22
* plpython.c - python as a procedural language for PostgreSQL
33
*
4-
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.104 2007/11/15 21:14:46 momjian Exp $
4+
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.105 2007/11/23 01:46:34 alvherre Exp $
55
*
66
*********************************************************************
77
*/
@@ -210,11 +210,8 @@ static char *PLy_procedure_name(PLyProcedure *);
210210
/* some utility functions */
211211
static void PLy_elog(int, const char *,...);
212212
static char *PLy_traceback(int *);
213-
static char *PLy_vprintf(const char *fmt, va_list ap);
214-
static char *PLy_printf(const char *fmt,...);
215213

216214
static void *PLy_malloc(size_t);
217-
static void *PLy_realloc(void *, size_t);
218215
static char *PLy_strdup(const char *);
219216
static void PLy_free(void *);
220217

@@ -2900,35 +2897,44 @@ PLy_exception_set(PyObject * exc, const char *fmt,...)
29002897
static void
29012898
PLy_elog(int elevel, const char *fmt,...)
29022899
{
2903-
va_list ap;
2904-
char *xmsg,
2905-
*emsg;
2900+
char *xmsg;
29062901
int xlevel;
2902+
StringInfoData emsg;
29072903

29082904
xmsg = PLy_traceback(&xlevel);
29092905

2910-
va_start(ap, fmt);
2911-
emsg = PLy_vprintf(fmt, ap);
2912-
va_end(ap);
2906+
initStringInfo(&emsg);
2907+
for (;;)
2908+
{
2909+
va_list ap;
2910+
bool success;
2911+
2912+
va_start(ap, fmt);
2913+
success = appendStringInfoVA(&emsg, fmt, ap);
2914+
va_end(ap);
2915+
if (success)
2916+
break;
2917+
enlargeStringInfo(&emsg, emsg.maxlen);
2918+
}
29132919

29142920
PG_TRY();
29152921
{
29162922
ereport(elevel,
2917-
(errmsg("plpython: %s", emsg),
2923+
(errmsg("plpython: %s", emsg.data),
29182924
(xmsg) ? errdetail("%s", xmsg) : 0));
29192925
}
29202926
PG_CATCH();
29212927
{
2922-
PLy_free(emsg);
2928+
pfree(emsg.data);
29232929
if (xmsg)
2924-
PLy_free(xmsg);
2930+
pfree(xmsg);
29252931
PG_RE_THROW();
29262932
}
29272933
PG_END_TRY();
29282934

2929-
PLy_free(emsg);
2935+
pfree(emsg.data);
29302936
if (xmsg)
2931-
PLy_free(xmsg);
2937+
pfree(xmsg);
29322938
}
29332939

29342940
static char *
@@ -2940,8 +2946,8 @@ PLy_traceback(int *xlevel)
29402946
PyObject *eob,
29412947
*vob = NULL;
29422948
char *vstr,
2943-
*estr,
2944-
*xstr = NULL;
2949+
*estr;
2950+
StringInfoData xstr;
29452951

29462952
/*
29472953
* get the current exception
@@ -2973,7 +2979,8 @@ PLy_traceback(int *xlevel)
29732979
* Assert() be more appropriate?
29742980
*/
29752981
estr = eob ? PyString_AsString(eob) : "Unknown Exception";
2976-
xstr = PLy_printf("%s: %s", estr, vstr);
2982+
initStringInfo(&xstr);
2983+
appendStringInfo(&xstr, "%s: %s", estr, vstr);
29772984

29782985
Py_DECREF(eob);
29792986
Py_XDECREF(vob);
@@ -2990,49 +2997,7 @@ PLy_traceback(int *xlevel)
29902997
*xlevel = ERROR;
29912998

29922999
Py_DECREF(e);
2993-
return xstr;
2994-
}
2995-
2996-
static char *
2997-
PLy_printf(const char *fmt,...)
2998-
{
2999-
va_list ap;
3000-
char *emsg;
3001-
3002-
va_start(ap, fmt);
3003-
emsg = PLy_vprintf(fmt, ap);
3004-
va_end(ap);
3005-
return emsg;
3006-
}
3007-
3008-
static char *
3009-
PLy_vprintf(const char *fmt, va_list ap)
3010-
{
3011-
size_t blen;
3012-
int bchar,
3013-
tries = 2;
3014-
char *buf;
3015-
3016-
blen = strlen(fmt) * 2;
3017-
if (blen < 256)
3018-
blen = 256;
3019-
buf = PLy_malloc(blen * sizeof(char));
3020-
3021-
while (1)
3022-
{
3023-
bchar = vsnprintf(buf, blen, fmt, ap);
3024-
if (bchar > 0 && bchar < blen)
3025-
return buf;
3026-
if (tries-- <= 0)
3027-
break;
3028-
if (blen > 0)
3029-
blen = bchar + 1;
3030-
else
3031-
blen *= 2;
3032-
buf = PLy_realloc(buf, blen);
3033-
}
3034-
PLy_free(buf);
3035-
return NULL;
3000+
return xstr.data;
30363001
}
30373002

30383003
/* python module code */
@@ -3050,18 +3015,6 @@ PLy_malloc(size_t bytes)
30503015
return ptr;
30513016
}
30523017

3053-
static void *
3054-
PLy_realloc(void *optr, size_t bytes)
3055-
{
3056-
void *nptr = realloc(optr, bytes);
3057-
3058-
if (nptr == NULL)
3059-
ereport(FATAL,
3060-
(errcode(ERRCODE_OUT_OF_MEMORY),
3061-
errmsg("out of memory")));
3062-
return nptr;
3063-
}
3064-
30653018
static char *
30663019
PLy_strdup(const char *str)
30673020
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy