Ejemplo n.º 1
0
/* Convert a Postgres encoding into Python encoding and decoding functions.
 *
 * Set clean_encoding to a clean version of the Postgres encoding name
 * and pyenc and pydec to python codec functions.
 *
 * Return 0 on success, else -1 and set an exception.
 */
RAISES_NEG static int
conn_get_python_codec(const char *encoding,
    char **clean_encoding, PyObject **pyenc, PyObject **pydec)
{
    int rv = -1;
    char *pgenc = NULL;
    PyObject *encname = NULL;
    PyObject *enc_tmp = NULL, *dec_tmp = NULL;

    /* get the Python name of the encoding as a C string */
    if (!(encname = conn_pgenc_to_pyenc(encoding, &pgenc))) { goto exit; }
    if (!(encname = psyco_ensure_bytes(encname))) { goto exit; }

    /* Look up the codec functions */
    if (!(enc_tmp = PyCodec_Encoder(Bytes_AS_STRING(encname)))) { goto exit; }
    if (!(dec_tmp = PyCodec_Decoder(Bytes_AS_STRING(encname)))) { goto exit; }

    /* success */
    *pyenc = enc_tmp; enc_tmp = NULL;
    *pydec = dec_tmp; dec_tmp = NULL;
    *clean_encoding = pgenc; pgenc = NULL;
    rv = 0;

exit:
    Py_XDECREF(enc_tmp);
    Py_XDECREF(dec_tmp);
    Py_XDECREF(encname);
    PyMem_Free(pgenc);

    return rv;
}
Ejemplo n.º 2
0
RAISES_NEG static int
_psyco_conn_parse_onoff(PyObject *pyval)
{
    int rv = -1;

    Py_INCREF(pyval);   /* for ensure_bytes */

    if (pyval == Py_None) {
        rv = STATE_DEFAULT;
    }
    else if (PyUnicode_CheckExact(pyval) || Bytes_CheckExact(pyval)) {
        if (!(pyval = psycopg_ensure_bytes(pyval))) {
            goto exit;
        }
        if (0 == strcasecmp("default", Bytes_AS_STRING(pyval))) {
            rv = STATE_DEFAULT;
        }
        else {
            PyErr_Format(PyExc_ValueError,
                "the only string accepted is 'default'; got %s",
                Bytes_AS_STRING(pyval));
            goto exit;
        }
    }
    else {
        int istrue;
        if (0 > (istrue = PyObject_IsTrue(pyval))) { goto exit; }
        rv = istrue ? STATE_ON : STATE_OFF;
    }

exit:
    Py_XDECREF(pyval);

    return rv;
}
Ejemplo n.º 3
0
static const char *
_psyco_conn_parse_isolevel(connectionObject *self, PyObject *pyval)
{
    const IsolationLevel *isolevel = NULL;

    Py_INCREF(pyval);   /* for ensure_bytes */

    /* parse from one of the level constants */
    if (PyInt_Check(pyval)) {
        long level = PyInt_AsLong(pyval);
        if (level == -1 && PyErr_Occurred()) { goto exit; }
        if (level < 1 || level > 4) {
            PyErr_SetString(PyExc_ValueError,
                "isolation_level must be between 1 and 4");
            goto exit;
        }

        isolevel = conn_isolevels;
        while ((++isolevel)->value != level)
            ; /* continue */
    }

    /* parse from the string -- this includes "default" */
    else {
        isolevel = conn_isolevels;
        while ((++isolevel)->name) {
            if (!(pyval = psycopg_ensure_bytes(pyval))) {
                goto exit;
            }
            if (0 == strcasecmp(isolevel->name, Bytes_AS_STRING(pyval))) {
                break;
            }
        }
        if (!isolevel->name) {
            char msg[256];
            snprintf(msg, sizeof(msg),
                "bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval));
            PyErr_SetString(PyExc_ValueError, msg);
        }
    }

    /* use only supported levels on older PG versions */
    if (isolevel && self->server_version < 80000) {
        if (isolevel->value == ISOLATION_LEVEL_READ_UNCOMMITTED
            || isolevel->value == ISOLATION_LEVEL_REPEATABLE_READ) {
            ++isolevel;
        }
    }

exit:
    Py_XDECREF(pyval);

    return isolevel ? isolevel->name : NULL;
}
Ejemplo n.º 4
0
RAISES_NEG static int
_psyco_conn_parse_isolevel(PyObject *pyval)
{
    int rv = -1;
    long level;

    Py_INCREF(pyval);   /* for ensure_bytes */

    /* None is default. This is only used when setting the property, because
     * set_session() has None used as "don't change" */
    if (pyval == Py_None) {
        rv = ISOLATION_LEVEL_DEFAULT;
    }

    /* parse from one of the level constants */
    else if (PyInt_Check(pyval)) {
        level = PyInt_AsLong(pyval);
        if (level == -1 && PyErr_Occurred()) { goto exit; }
        if (level < 1 || level > 4) {
            PyErr_SetString(PyExc_ValueError,
                "isolation_level must be between 1 and 4");
            goto exit;
        }

        rv = level;
    }

    /* parse from the string -- this includes "default" */
    else {
        if (!(pyval = psycopg_ensure_bytes(pyval))) {
            goto exit;
        }
        for (level = 1; level <= 4; level++) {
            if (0 == strcasecmp(srv_isolevels[level], Bytes_AS_STRING(pyval))) {
                rv = level;
                break;
            }
        }
        if (rv < 0 && 0 == strcasecmp("default", Bytes_AS_STRING(pyval))) {
            rv = ISOLATION_LEVEL_DEFAULT;
        }
        if (rv < 0) {
            PyErr_Format(PyExc_ValueError,
                "bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval));
            goto exit;
        }
    }

exit:
    Py_XDECREF(pyval);

    return rv;
}
Ejemplo n.º 5
0
static PyObject *
psyco_parse_dsn(PyObject *self, PyObject *args, PyObject *kwargs)
{
    char *err = NULL;
    PQconninfoOption *options = NULL;
    PyObject *res = NULL, *dsn;

    static char *kwlist[] = {"dsn", NULL};
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &dsn)) {
        return NULL;
    }

    Py_INCREF(dsn); /* for ensure_bytes */
    if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; }

    options = PQconninfoParse(Bytes_AS_STRING(dsn), &err);
    if (options == NULL) {
        if (err != NULL) {
            PyErr_Format(ProgrammingError, "invalid dsn: %s", err);
            PQfreemem(err);
        } else {
            PyErr_SetString(OperationalError, "PQconninfoParse() failed");
        }
        goto exit;
    }

    res = psycopg_dict_from_conninfo_options(options, /* include_password = */ 1);

