Exemplo n.º 1
0
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;
}