diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2019-09-04 12:27:16 +0100 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2019-09-04 12:30:18 +0100 |
commit | 80df0553a6450df25fa96ee4dbb6acf63efb8ffc (patch) | |
tree | f6eed1aea6492155cbc2a33e8c164b42f1780290 /psycopg | |
parent | 4d10f1235fed1c0aa5958cc4a9248688c3345aad (diff) | |
download | psycopg2-80df0553a6450df25fa96ee4dbb6acf63efb8ffc.tar.gz |
Fixed handling large Oid valuesfix-961
Oid is defined as unsigned 32. On some Python implementations (probably
the ones where maxint = 2 ** 31) this can cause int overflow for large
values (see #961). On my 64 box it doesn't seem the case.
Oid handling was sloppy here and there (messages, casts...): trying to
use uint everywhere, and added a couple of helper macros to treat Oid
consistently.
Close #961.
Diffstat (limited to 'psycopg')
-rw-r--r-- | psycopg/connection_type.c | 2 | ||||
-rw-r--r-- | psycopg/cursor_type.c | 2 | ||||
-rw-r--r-- | psycopg/lobject_int.c | 2 | ||||
-rw-r--r-- | psycopg/lobject_type.c | 4 | ||||
-rw-r--r-- | psycopg/pqpath.c | 12 | ||||
-rw-r--r-- | psycopg/python.h | 10 |
6 files changed, 21 insertions, 11 deletions
diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index b94dd8b..bc88d78 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -968,7 +968,7 @@ psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds) Dprintf("psyco_conn_lobject: new lobject for connection at %p", self); Dprintf("psyco_conn_lobject: parameters: oid = %u, mode = %s", oid, smode); - Dprintf("psyco_conn_lobject: parameters: new_oid = %d, new_file = %s", + Dprintf("psyco_conn_lobject: parameters: new_oid = %u, new_file = %s", new_oid, new_file); if (new_file) diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index 99486a1..b5c08dc 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -1827,7 +1827,7 @@ static struct PyMemberDef cursorObject_members[] = { "Number of records ``iter(cur)`` must fetch per network roundtrip."}, {"description", T_OBJECT, OFFSETOF(description), READONLY, "Cursor description as defined in DBAPI-2.0."}, - {"lastrowid", T_LONG, OFFSETOF(lastoid), READONLY, + {"lastrowid", T_OID, OFFSETOF(lastoid), READONLY, "The ``oid`` of the last row inserted by the cursor."}, /* DBAPI-2.0 extensions */ {"rownumber", T_LONG, OFFSETOF(row), READONLY, diff --git a/psycopg/lobject_int.c b/psycopg/lobject_int.c index a14faef..973f163 100644 --- a/psycopg/lobject_int.c +++ b/psycopg/lobject_int.c @@ -176,7 +176,7 @@ lobject_open(lobjectObject *self, connectionObject *conn, self->oid = lo_creat(self->conn->pgconn, INV_READ | INV_WRITE); } - Dprintf("lobject_open: large object created with oid = %d", + Dprintf("lobject_open: large object created with oid = %u", self->oid); if (self->oid == InvalidOid) { diff --git a/psycopg/lobject_type.c b/psycopg/lobject_type.c index 568e533..e84de82 100644 --- a/psycopg/lobject_type.c +++ b/psycopg/lobject_type.c @@ -327,7 +327,7 @@ static struct PyMethodDef lobjectObject_methods[] = { /* object member list */ static struct PyMemberDef lobjectObject_members[] = { - {"oid", T_UINT, offsetof(lobjectObject, oid), READONLY, + {"oid", T_OID, offsetof(lobjectObject, oid), READONLY, "The backend OID associated to this lobject."}, {"mode", T_STRING, offsetof(lobjectObject, smode), READONLY, "Open mode."}, @@ -368,7 +368,7 @@ lobject_setup(lobjectObject *self, connectionObject *conn, Dprintf("lobject_setup: good lobject object at %p, refcnt = " FORMAT_CODE_PY_SSIZE_T, self, Py_REFCNT(self)); - Dprintf("lobject_setup: oid = %d, fd = %d", self->oid, self->fd); + Dprintf("lobject_setup: oid = %u, fd = %d", self->oid, self->fd); return 0; } diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index b21f397..414c2d7 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -995,9 +995,9 @@ _get_cast(cursorObject *curs, PGresult *pgres, int i) PyObject *rv = NULL; Oid ftype = PQftype(pgres, i); - if (!(type = PyInt_FromLong(ftype))) { goto exit; } + if (!(type = PyLong_FromOid(ftype))) { goto exit; } - Dprintf("_pq_fetch_tuples: looking for cast %d:", ftype); + Dprintf("_pq_fetch_tuples: looking for cast %u:", ftype); if (!(cast = curs_get_cast(curs, type))) { goto exit; } /* else if we got binary tuples and if we got a field that @@ -1006,11 +1006,11 @@ _get_cast(cursorObject *curs, PGresult *pgres, int i) */ if (cast == psyco_default_binary_cast && PQbinaryTuples(pgres)) { Dprintf("_pq_fetch_tuples: Binary cursor and " - "binary field: %i using default cast", ftype); + "binary field: %u using default cast", ftype); cast = psyco_default_cast; } - Dprintf("_pq_fetch_tuples: using cast at %p for type %d", cast, ftype); + Dprintf("_pq_fetch_tuples: using cast at %p for type %u", cast, ftype); /* success */ Py_INCREF(cast); @@ -1041,7 +1041,7 @@ _make_column(connectionObject *conn, PGresult *pgres, int i) /* fill the type and name fields */ { PyObject *tmp; - if (!(tmp = PyInt_FromLong(ftype))) { + if (!(tmp = PyLong_FromOid(ftype))) { goto exit; } column->type_code = tmp; @@ -1099,7 +1099,7 @@ _make_column(connectionObject *conn, PGresult *pgres, int i) /* table_oid, table_column */ if (ftable != InvalidOid) { PyObject *tmp; - if (!(tmp = PyInt_FromLong((long)ftable))) { goto exit; } + if (!(tmp = PyLong_FromOid(ftable))) { goto exit; } column->table_oid = tmp; } diff --git a/psycopg/python.h b/psycopg/python.h index 521c568..f45aeb5 100644 --- a/psycopg/python.h +++ b/psycopg/python.h @@ -91,6 +91,11 @@ typedef unsigned long Py_uhash_t; #define INIT_MODULE(m) init ## m +/* fix #961, but don't change all types to longs. Sure someone will complain. */ +#define PyLong_FromOid(x) (((x) & 0x80000000) ? \ + PyLong_FromUnsignedLong((unsigned long)(x)) : \ + PyInt_FromLong((x))) + #endif /* PY_2 */ #if PY_3 @@ -133,6 +138,11 @@ typedef unsigned long Py_uhash_t; #define INIT_MODULE(m) PyInit_ ## m +#define PyLong_FromOid(x) (PyLong_FromUnsignedLong((unsigned long)(x))) + #endif /* PY_3 */ +/* expose Oid attributes in Python C objects */ +#define T_OID T_UINT + #endif /* !defined(PSYCOPG_PYTHON_H) */ |