exit:
    PQconninfoFree(options);    /* safe on null */
    Py_XDECREF(dsn);

    return res;
}
Ejemplo n.º 6
0
static PyObject *
pint_getquoted(pintObject *self, PyObject *args)
{
    PyObject *res = NULL;

    /* Convert subclass to int to handle IntEnum and other subclasses
     * whose str() is not the number. */
    if (PyLong_CheckExact(self->wrapped)
#if PY_MAJOR_VERSION < 2
        || PyInt_CheckExact(self->wrapped)
#endif
       ) {
        res = PyObject_Str(self->wrapped);
    } else {
        PyObject *tmp;
        if (!(tmp = PyObject_CallFunctionObjArgs(
                (PyObject *)&PyLong_Type, self->wrapped, NULL))) {
            goto exit;
        }
        res = PyObject_Str(tmp);
        Py_DECREF(tmp);
    }

    if (!res) {
        goto exit;
    }

#if PY_MAJOR_VERSION > 2
    /* unicode to bytes in Py3 */
    {
        PyObject *tmp = PyUnicode_AsUTF8String(res);
        Py_DECREF(res);
        if (!(res = tmp)) {
            goto exit;
        }
    }
#endif

    if ('-' == Bytes_AS_STRING(res)[0]) {
        /* Prepend a space in front of negative numbers (ticket #57) */
        PyObject *tmp;
        if (!(tmp = Bytes_FromString(" "))) {
            Py_DECREF(res);
            res = NULL;
            goto exit;
        }
        Bytes_ConcatAndDel(&tmp, res);
        if (!(res = tmp)) {
            goto exit;
        }
    }

exit:
    return res;
}
Ejemplo n.º 7
0
static PyObject *
psyco_parse_dsn(PyObject *self, PyObject *args, PyObject *kwargs)
{
    char *err = NULL;
    PQconninfoOption *options = NULL, *o;
    PyObject *dict = NULL, *res = NULL, *dsn;

    static char *kwlist[] = {"dsn", NULL};
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &dsn)) {
        return NULL;
    }

    Py_INCREF(dsn); /* for ensure_bytes */
    if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; }

    options = PQconninfoParse(Bytes_AS_STRING(dsn), &err);
    if (options == NULL) {
        if (err != NULL) {
            PyErr_Format(ProgrammingError, "error parsing the dsn: %s", err);
            PQfreemem(err);
        } else {
            PyErr_SetString(OperationalError, "PQconninfoParse() failed");
        }
        goto exit;
    }

    if (!(dict = PyDict_New())) { goto exit; }
    for (o = options; o->keyword != NULL; o++) {
        if (o->val != NULL) {
            PyObject *value;
            if (!(value = Text_FromUTF8(o->val))) { goto exit; }
            if (PyDict_SetItemString(dict, o->keyword, value) != 0) {
                Py_DECREF(value);
                goto exit;
            }
            Py_DECREF(value);
        }
    }

    /* success */
    res = dict;
    dict = NULL;

