static PyObject * qstring_quote(qstringObject *self) { PyObject *str; char *s, *buffer; Py_ssize_t len, qlen; /* if the wrapped object is an unicode object we can encode it to match self->encoding but if the encoding is not specified we don't know what to do and we raise an exception */ Dprintf("qstring_quote: encoding to %s", self->encoding); if (PyUnicode_Check(self->wrapped) && self->encoding) { PyObject *enc = PyDict_GetItemString(psycoEncodings, self->encoding); /* note that enc is a borrowed reference */ if (enc) { const char *s = PyString_AsString(enc); Dprintf("qstring_quote: encoding unicode object to %s", s); str = PyUnicode_AsEncodedString(self->wrapped, s, NULL); Dprintf("qstring_quote: got encoded object at %p", str); if (str == NULL) return NULL; } else { /* can't find the right encoder, raise exception */ PyErr_Format(InterfaceError, "can't encode unicode string to %s", self->encoding); return NULL; } } /* if the wrapped object is a simple string, we don't know how to (re)encode it, so we pass it as-is */ else if (PyString_Check(self->wrapped)) { str = self->wrapped; /* INCREF to make it ref-wise identical to unicode one */ Py_INCREF(str); } /* if the wrapped object is not a string, this is an error */ else { PyErr_SetString(PyExc_TypeError, "can't quote non-string object (or missing encoding)"); return NULL; } /* encode the string into buffer */ PyString_AsStringAndSize(str, &s, &len); /* Call qstring_escape with the GIL released, then reacquire the GIL before verifying that the results can fit into a Python string; raise an exception if not. */ Py_BEGIN_ALLOW_THREADS buffer = psycopg_escape_string(self->conn, s, len, NULL, &qlen); Py_END_ALLOW_THREADS if (buffer == NULL) { Py_DECREF(str); PyErr_NoMemory(); return NULL; } if (qlen > (size_t) PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_IndexError, "PG buffer too large to fit in Python buffer."); PyMem_Free(buffer); Py_DECREF(str); return NULL; } self->buffer = PyString_FromStringAndSize(buffer, qlen); PyMem_Free(buffer); Py_DECREF(str); return self->buffer; }
static PyObject * qstring_quote(qstringObject *self) { PyObject *str = NULL; char *s, *buffer = NULL; Py_ssize_t len, qlen; const char *encoding = default_encoding; PyObject *rv = NULL; /* if the wrapped object is an unicode object we can encode it to match conn->encoding but if the encoding is not specified we don't know what to do and we raise an exception */ if (self->conn) { encoding = self->conn->codec; } Dprintf("qstring_quote: encoding to %s", encoding); if (PyUnicode_Check(self->wrapped) && encoding) { str = PyUnicode_AsEncodedString(self->wrapped, encoding, NULL); Dprintf("qstring_quote: got encoded object at %p", str); if (str == NULL) goto exit; } #if PY_MAJOR_VERSION < 3 /* if the wrapped object is a simple string, we don't know how to (re)encode it, so we pass it as-is */ else if (PyString_Check(self->wrapped)) { str = self->wrapped; /* INCREF to make it ref-wise identical to unicode one */ Py_INCREF(str); } #endif /* if the wrapped object is not a string, this is an error */ else { PyErr_SetString(PyExc_TypeError, "can't quote non-string object (or missing encoding)"); goto exit; } /* encode the string into buffer */ Bytes_AsStringAndSize(str, &s, &len); if (!(buffer = psycopg_escape_string(self->conn, s, len, NULL, &qlen))) { goto exit; } if (qlen > (size_t) PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_IndexError, "PG buffer too large to fit in Python buffer."); goto exit; } rv = Bytes_FromStringAndSize(buffer, qlen); exit: PyMem_Free(buffer); Py_XDECREF(str); return rv; }