aboutsummaryrefslogtreecommitdiff
path: root/src/pl/plpython/plpython.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2005-07-10 04:56:55 +0000
committerBruce Momjian <bruce@momjian.us>2005-07-10 04:56:55 +0000
commit37f11c308136b64f521abfb87bdebd3f9df7b9e9 (patch)
treed73afa325745906fd69e5a51d21b64b5ded9b5c8 /src/pl/plpython/plpython.c
parent75a64eeb4b9dc4ad790ddc87f1f8357c2049576a (diff)
downloadpostgresql-37f11c308136b64f521abfb87bdebd3f9df7b9e9.tar.gz
postgresql-37f11c308136b64f521abfb87bdebd3f9df7b9e9.zip
This patch addresses the problem mentioned in the "process crash
when a plpython function returns unicode" thread: http://archives.postgresql.org/pgsql-bugs/2005-06/msg00105.php 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. In one place the patch doesn't call PLy_elog() because that could cause infinite recursion; see the comment I added. I'm not sure how to test that particular case or whether it's even possible to get an error there: the value that the code should check is the Python exception type, so I wonder if a NULL value "shouldn't happen." This patch converts NULL to "Unknown Exception" but I wonder if an Assert() would be appropriate. The patch is against HEAD but the same changes should be applied to earlier versions because they have the same problem. The patch might not apply cleanly against earlier versions -- will the committer take care of little differences or should I submit different versions of the patch? Michael Fuhr
Diffstat (limited to 'src/pl/plpython/plpython.c')
-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 3d7230ffca9..b1d47c77820 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.64 2005/07/05 18:15:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.65 2005/07/10 04:56:55 momjian Exp $
*
*********************************************************************
*/
@@ -517,6 +517,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,
@@ -774,6 +776,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),
@@ -2019,7 +2023,9 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long 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",
@@ -2044,6 +2050,9 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long 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);
/*
@@ -2531,7 +2540,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);