exit:
    PQconninfoFree(options);    /* safe on null */
    Py_XDECREF(dict);
    Py_XDECREF(dsn);

    return res;
}
Ejemplo n.º 8
0
static PyObject *
psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs)
{
#if PG_VERSION_NUM >= 90000
    PyObject *ident = NULL, *obj = NULL, *result = NULL;
    connectionObject *conn;
    const char *str;
    char *quoted = NULL;

    static char *kwlist[] = {"ident", "scope", NULL};
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &ident, &obj)) {
        return NULL;
    }

    if (PyObject_TypeCheck(obj, &cursorType)) {
        conn = ((cursorObject*)obj)->conn;
    }
    else if (PyObject_TypeCheck(obj, &connectionType)) {
        conn = (connectionObject*)obj;
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "argument 2 must be a connection or a cursor");
        return NULL;
    }

    Py_INCREF(ident); /* for ensure_bytes */
    if (!(ident = psycopg_ensure_bytes(ident))) { goto exit; }

    str = Bytes_AS_STRING(ident);

    quoted = PQescapeIdentifier(conn->pgconn, str, strlen(str));
    if (!quoted) {
        PyErr_NoMemory();
        goto exit;
    }
    result = conn_text_from_chars(conn, quoted);

exit:
    PQfreemem(quoted);
    Py_XDECREF(ident);

    return result;
#else
    PyErr_SetString(NotSupportedError, "PQescapeIdentifier not available in libpq < 9.0");
    return NULL;
#endif
}
Ejemplo n.º 9
0
RAISES_NEG static int
obscure_password(connectionObject *conn)
{
    PQconninfoOption *options;
    PyObject *d = NULL, *v = NULL, *dsn = NULL;
    char *tmp;
    int rv = -1;

    if (!conn || !conn->dsn) {
        return 0;
    }

    if (!(options = PQconninfoParse(conn->dsn, NULL))) {
        /* unlikely: the dsn was already tested valid */
        return 0;
    }

    if (!(d = psycopg_dict_from_conninfo_options(
            options, /* include_password = */ 1))) {
        goto exit;
    }
    if (NULL == PyDict_GetItemString(d, "password")) {
        /* the dsn doesn't have a password */
        rv = 0;
        goto exit;
    }

    /* scrub the password and put back the connection string together */
    if (!(v = Text_FromUTF8("xxx"))) { goto exit; }
    if (0 > PyDict_SetItemString(d, "password", v)) { goto exit; }
    if (!(dsn = psycopg_make_dsn(Py_None, d))) { goto exit; }
    if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; }

    /* Replace the connection string on the connection object */
    tmp = conn->dsn;
    psycopg_strdup(&conn->dsn, Bytes_AS_STRING(dsn), -1);
    PyMem_Free(tmp);

    rv = 0;

