Patch some corner-case bugs in pl/python.
authorTom Lane
Tue, 13 Mar 2012 19:26:32 +0000 (15:26 -0400)
committerTom Lane
Tue, 13 Mar 2012 19:26:32 +0000 (15:26 -0400)
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
src/pl/plpython/plpy_main.c
src/pl/plpython/plpy_plpymodule.c
src/pl/plpython/plpy_spi.c
src/pl/plpython/plpy_typeio.c

index 2f04a8c0dba17645f8ae786a3bbae61776767a7f..f7d321289d4acec776dca8da684f08e6532fb157 100644 (file)
@@ -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;
index 277dedc22d2dae8c568aa32283006835216ff9b2..c126db995ae3470a405d4f1d96a7a3c638be6937 100644 (file)
@@ -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())
index d2d0a2a2323c0751c4b5841937de0698e9048aea..01caa0a3236e59e413232f4fd27b93c226ca1a44 100644 (file)
@@ -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
index a75839b93ea3c95250d45ca6744d910ce61bf7b2..cde3c08f967bd5d3aaf2af86fb7711905b9733e9 100644 (file)
@@ -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));
index d04fe46d4b77ebf3f116f8879ebe00466bf5c371..9d6af053761a13e19895e26891b1ec30a0fd8e38 100644 (file)
@@ -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++)
    {