diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index 67694ab4..68ecb3bd 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -1016,6 +1016,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", @@ -1040,40 +1044,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