exit:
    PQconninfoFree(options);
    Py_XDECREF(v);
    Py_XDECREF(d);
    Py_XDECREF(dsn);

    return rv;
}
Ejemplo n.º 10
0
static PyObject *
pfloat_getquoted(pfloatObject *self, PyObject *args)
{
    PyObject *rv;
    double n = PyFloat_AsDouble(self->wrapped);
    if (isnan(n))
        rv = Bytes_FromString("'NaN'::float");
    else if (isinf(n)) {
        if (n > 0)
            rv = Bytes_FromString("'Infinity'::float");
        else
            rv = Bytes_FromString("'-Infinity'::float");
    }
    else {
        if (!(rv = PyObject_Repr(self->wrapped))) {
            goto exit;
        }

#if PY_MAJOR_VERSION > 2
        /* unicode to bytes in Py3 */
        {
            PyObject *tmp = PyUnicode_AsUTF8String(rv);
            Py_DECREF(rv);
            if (!(rv = tmp)) {
                goto exit;
            }
        }
#endif

        if ('-' == Bytes_AS_STRING(rv)[0]) {
            /* Prepend a space in front of negative numbers (ticket #57) */
            PyObject *tmp;
            if (!(tmp = Bytes_FromString(" "))) {
                Py_DECREF(rv);
                rv = NULL;
                goto exit;
            }
            Bytes_ConcatAndDel(&tmp, rv);
            if (!(rv = tmp)) {
                goto exit;
            }
        }
    }

exit:
    return rv;
}
Ejemplo n.º 11
0
static PyObject *
typecast_repr(PyObject *self)
{
    PyObject *name = ((typecastObject *)self)->name;
    PyObject *rv;

    Py_INCREF(name);
    if (!(name = psycopg_ensure_bytes(name))) {
        return NULL;
    }

    rv = PyString_FromFormat("<%s '%s' at %p>",
        Py_TYPE(self)->tp_name, Bytes_AS_STRING(name), self);

    Py_DECREF(name);
    return rv;
}
Ejemplo n.º 12
0
static int
_pyobj_read_threaded (SDL_RWops *ops, void* ptr, int size, int num)
{
    _RWWrapper *wrapper = (_RWWrapper *) ops->hidden.unknown.data1;
    PyObject *result;
    int retval;
    PyThreadState* oldstate;
    
    if (!wrapper->read)
        return -1;
    
    PyEval_AcquireThread (wrapper->thread);
    oldstate = PyThreadState_Swap (wrapper->thread);
        
    result = PyObject_CallFunction (wrapper->read, "i", size * num);
    if (!result)
    {
        PyErr_Print ();
        retval = -1;
        goto end;
    }
    
    if (!Bytes_Check (result))
    {
        Py_DECREF (result);
        PyErr_Print ();
        retval = -1;
        goto end;
    }
    
    retval = Bytes_GET_SIZE (result);
    memcpy (ptr, Bytes_AS_STRING (result), (size_t) retval);
    retval /= size;
    
    Py_DECREF (result);

end:
    PyThreadState_Swap (oldstate);
    PyEval_ReleaseThread (wrapper->thread);
    return retval;
}
Ejemplo n.º 13
0
static PyObject *
psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs)
{
    PyObject *ident = NULL, *obj = NULL, *result = NULL;
    connectionObject *conn;
    char *quoted = NULL;

    static char *kwlist[] = {"ident", "scope", NULL};
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &ident, &obj)) {
        return NULL;
    }

    if (PyObject_TypeCheck(obj, &cursorType)) {
        conn = ((cursorObject*)obj)->conn;
    }
    else if (PyObject_TypeCheck(obj, &connectionType)) {
        conn = (connectionObject*)obj;
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "argument 2 must be a connection or a cursor");
        return NULL;
    }

    Py_INCREF(ident); /* for ensure_bytes */
    if (!(ident = psycopg_ensure_bytes(ident))) { goto exit; }

    if (!(quoted = psycopg_escape_identifier(conn,
        Bytes_AS_STRING(ident), Bytes_GET_SIZE(ident)))) { goto exit; }

    result = conn_text_from_chars(conn, quoted);

