summaryrefslogtreecommitdiff
path: root/psycopg
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2019-09-04 12:27:16 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2019-09-04 12:30:18 +0100
commit80df0553a6450df25fa96ee4dbb6acf63efb8ffc (patch)
treef6eed1aea6492155cbc2a33e8c164b42f1780290 /psycopg
parent4d10f1235fed1c0aa5958cc4a9248688c3345aad (diff)
downloadpsycopg2-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.c2
-rw-r--r--psycopg/cursor_type.c2
-rw-r--r--psycopg/lobject_int.c2
-rw-r--r--psycopg/lobject_type.c4
-rw-r--r--psycopg/pqpath.c12
-rw-r--r--psycopg/python.h10
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) */