summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2014-06-05 02:18:05 +0200
committermrmilosz <milosz@milosz.ca>2015-12-12 17:51:08 -0500
commitd297976d6d01273745e8e1f18b435d84e84984fc (patch)
treeb0eec89f23d02b76f2fe98ad7277a971ed075185
parenta3eed9c9f530f62b6d4c595b0f66ab16c5a4978d (diff)
downloadpsycopg2-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.c34
-rwxr-xr-xtests/test_cursor.py6
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)