exit:
    PQfreemem(quoted);
    Py_XDECREF(ident);

    return result;
}
Ejemplo n.º 14
0
static int
_pyobj_read (SDL_RWops *ops, void* ptr, int size, int num)
{
    _RWWrapper *wrapper = (_RWWrapper *) ops->hidden.unknown.data1;
    PyObject *result;
    int retval;
    
    if (!wrapper->read)
        return -1;
    result = PyObject_CallFunction (wrapper->read, "i", size * num);
    if (!result)
        return -1;
    if (!Bytes_Check (result))
    {
        Py_DECREF (result);
        return -1;
    }
    retval = Bytes_GET_SIZE (result);
    memcpy (ptr, Bytes_AS_STRING (result), (size_t) retval);
    retval /= size;
    
    Py_DECREF (result);
    return retval;
}
Ejemplo n.º 15
0
static int
_view_kind(PyObject *obj, void *view_kind_vptr)
{
    unsigned long ch;
    _pc_view_kind_t *view_kind_ptr = (_pc_view_kind_t *)view_kind_vptr;

    if (PyUnicode_Check(obj)) {
        if (PyUnicode_GET_SIZE(obj) != 1) {
            PyErr_SetString(PyExc_TypeError,
                            "expected a length 1 string for argument 3");
            return 0;
        }
        ch = *PyUnicode_AS_UNICODE(obj);
    }
    else if (Bytes_Check(obj)) {
        if (Bytes_GET_SIZE(obj) != 1) {
            PyErr_SetString(PyExc_TypeError,
                            "expected a length 1 string for argument 3");
            return 0;
        }
        ch = *Bytes_AS_STRING(obj);
    }
    else {
        PyErr_Format(PyExc_TypeError,
                     "expected a length one string for argument 3: got '%s'",
                     Py_TYPE(obj)->tp_name);
        return 0;
    }
    switch (ch) {

    case 'R':
    case 'r':
        *view_kind_ptr = VIEWKIND_RED;
        break;
    case 'G':
    case 'g':
        *view_kind_ptr = VIEWKIND_GREEN;
        break;
    case 'B':
    case 'b':
        *view_kind_ptr = VIEWKIND_BLUE;
        break;
    case 'A':
    case 'a':
        *view_kind_ptr = VIEWKIND_ALPHA;
        break;
    case 'C':
    case 'c':
        *view_kind_ptr = VIEWKIND_COLORKEY;
        break;
    case 'P':
    case 'p':
        *view_kind_ptr = VIEWKIND_RGB;
        break;
    default:
        PyErr_Format(PyExc_TypeError,
                     "unrecognized view kind '%c' for argument 3", (int)ch);
        return 0;
    }
    return 1;
}
Ejemplo n.º 16
0
static int
CPyStreamWrapper_Read (CPyStreamWrapper *wrapper, void *buf, pguint32 offset,
    pguint32 count, pguint32 *read_)
{
    PyObject *result;
    pguint32 off, _read = 0;
    int retval = 1;
    char *tmp;
    char *ptr = (char*) buf;

    if (!wrapper->read || !wrapper->seek || !read_)
        return 0;

    if (offset != 0)
    {
        /* Move to the correct offset. */
        result = PyObject_CallFunction (wrapper->seek, "li", offset, SEEK_SET);
        if (!result)
        {
            PyErr_Print();
            retval = 0;
            goto end;
        }
        Py_DECREF (result);
    }
    if (count == 0)
    {
        /* Just a seek was wanted */
        goto end;
    }

    result = PyObject_CallFunction (wrapper->read, "l", count);
    if (!result)
    {
        PyErr_Print ();
        retval = 0;
        goto end;
    }
    
    if (!Bytes_Check (result))
    {
        Py_DECREF (result);
        PyErr_Print ();
        retval = 0;
        goto end;
    }
    
    _read = (pguint32) Bytes_GET_SIZE (result);
    tmp = Bytes_AS_STRING (result);

    off = 0;
    while ((_read - off) > SIZE_MAX)
    {
        memcpy (ptr + off, tmp + off, SIZE_MAX);
        off += SIZE_MAX;
    }
    memcpy (ptr + off, tmp + off, (size_t) (_read - off));
    Py_DECREF (result);

end:
    *read_ = _read;
    return retval;
}
Ejemplo n.º 17
0
PyObject *_PGFT_Render_PixelArray(FreeTypeInstance *ft, PgFontObject *fontobj,
                                  const FontRenderMode *mode,
                                  PGFT_String *text, int invert,
                                  int *_width, int *_height)
{
    FT_Byte *buffer = 0;
    PyObject *array = 0;
    FontSurface surf;

    Layout *font_text;
    unsigned width;
    unsigned height;
    FT_Vector offset;
    FT_Pos underline_top;
    FT_Fixed underline_size;
    int array_size;

    /* build font text */
    font_text = _PGFT_LoadLayout(ft, fontobj, mode, text);
    if (!font_text) {
        return 0;
    }

    if (font_text->length == 0) {
        /* Nothing to render */
        *_width = 0;
        *_height = _PGFT_Font_GetHeight(ft, fontobj);
        return Bytes_FromStringAndSize("", 0);
    }

    _PGFT_GetRenderMetrics(mode, font_text, &width, &height, &offset,
                           &underline_top, &underline_size);

    array_size = width * height;
    if (array_size == 0) {
        /* Empty array */
        *_width = 0;
        *_height = height;
        return Bytes_FromStringAndSize("", 0);
    }

    /* Create an uninitialized string whose buffer can be directly set. */
    array = Bytes_FromStringAndSize(0, array_size);
    if (!array) {
        return 0;
    }
    buffer = (FT_Byte *)Bytes_AS_STRING(array);
    if (invert) {
        memset(buffer, SDL_ALPHA_OPAQUE, (size_t)array_size);
    }
    else {
        memset(buffer, SDL_ALPHA_TRANSPARENT, (size_t)array_size);
    }
    surf.buffer = buffer;
    surf.width = width;
    surf.height = height;
    surf.pitch = (int)surf.width;
    surf.format = 0;
    surf.render_gray = __render_glyph_GRAY1;
    surf.render_mono = __render_glyph_MONO_as_GRAY1;
    surf.fill = __fill_glyph_GRAY1;

    render(ft, font_text, mode, invert ? &mono_transparent : &mono_opaque,
           &surf, width, height, &offset, underline_top, underline_size);

    *_width = width;
    *_height = height;

    return array;
}
Ejemplo n.º 18
0
static PyObject *
psyco_encrypt_password(PyObject *self, PyObject *args, PyObject *kwargs)
{
    char *encrypted = NULL;
    PyObject *password = NULL, *user = NULL;
    PyObject *scope = Py_None, *algorithm = Py_None;
    PyObject *res = NULL;
    connectionObject *conn = NULL;

    static char *kwlist[] = {"password", "user", "scope", "algorithm", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|OO", kwlist,
            &password, &user, &scope, &algorithm)) {
        return NULL;
    }

    /* for ensure_bytes */
    Py_INCREF(user);
    Py_INCREF(password);
    Py_INCREF(algorithm);

    if (scope != Py_None) {
        if (PyObject_TypeCheck(scope, &cursorType)) {
            conn = ((cursorObject*)scope)->conn;
        }
        else if (PyObject_TypeCheck(scope, &connectionType)) {
            conn = (connectionObject*)scope;
        }
        else {
            PyErr_SetString(PyExc_TypeError,
                "the scope must be a connection or a cursor");
            goto exit;
        }
    }

    if (!(user = psycopg_ensure_bytes(user))) { goto exit; }
    if (!(password = psycopg_ensure_bytes(password))) { goto exit; }
    if (algorithm != Py_None) {
        if (!(algorithm = psycopg_ensure_bytes(algorithm))) {
            goto exit;
        }
    }

    /* If we have to encrypt md5 we can use the libpq < 10 API */
    if (algorithm != Py_None &&
            strcmp(Bytes_AS_STRING(algorithm), "md5") == 0) {
        encrypted = PQencryptPassword(
            Bytes_AS_STRING(password), Bytes_AS_STRING(user));
    }

    /* If the algorithm is not md5 we have to use the API available from
     * libpq 10. */
    else {
#if PG_VERSION_NUM >= 100000
        if (!conn) {
            PyErr_SetString(ProgrammingError,
                "password encryption (other than 'md5' algorithm)"
                " requires a connection or cursor");
            goto exit;
        }

        /* TODO: algo = None will block: forbid on async/green conn? */
        encrypted = PQencryptPasswordConn(conn->pgconn,
            Bytes_AS_STRING(password), Bytes_AS_STRING(user),
            algorithm != Py_None ? Bytes_AS_STRING(algorithm) : NULL);
#else
        PyErr_SetString(NotSupportedError,
            "password encryption (other than 'md5' algorithm)"
            " requires libpq 10");
        goto exit;
#endif
    }

    if (encrypted) {
        res = Text_FromUTF8(encrypted);
    }
    else {
        const char *msg = PQerrorMessage(conn->pgconn);
        PyErr_Format(ProgrammingError,
            "password encryption failed: %s", msg ? msg : "no reason given");
        goto exit;
    }

