Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0cb4a0b

Browse files
committed
Patch some corner-case bugs in pl/python.
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
1 parent 5a264d4 commit 0cb4a0b

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

src/pl/plpython/plpython.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,8 @@ PLyList_FromArray(PLyDatumToOb *arg, Datum d)
23452345
length = ARR_DIMS(array)[0];
23462346
lbound = ARR_LBOUND(array)[0];
23472347
list = PyList_New(length);
2348+
if (list == NULL)
2349+
PLy_elog(ERROR, "could not create new list");
23482350

23492351
for (i = 0; i < length; i++)
23502352
{
@@ -3664,7 +3666,7 @@ PLy_spi_execute_query(char *query, long limit)
36643666
int rv;
36653667
volatile MemoryContext oldcontext;
36663668
volatile ResourceOwner oldowner;
3667-
PyObject *ret;
3669+
PyObject *ret = NULL;
36683670

36693671
oldcontext = CurrentMemoryContext;
36703672
oldowner = CurrentResourceOwner;
@@ -3727,6 +3729,7 @@ PLy_spi_execute_query(char *query, long limit)
37273729

37283730
if (rv < 0)
37293731
{
3732+
Py_XDECREF(ret);
37303733
PLy_exception_set(PLy_exc_spi_error,
37313734
"SPI_execute failed: %s",
37323735
SPI_result_code_string(rv));
@@ -3967,7 +3970,13 @@ PLy_generate_spi_exceptions(PyObject *mod, PyObject *base)
39673970
PyObject *sqlstate;
39683971
PyObject *dict = PyDict_New();
39693972

3973+
if (dict == NULL)
3974+
PLy_elog(ERROR, "could not generate SPI exceptions");
3975+
39703976
sqlstate = PyString_FromString(unpack_sql_state(exception_map[i].sqlstate));
3977+
if (sqlstate == NULL)
3978+
PLy_elog(ERROR, "could not generate SPI exceptions");
3979+
39713980
PyDict_SetItemString(dict, "sqlstate", sqlstate);
39723981
Py_DECREF(sqlstate);
39733982
exc = PyErr_NewException(exception_map[i].name, base, dict);
@@ -4008,6 +4017,11 @@ PLy_add_exceptions(PyObject *plpy)
40084017
PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL);
40094018
PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL);
40104019

4020+
if (PLy_exc_error == NULL ||
4021+
PLy_exc_fatal == NULL ||
4022+
PLy_exc_spi_error == NULL)
4023+
PLy_elog(ERROR, "could not create the base SPI exceptions");
4024+
40114025
Py_INCREF(PLy_exc_error);
40124026
PyModule_AddObject(plpy, "Error", PLy_exc_error);
40134027
Py_INCREF(PLy_exc_fatal);
@@ -4124,6 +4138,8 @@ PLy_init_interp(void)
41244138
Py_INCREF(mainmod);
41254139
PLy_interp_globals = PyModule_GetDict(mainmod);
41264140
PLy_interp_safe_globals = PyDict_New();
4141+
if (PLy_interp_safe_globals == NULL)
4142+
PLy_elog(ERROR, "could not create globals");
41274143
PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
41284144
Py_DECREF(mainmod);
41294145
if (PLy_interp_globals == NULL || PyErr_Occurred())
@@ -4164,9 +4180,11 @@ PLy_init_plpy(void)
41644180
main_mod = PyImport_AddModule("__main__");
41654181
main_dict = PyModule_GetDict(main_mod);
41664182
plpy_mod = PyImport_AddModule("plpy");
4183+
if (plpy_mod == NULL)
4184+
PLy_elog(ERROR, "could not initialize plpy");
41674185
PyDict_SetItemString(main_dict, "plpy", plpy_mod);
41684186
if (PyErr_Occurred())
4169-
elog(ERROR, "could not initialize plpy");
4187+
PLy_elog(ERROR, "could not initialize plpy");
41704188
}
41714189

41724190
/* the python interface to the elog function
@@ -4232,7 +4250,8 @@ PLy_output(volatile int level, PyObject *self, PyObject *args)
42324250
*/
42334251
PyObject *o;
42344252

4235-
PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o);
4253+
if (!PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o))
4254+
PLy_elog(ERROR, "could not unpack arguments in plpy.elog");
42364255
so = PyObject_Str(o);
42374256
}
42384257
else
@@ -4554,6 +4573,10 @@ get_source_line(const char *src, int lineno)
45544573
const char *next = src;
45554574
int current = 0;
45564575

4576+
/* sanity check */
4577+
if (lineno <= 0)
4578+
return NULL;
4579+
45574580
while (current < lineno)
45584581
{
45594582
s = next;

0 commit comments

Comments
 (0)