Raise TypeError if the dict in callproc param contains non-strings

Check-and-conversion chain fixed and simplified. 'spname' was a
reference leak.
This commit is contained in:
Daniele Varrazzo 2014-06-05 02:18:05 +02:00 committed by mrmilosz
parent a3eed9c9f5
commit d297976d6d
2 changed files with 15 additions and 29 deletions

View File

@ -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))) {
if (!(pname = PyList_GetItem(pnames, i))) { goto exit; }
Py_INCREF(pname); /* was borrowed */
/* 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)))) {
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 (!(cpname = Bytes_AsString(bpname))) {
Py_XDECREF(bpname);
goto exit;
}
if (!(scpnames[i] = PQescapeIdentifier(self->conn->pgconn, cpname,
strlen(cpname)))) {
Py_XDECREF(bpname);
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);

View File

@ -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)