exit:
    if (encrypted) {
        PQfreemem(encrypted);
    }
    Py_XDECREF(user);
    Py_XDECREF(password);
    Py_XDECREF(algorithm);

    return res;
}
Ejemplo n.º 19
0
PyObject *
Bytes_Format(PyObject *format, PyObject *args)
{
    char *fmt, *res;
    Py_ssize_t arglen, argidx;
    Py_ssize_t reslen, rescnt, fmtcnt;
    int args_owned = 0;
    PyObject *result;
    PyObject *dict = NULL;
    if (format == NULL || !Bytes_Check(format) || args == NULL) {
        PyErr_BadInternalCall();
        return NULL;
    }
    fmt = Bytes_AS_STRING(format);
    fmtcnt = Bytes_GET_SIZE(format);
    reslen = rescnt = fmtcnt + 100;
    result = Bytes_FromStringAndSize((char *)NULL, reslen);
    if (result == NULL)
        return NULL;
    res = Bytes_AsString(result);
    if (PyTuple_Check(args)) {
        arglen = PyTuple_GET_SIZE(args);
        argidx = 0;
    }
    else {
        arglen = -1;
        argidx = -2;
    }
    if (Py_TYPE(args)->tp_as_mapping && !PyTuple_Check(args) &&
        !PyObject_TypeCheck(args, &Bytes_Type))
        dict = args;
    while (--fmtcnt >= 0) {
        if (*fmt != '%') {
            if (--rescnt < 0) {
                rescnt = fmtcnt + 100;
                reslen += rescnt;
                if (_Bytes_Resize(&result, reslen))
                    return NULL;
                res = Bytes_AS_STRING(result)
                    + reslen - rescnt;
                --rescnt;
            }
            *res++ = *fmt++;
        }
        else {
            /* Got a format specifier */
            Py_ssize_t width = -1;
            int c = '\0';
            PyObject *v = NULL;
            PyObject *temp = NULL;
            char *pbuf;
            Py_ssize_t len;
            fmt++;
            if (*fmt == '(') {
                char *keystart;
                Py_ssize_t keylen;
                PyObject *key;
                int pcount = 1;

                if (dict == NULL) {
                    PyErr_SetString(PyExc_TypeError,
                             "format requires a mapping");
                    goto error;
                }
                ++fmt;
                --fmtcnt;
                keystart = fmt;
                /* Skip over balanced parentheses */
                while (pcount > 0 && --fmtcnt >= 0) {
                    if (*fmt == ')')
                        --pcount;
                    else if (*fmt == '(')
                        ++pcount;
                    fmt++;
                }
                keylen = fmt - keystart - 1;
                if (fmtcnt < 0 || pcount > 0) {
                    PyErr_SetString(PyExc_ValueError,
                               "incomplete format key");
                    goto error;
                }
                key = Text_FromUTF8AndSize(keystart, keylen);
                if (key == NULL)
                    goto error;
                if (args_owned) {
                    Py_DECREF(args);
                    args_owned = 0;
                }
                args = PyObject_GetItem(dict, key);
                Py_DECREF(key);
                if (args == NULL) {
                    goto error;
                }
                args_owned = 1;
                arglen = -1;
                argidx = -2;
            }
            while (--fmtcnt >= 0) {
                c = *fmt++;
                break;
            }
            if (fmtcnt < 0) {
                PyErr_SetString(PyExc_ValueError,
                                "incomplete format");
                goto error;
            }
            if (c != '%') {
                v = getnextarg(args, arglen, &argidx);
                if (v == NULL)
                    goto error;
            }
            switch (c) {
            case '%':
                pbuf = "%";
                len = 1;
                break;
            case 's':
                /* only bytes! */
                if (!Bytes_CheckExact(v)) {
                    PyErr_Format(PyExc_ValueError,
                                    "only bytes values expected, got %s",
                                    Py_TYPE(v)->tp_name);
                    goto error;
                }
                temp = v;
                Py_INCREF(v);
                pbuf = Bytes_AS_STRING(temp);
                len = Bytes_GET_SIZE(temp);
                break;
            default:
                PyErr_Format(PyExc_ValueError,
                  "unsupported format character '%c' (0x%x) "
                  "at index " FORMAT_CODE_PY_SSIZE_T,
                  c, c,
                  (Py_ssize_t)(fmt - 1 -
                               Bytes_AsString(format)));
                goto error;
            }
            if (width < len)
                width = len;
            if (rescnt < width) {
                reslen -= rescnt;
                rescnt = width + fmtcnt + 100;
                reslen += rescnt;
                if (reslen < 0) {
                    Py_DECREF(result);
                    Py_XDECREF(temp);
                    return PyErr_NoMemory();
                }
                if (_Bytes_Resize(&result, reslen)) {
                    Py_XDECREF(temp);
                    return NULL;
                }
                res = Bytes_AS_STRING(result)
                    + reslen - rescnt;
            }
            Py_MEMCPY(res, pbuf, len);
            res += len;
            rescnt -= len;
            while (--width >= len) {
                --rescnt;
                *res++ = ' ';
            }
            if (dict && (argidx < arglen) && c != '%') {
                PyErr_SetString(PyExc_TypeError,
                           "not all arguments converted during string formatting");
                Py_XDECREF(temp);
                goto error;
            }
            Py_XDECREF(temp);
        } /* '%' */
    } /* until end */
    if (argidx < arglen && !dict) {
        PyErr_SetString(PyExc_TypeError,
                        "not all arguments converted during string formatting");
        goto error;
    }
    if (args_owned) {
        Py_DECREF(args);
    }
    if (_Bytes_Resize(&result, reslen - rescnt))
        return NULL;
    return result;

 error:
    Py_DECREF(result);
    if (args_owned) {
        Py_DECREF(args);
    }
    return NULL;
}