diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index 16339971..113e0a54 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -1025,6 +1025,10 @@ psyco_curs_callproc(cursorObject *self, PyObject *args) PyObject *operation = NULL; PyObject *res = NULL; PyObject *parameter_name = NULL; + PyObject *parameter_name_bytes = NULL; + char *parameter_name_cstr = NULL; + char *parameter_name_cstr_sanitized = NULL; + char **parameter_name_cstr_sanitized_CACHE = NULL; PyObject *parameter_names = NULL; if (!PyArg_ParseTuple(args, "s#|O", @@ -1048,40 +1052,71 @@ psyco_curs_callproc(cursorObject *self, PyObject *args) /* allocate some memory, build the SQL and create a PyString from it */ + /* a dict requires special handling: we put the parameter names into the SQL */ if (nparameters > 0 && PyDict_Check(parameters)) { - /* for a dict, we put the parameter names into the SQL */ + parameter_names = PyDict_Keys(parameters); - /* first we need to figure out how much space we need for the SQL */ - sl = procname_len + 17 + nparameters*5 - (nparameters ? 1 : 0); + /* first we need to ensure the dict's keys are text */ for(i=0; iconn->pgconn, parameter_name_cstr, strlen(parameter_name_cstr)); + Py_DECREF(parameter_name); + + /* must add the length of the sanitized string to the length of the SQL string */ + sl += strlen(parameter_name_cstr_sanitized); + + parameter_name_cstr_sanitized_CACHE[i] = parameter_name_cstr_sanitized; + } + + Py_DECREF(parameter_names); + sql = (char*)PyMem_Malloc(sl); if (sql == NULL) { - PyErr_NoMemory(); - goto exit; + PyErr_NoMemory(); + for(i=0; i 2