From 5cd72c7a7c7bd76ab028e1dc59d90a47750acebe Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 13 Mar 2012 15:26:32 -0400 Subject: [PATCH] Patch some corner-case bugs in pl/python. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dave Malcolm of Red Hat is working on a static code analysis tool for Python-related C code. It reported a number of problems in plpython, most of which were failures to check for NULL results from object-creation functions, so would only be an issue in very-low-memory situations. Patch in HEAD and 9.1. We could go further back but it's not clear that these issues are important enough to justify the work. Jan UrbaƄski --- src/pl/plpython/plpy_elog.c | 4 ++++ src/pl/plpython/plpy_main.c | 2 ++ src/pl/plpython/plpy_plpymodule.c | 18 ++++++++++++++++-- src/pl/plpython/plpy_spi.c | 3 ++- src/pl/plpython/plpy_typeio.c | 2 ++ 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c index 2f04a8c0db..f7d321289d 100644 --- a/src/pl/plpython/plpy_elog.c +++ b/src/pl/plpython/plpy_elog.c @@ -367,6 +367,10 @@ get_source_line(const char *src, int lineno) const char *next = src; int current = 0; + /* sanity check */ + if (lineno <= 0) + return NULL; + while (current < lineno) { s = next; diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c index 277dedc22d..c126db995a 100644 --- a/src/pl/plpython/plpy_main.c +++ b/src/pl/plpython/plpy_main.c @@ -142,6 +142,8 @@ PLy_init_interp(void) Py_INCREF(mainmod); PLy_interp_globals = PyModule_GetDict(mainmod); PLy_interp_safe_globals = PyDict_New(); + if (PLy_interp_safe_globals == NULL) + PLy_elog(ERROR, "could not create globals"); PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals); Py_DECREF(mainmod); if (PLy_interp_globals == NULL || PyErr_Occurred()) diff --git a/src/pl/plpython/plpy_plpymodule.c b/src/pl/plpython/plpy_plpymodule.c index d2d0a2a232..01caa0a323 100644 --- a/src/pl/plpython/plpy_plpymodule.c +++ b/src/pl/plpython/plpy_plpymodule.c @@ -173,9 +173,11 @@ PLy_init_plpy(void) main_mod = PyImport_AddModule("__main__"); main_dict = PyModule_GetDict(main_mod); plpy_mod = PyImport_AddModule("plpy"); + if (plpy_mod == NULL) + PLy_elog(ERROR, "could not initialize plpy"); PyDict_SetItemString(main_dict, "plpy", plpy_mod); if (PyErr_Occurred()) - elog(ERROR, "could not initialize plpy"); + PLy_elog(ERROR, "could not initialize plpy"); } static void @@ -208,6 +210,11 @@ PLy_add_exceptions(PyObject *plpy) PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL); PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL); + if (PLy_exc_error == NULL || + PLy_exc_fatal == NULL || + PLy_exc_spi_error == NULL) + PLy_elog(ERROR, "could not create the base SPI exceptions"); + Py_INCREF(PLy_exc_error); PyModule_AddObject(plpy, "Error", PLy_exc_error); Py_INCREF(PLy_exc_fatal); @@ -241,7 +248,13 @@ PLy_generate_spi_exceptions(PyObject *mod, PyObject *base) PyObject *sqlstate; PyObject *dict = PyDict_New(); + if (dict == NULL) + PLy_elog(ERROR, "could not generate SPI exceptions"); + sqlstate = PyString_FromString(unpack_sql_state(exception_map[i].sqlstate)); + if (sqlstate == NULL) + PLy_elog(ERROR, "could not generate SPI exceptions"); + PyDict_SetItemString(dict, "sqlstate", sqlstate); Py_DECREF(sqlstate); exc = PyErr_NewException(exception_map[i].name, base, dict); @@ -370,7 +383,8 @@ PLy_output(volatile int level, PyObject *self, PyObject *args) */ PyObject *o; - PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o); + if (!PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o)) + PLy_elog(ERROR, "could not unpack arguments in plpy.elog"); so = PyObject_Str(o); } else diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c index a75839b93e..cde3c08f96 100644 --- a/src/pl/plpython/plpy_spi.c +++ b/src/pl/plpython/plpy_spi.c @@ -340,7 +340,7 @@ PLy_spi_execute_query(char *query, long limit) int rv; volatile MemoryContext oldcontext; volatile ResourceOwner oldowner; - PyObject *ret; + PyObject *ret = NULL; oldcontext = CurrentMemoryContext; oldowner = CurrentResourceOwner; @@ -366,6 +366,7 @@ PLy_spi_execute_query(char *query, long limit) if (rv < 0) { + Py_XDECREF(ret); PLy_exception_set(PLy_exc_spi_error, "SPI_execute failed: %s", SPI_result_code_string(rv)); diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c index d04fe46d4b..9d6af05376 100644 --- a/src/pl/plpython/plpy_typeio.c +++ b/src/pl/plpython/plpy_typeio.c @@ -584,6 +584,8 @@ PLyList_FromArray(PLyDatumToOb *arg, Datum d) length = ARR_DIMS(array)[0]; lbound = ARR_LBOUND(array)[0]; list = PyList_New(length); + if (list == NULL) + PLy_elog(ERROR, "could not create new Python list"); for (i = 0; i < length; i++) {