aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2005-09-23 21:02:37 +0000
committerBruce Momjian <bruce@momjian.us>2005-09-23 21:02:37 +0000
commit341c3399da6f58e6aaaf38d96af0656efe923a52 (patch)
treecdc33a4309c4ad0878901891573caf9b4ae819e2 /src
parent9516724bd7aab58745eb0fb8b73fb6449272adf1 (diff)
downloadpostgresql-341c3399da6f58e6aaaf38d96af0656efe923a52.tar.gz
postgresql-341c3399da6f58e6aaaf38d96af0656efe923a52.zip
Backpatch to 8.0.X:
In several places PL/Python was calling PyObject_Str() and then PyString_AsString() without checking if the former had returned NULL to indicate an error. PyString_AsString() doesn't expect a NULL argument, so passing one causes a segmentation fault. This patch adds checks for NULL and raises errors via PLy_elog(), which prints details of the underlying Python exception. The patch also adds regression tests for these checks. All tests pass on my Solaris 9 box running HEAD and Python 2.4.1.
Diffstat (limited to 'src')
-rw-r--r--src/pl/plpython/plpython.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index ff584f077dd..acd9ce216bf 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -29,7 +29,7 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.58.4.1 2005/03/24 17:22:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.58.4.2 2005/09/23 21:02:37 momjian Exp $
*
*********************************************************************
*/
@@ -516,6 +516,8 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
if (plval != Py_None && !tupdesc->attrs[atti]->attisdropped)
{
plstr = PyObject_Str(plval);
+ if (!plstr)
+ PLy_elog(ERROR, "function \"%s\" could not modify tuple", proc->proname);
src = PyString_AsString(plstr);
modvalues[i] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc,
@@ -773,6 +775,8 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
{
fcinfo->isnull = false;
plrv_so = PyObject_Str(plrv);
+ if (!plrv_so)
+ PLy_elog(ERROR, "function \"%s\" could not create return value", proc->proname);
plrv_sc = PyString_AsString(plrv_so);
rv = FunctionCall3(&proc->result.out.d.typfunc,
PointerGetDatum(plrv_sc),
@@ -2018,7 +2022,9 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit)
char *sv;
PyObject *so = PyObject_Str(list);
-
+ if (!so)
+ PLy_elog(ERROR, "function \"%s\" could not execute plan",
+ PLy_procedure_name(PLy_curr_procedure));
sv = PyString_AsString(so);
PLy_exception_set(PLy_exc_spi_error,
"Expected sequence of %d arguments, got %d. %s",
@@ -2043,6 +2049,9 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit)
if (elem != Py_None)
{
so = PyObject_Str(elem);
+ if (!so)
+ PLy_elog(ERROR, "function \"%s\" could not execute plan",
+ PLy_procedure_name(PLy_curr_procedure));
sv = PyString_AsString(so);
/*
@@ -2530,7 +2539,13 @@ PLy_traceback(int *xlevel)
else
vstr = "Unknown";
- estr = PyString_AsString(eob);
+ /*
+ * I'm not sure what to do if eob is NULL here -- we can't call
+ * PLy_elog because that function calls us, so we could end up
+ * with infinite recursion. I'm not even sure if eob could be
+ * NULL here -- would an Assert() be more appropriate?
+ */
+ estr = eob ? PyString_AsString(eob) : "Unknown Exception";
xstr = PLy_printf("%s: %s", estr, vstr);
Py_DECREF(eob);