diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2014-06-05 02:18:05 +0200 |
---|---|---|
committer | mrmilosz <milosz@milosz.ca> | 2015-12-12 17:51:08 -0500 |
commit | d297976d6d01273745e8e1f18b435d84e84984fc (patch) | |
tree | b0eec89f23d02b76f2fe98ad7277a971ed075185 | |
parent | a3eed9c9f530f62b6d4c595b0f66ab16c5a4978d (diff) | |
download | psycopg2-d297976d6d01273745e8e1f18b435d84e84984fc.tar.gz |
Raise TypeError if the dict in callproc param contains non-strings
Check-and-conversion chain fixed and simplified. 'spname' was a
reference leak.
-rw-r--r-- | psycopg/cursor_type.c | 34 | ||||
-rwxr-xr-x | tests/test_cursor.py | 6 |
2 files changed, 13 insertions, 27 deletions
diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index effb2e6..b65b7d2 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -1028,8 +1028,6 @@ psyco_curs_callproc(cursorObject *self, PyObject *args) int using_dict; #if PG_VERSION_HEX >= 0x090000 PyObject *pname = NULL; - PyObject *spname = NULL; - PyObject *bpname = NULL; PyObject *pnames = NULL; char *cpname = NULL; char **scpnames = NULL; @@ -1076,37 +1074,24 @@ psyco_curs_callproc(cursorObject *self, PyObject *args) for (i = 0; i < nparameters; i++) { /* all errors are RuntimeErrors as they should never occur */ - if (!(pname = PyList_GetItem(pnames, i))) { - goto exit; - } - - if (!(spname = PyObject_Str(pname))) { - goto exit; - } - - /* this is the only function here that returns a new reference */ - if (!(bpname = psycopg_ensure_bytes(spname))) { - goto exit; - } + if (!(pname = PyList_GetItem(pnames, i))) { goto exit; } + Py_INCREF(pname); /* was borrowed */ - if (!(cpname = Bytes_AsString(bpname))) { - Py_XDECREF(bpname); - goto exit; - } + /* this also makes a check for keys being strings */ + if (!(pname = psycopg_ensure_bytes(pname))) { goto exit; } + if (!(cpname = Bytes_AsString(pname))) { goto exit; } - if (!(scpnames[i] = PQescapeIdentifier(self->conn->pgconn, cpname, - strlen(cpname)))) { - Py_XDECREF(bpname); + if (!(scpnames[i] = PQescapeIdentifier( + self->conn->pgconn, cpname, strlen(cpname)))) { goto exit; } - Py_XDECREF(bpname); + Py_CLEAR(pname); sl += strlen(scpnames[i]); } - sql = (char*)PyMem_Malloc(sl); - if (sql == NULL) { + if (!(sql = (char*)PyMem_Malloc(sl))) { PyErr_NoMemory(); goto exit; } @@ -1170,6 +1155,7 @@ exit: } } PyMem_Del(scpnames); + Py_XDECREF(pname); Py_XDECREF(pnames); #endif Py_XDECREF(operation); diff --git a/tests/test_cursor.py b/tests/test_cursor.py index 00d19df..00143ee 100755 --- a/tests/test_cursor.py +++ b/tests/test_cursor.py @@ -520,9 +520,9 @@ class CursorTests(ConnectingTestCase): ({ paramname: 2, 'foo': 'bar' }, psycopg2.ProgrammingError), ({ paramname: '2' }, psycopg2.ProgrammingError), ({ paramname: 'two' }, psycopg2.ProgrammingError), - ({ 'bjørn': 2 }, psycopg2.ProgrammingError), - ({ 3: 2 }, psycopg2.ProgrammingError), - ({ self: 2 }, psycopg2.ProgrammingError), + ({ u'bj\xc3rn': 2 }, psycopg2.ProgrammingError), + ({ 3: 2 }, TypeError), + ({ self: 2 }, TypeError), ] for parameter_sequence, exception in failing_cases: self.assertRaises(exception, cur.callproc, procname, parameter_sequence) |