]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111178: fix UBSan failures in `Modules/_sqlite` (GH-129087)
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>
Fri, 31 Jan 2025 13:33:30 +0000 (14:33 +0100)
committerGitHub <noreply@github.com>
Fri, 31 Jan 2025 13:33:30 +0000 (14:33 +0100)
* fix UBSan failures for `pysqlite_Blob`
* fix UBSan failures for `pysqlite_Connection`
* fix UBSan failures for `pysqlite_Cursor`
* fix UBSan failures for `pysqlite_PrepareProtocol`
* fix UBSan failures for `pysqlite_Row`
* fix UBSan failures for `pysqlite_Statement`

* suppress unused return values

Modules/_sqlite/blob.c
Modules/_sqlite/connection.c
Modules/_sqlite/cursor.c
Modules/_sqlite/module.c
Modules/_sqlite/prepare_protocol.c
Modules/_sqlite/row.c
Modules/_sqlite/statement.c

index d1a549a971c24a233a8df1d90565fd9009fe7648..390375628bfb4f6d23c403c55fb812cdb71eb5fb 100644 (file)
@@ -9,6 +9,8 @@
 #include "clinic/blob.c.h"
 #undef clinic_state
 
+#define _pysqlite_Blob_CAST(op) ((pysqlite_Blob *)(op))
+
 /*[clinic input]
 module _sqlite3
 class _sqlite3.Blob "pysqlite_Blob *" "clinic_state()->BlobType"
@@ -29,32 +31,35 @@ close_blob(pysqlite_Blob *self)
 }
 
 static int
-blob_traverse(pysqlite_Blob *self, visitproc visit, void *arg)
+blob_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    pysqlite_Blob *self = _pysqlite_Blob_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->connection);
     return 0;
 }
 
 static int
-blob_clear(pysqlite_Blob *self)
+blob_clear(PyObject *op)
 {
+    pysqlite_Blob *self = _pysqlite_Blob_CAST(op);
     Py_CLEAR(self->connection);
     return 0;
 }
 
 static void
-blob_dealloc(pysqlite_Blob *self)
+blob_dealloc(PyObject *op)
 {
+    pysqlite_Blob *self = _pysqlite_Blob_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
 
     close_blob(self);
 
     if (self->in_weakreflist != NULL) {
-        PyObject_ClearWeakRefs((PyObject*)self);
+        PyObject_ClearWeakRefs(op);
     }
-    tp->tp_clear((PyObject *)self);
+    (void)tp->tp_clear(op);
     tp->tp_free(self);
     Py_DECREF(tp);
 }
@@ -373,8 +378,9 @@ blob_exit_impl(pysqlite_Blob *self, PyObject *type, PyObject *val,
 }
 
 static Py_ssize_t
-blob_length(pysqlite_Blob *self)
+blob_length(PyObject *op)
 {
+    pysqlite_Blob *self = _pysqlite_Blob_CAST(op);
     if (!check_blob(self)) {
         return -1;
     }
@@ -449,8 +455,9 @@ subscript_slice(pysqlite_Blob *self, PyObject *item)
 }
 
 static PyObject *
-blob_subscript(pysqlite_Blob *self, PyObject *item)
+blob_subscript(PyObject *op, PyObject *item)
 {
+    pysqlite_Blob *self = _pysqlite_Blob_CAST(op);
     if (!check_blob(self)) {
         return NULL;
     }
@@ -546,8 +553,9 @@ ass_subscript_slice(pysqlite_Blob *self, PyObject *item, PyObject *value)
 }
 
 static int
-blob_ass_subscript(pysqlite_Blob *self, PyObject *item, PyObject *value)
+blob_ass_subscript(PyObject *op, PyObject *item, PyObject *value)
 {
+    pysqlite_Blob *self = _pysqlite_Blob_CAST(op);
     if (!check_blob(self)) {
         return -1;
     }
index 0c98f5065ee303064bbcb2724bcdd2021a78b48e..80021ccad4629eeda4ddda23cbb262acc4e3887f 100644 (file)
@@ -135,6 +135,8 @@ sqlite3_int64_converter(PyObject *obj, sqlite3_int64 *result)
 #include "clinic/connection.c.h"
 #undef clinic_state
 
+#define _pysqlite_Connection_CAST(op)   ((pysqlite_Connection *)(op))
+
 /*[clinic input]
 module _sqlite3
 class _sqlite3.Connection "pysqlite_Connection *" "clinic_state()->ConnectionType"
@@ -384,8 +386,9 @@ do {                                \
 } while (0)
 
 static int
-connection_traverse(pysqlite_Connection *self, visitproc visit, void *arg)
+connection_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->statement_cache);
     Py_VISIT(self->cursors);
@@ -409,8 +412,9 @@ clear_callback_context(callback_context *ctx)
 }
 
 static int
-connection_clear(pysqlite_Connection *self)
+connection_clear(PyObject *op)
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     Py_CLEAR(self->statement_cache);
     Py_CLEAR(self->cursors);
     Py_CLEAR(self->blobs);
@@ -517,7 +521,7 @@ connection_dealloc(PyObject *self)
     }
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
-    tp->tp_clear(self);
+    (void)tp->tp_clear(self);
     tp->tp_free(self);
     Py_DECREF(tp);
 }
@@ -1715,8 +1719,10 @@ int pysqlite_check_thread(pysqlite_Connection* self)
     return 1;
 }
 
-static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* self, void* unused)
+static PyObject *
+pysqlite_connection_get_isolation_level(PyObject *op, void *Py_UNUSED(closure))
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     if (!pysqlite_check_connection(self)) {
         return NULL;
     }
@@ -1726,16 +1732,20 @@ static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* se
     Py_RETURN_NONE;
 }
 
-static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self, void* unused)
+static PyObject *
+pysqlite_connection_get_total_changes(PyObject *op, void *Py_UNUSED(closure))
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     if (!pysqlite_check_connection(self)) {
         return NULL;
     }
     return PyLong_FromLong(sqlite3_total_changes(self->db));
 }
 
-static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused)
+static PyObject *
+pysqlite_connection_get_in_transaction(PyObject *op, void *Py_UNUSED(closure))
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     if (!pysqlite_check_connection(self)) {
         return NULL;
     }
@@ -1746,8 +1756,11 @@ static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* sel
 }
 
 static int
-pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored))
+pysqlite_connection_set_isolation_level(PyObject *op,
+                                        PyObject *isolation_level,
+                                        void *Py_UNUSED(ignored))
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     if (isolation_level == NULL) {
         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
         return -1;
@@ -1770,11 +1783,11 @@ pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* iso
 }
 
 static PyObject *
-pysqlite_connection_call(pysqlite_Connection *self, PyObject *args,
-                         PyObject *kwargs)
+pysqlite_connection_call(PyObject *op, PyObject *args, PyObject *kwargs)
 {
     PyObject* sql;
     pysqlite_Statement* statement;
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
 
     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
         return NULL;
@@ -2525,8 +2538,9 @@ getconfig_impl(pysqlite_Connection *self, int op)
 }
 
 static PyObject *
-get_autocommit(pysqlite_Connection *self, void *Py_UNUSED(ctx))
+get_autocommit(PyObject *op, void *Py_UNUSED(closure))
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
         return NULL;
     }
@@ -2540,8 +2554,9 @@ get_autocommit(pysqlite_Connection *self, void *Py_UNUSED(ctx))
 }
 
 static int
-set_autocommit(pysqlite_Connection *self, PyObject *val, void *Py_UNUSED(ctx))
+set_autocommit(PyObject *op, PyObject *val, void *Py_UNUSED(closure))
 {
+    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
         return -1;
     }
@@ -2566,7 +2581,7 @@ set_autocommit(pysqlite_Connection *self, PyObject *val, void *Py_UNUSED(ctx))
 }
 
 static PyObject *
-get_sig(PyObject *self, void *Py_UNUSED(ctx))
+get_sig(PyObject *Py_UNUSED(self), void *Py_UNUSED(closure))
 {
     return PyUnicode_FromString("(sql, /)");
 }
@@ -2576,11 +2591,12 @@ static const char connection_doc[] =
 PyDoc_STR("SQLite database connection object.");
 
 static PyGetSetDef connection_getset[] = {
-    {"isolation_level",  (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level},
-    {"total_changes",  (getter)pysqlite_connection_get_total_changes, (setter)0},
-    {"in_transaction",  (getter)pysqlite_connection_get_in_transaction, (setter)0},
-    {"autocommit",  (getter)get_autocommit, (setter)set_autocommit},
-    {"__text_signature__", get_sig, (setter)0},
+    {"isolation_level", pysqlite_connection_get_isolation_level,
+     pysqlite_connection_set_isolation_level},
+    {"total_changes",  pysqlite_connection_get_total_changes, NULL},
+    {"in_transaction", pysqlite_connection_get_in_transaction, NULL},
+    {"autocommit",  get_autocommit, set_autocommit},
+    {"__text_signature__", get_sig, NULL},
     {NULL}
 };
 
index 24e97fcf1897e9c6952931d93d5084ea35941049..02d598040775b04605e9c7c4062f7bebb4a8cfac 100644 (file)
@@ -44,6 +44,8 @@ typedef enum {
 #include "clinic/cursor.c.h"
 #undef clinic_state
 
+#define _pysqlite_Cursor_CAST(op)   ((pysqlite_Cursor *)(op))
+
 static inline int
 check_cursor_locked(pysqlite_Cursor *cur)
 {
@@ -146,8 +148,9 @@ stmt_reset(pysqlite_Statement *self)
 }
 
 static int
-cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg)
+cursor_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    pysqlite_Cursor *self = _pysqlite_Cursor_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->connection);
     Py_VISIT(self->description);
@@ -159,8 +162,9 @@ cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg)
 }
 
 static int
-cursor_clear(pysqlite_Cursor *self)
+cursor_clear(PyObject *op)
 {
+    pysqlite_Cursor *self = _pysqlite_Cursor_CAST(op);
     Py_CLEAR(self->connection);
     Py_CLEAR(self->description);
     Py_CLEAR(self->row_cast_map);
@@ -176,14 +180,15 @@ cursor_clear(pysqlite_Cursor *self)
 }
 
 static void
-cursor_dealloc(pysqlite_Cursor *self)
+cursor_dealloc(PyObject *op)
 {
+    pysqlite_Cursor *self = _pysqlite_Cursor_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
     if (self->in_weakreflist != NULL) {
-        PyObject_ClearWeakRefs((PyObject*)self);
+        PyObject_ClearWeakRefs(op);
     }
-    tp->tp_clear((PyObject *)self);
+    (void)tp->tp_clear(op);
     tp->tp_free(self);
     Py_DECREF(tp);
 }
@@ -1087,8 +1092,9 @@ error:
 }
 
 static PyObject *
-pysqlite_cursor_iternext(pysqlite_Cursor *self)
+pysqlite_cursor_iternext(PyObject *op)
 {
+    pysqlite_Cursor *self = _pysqlite_Cursor_CAST(op);
     if (!check_cursor(self)) {
         return NULL;
     }
@@ -1125,7 +1131,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
     }
     if (!Py_IsNone(self->row_factory)) {
         PyObject *factory = self->row_factory;
-        PyObject *args[] = { (PyObject *)self, row, };
+        PyObject *args[] = { op, row, };
         PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL);
         Py_SETREF(row, new_row);
     }
@@ -1144,7 +1150,7 @@ pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self)
 {
     PyObject* row;
 
-    row = pysqlite_cursor_iternext(self);
+    row = pysqlite_cursor_iternext((PyObject *)self);
     if (!row && !PyErr_Occurred()) {
         Py_RETURN_NONE;
     }
@@ -1174,7 +1180,7 @@ pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows)
         return NULL;
     }
 
-    while ((row = pysqlite_cursor_iternext(self))) {
+    while ((row = pysqlite_cursor_iternext((PyObject *)self))) {
         if (PyList_Append(list, row) < 0) {
             Py_DECREF(row);
             break;
@@ -1212,7 +1218,7 @@ pysqlite_cursor_fetchall_impl(pysqlite_Cursor *self)
         return NULL;
     }
 
-    while ((row = pysqlite_cursor_iternext(self))) {
+    while ((row = pysqlite_cursor_iternext((PyObject *)self))) {
         if (PyList_Append(list, row) < 0) {
             Py_DECREF(row);
             break;
index 73d55fb44e2e15634437123acc593b23a1c4beb5..27e8dab92e0e67879a0339919cf4328d91960a49 100644 (file)
@@ -617,7 +617,7 @@ module_clear(PyObject *module)
 static void
 module_free(void *module)
 {
-    module_clear((PyObject *)module);
+    (void)module_clear((PyObject *)module);
 }
 
 #define ADD_TYPE(module, type)                 \
index 44533225665dab5935cf97ce0aec52ae028a9b5c..31092417cb480d2a60e11e19dba79bd13ee2f0d1 100644 (file)
@@ -24,8 +24,7 @@
 #include "prepare_protocol.h"
 
 static int
-pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol *self, PyObject *args,
-                               PyObject *kwargs)
+pysqlite_prepare_protocol_init(PyObject *self, PyObject *args, PyObject *kwargs)
 {
     return 0;
 }
@@ -38,7 +37,7 @@ pysqlite_prepare_protocol_traverse(PyObject *self, visitproc visit, void *arg)
 }
 
 static void
-pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol *self)
+pysqlite_prepare_protocol_dealloc(PyObject *self)
 {
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
index 14555076a7e79a0875687b807602368b17143ebf..79660008b180dc4eb45e085e31b9c4de2407733a 100644 (file)
@@ -32,6 +32,8 @@
 #include "clinic/row.c.h"
 #undef clinic_state
 
+#define _pysqlite_Row_CAST(op)  ((pysqlite_Row *)(op))
+
 /*[clinic input]
 module _sqlite3
 class _sqlite3.Row "pysqlite_Row *" "clinic_state()->RowType"
@@ -39,16 +41,18 @@ class _sqlite3.Row "pysqlite_Row *" "clinic_state()->RowType"
 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=966c53403d7f3a40]*/
 
 static int
-row_clear(pysqlite_Row *self)
+row_clear(PyObject *op)
 {
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
     Py_CLEAR(self->data);
     Py_CLEAR(self->description);
     return 0;
 }
 
 static int
-row_traverse(pysqlite_Row *self, visitproc visit, void *arg)
+row_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->data);
     Py_VISIT(self->description);
@@ -60,7 +64,7 @@ pysqlite_row_dealloc(PyObject *self)
 {
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
-    tp->tp_clear(self);
+    (void)tp->tp_clear(self);
     tp->tp_free(self);
     Py_DECREF(tp);
 }
@@ -94,10 +98,12 @@ pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor,
     return (PyObject *) self;
 }
 
-PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
+static PyObject *
+pysqlite_row_item(PyObject *op, Py_ssize_t idx)
 {
-   PyObject *item = PyTuple_GetItem(self->data, idx);
-   return Py_XNewRef(item);
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
+    PyObject *item = PyTuple_GetItem(self->data, idx);
+    return Py_XNewRef(item);
 }
 
 static int
@@ -129,10 +135,11 @@ equal_ignore_case(PyObject *left, PyObject *right)
 }
 
 static PyObject *
-pysqlite_row_subscript(pysqlite_Row *self, PyObject *idx)
+pysqlite_row_subscript(PyObject *op, PyObject *idx)
 {
     Py_ssize_t _idx;
     Py_ssize_t nitems, i;
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
 
     if (PyLong_Check(idx)) {
         _idx = PyNumber_AsSsize_t(idx, PyExc_IndexError);
@@ -174,8 +181,9 @@ pysqlite_row_subscript(pysqlite_Row *self, PyObject *idx)
 }
 
 static Py_ssize_t
-pysqlite_row_length(pysqlite_Row* self)
+pysqlite_row_length(PyObject *op)
 {
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
     return PyTuple_GET_SIZE(self->data);
 }
 
@@ -208,24 +216,30 @@ pysqlite_row_keys_impl(pysqlite_Row *self)
     return list;
 }
 
-static PyObject* pysqlite_iter(pysqlite_Row* self)
+static PyObject *
+pysqlite_iter(PyObject *op)
 {
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
     return PyObject_GetIter(self->data);
 }
 
-static Py_hash_t pysqlite_row_hash(pysqlite_Row *self)
+static Py_hash_t
+pysqlite_row_hash(PyObject *op)
 {
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
     return PyObject_Hash(self->description) ^ PyObject_Hash(self->data);
 }
 
-static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid)
+static PyObject *
+pysqlite_row_richcompare(PyObject *op, PyObject *opother, int opid)
 {
     if (opid != Py_EQ && opid != Py_NE)
         Py_RETURN_NOTIMPLEMENTED;
 
+    pysqlite_Row *self = _pysqlite_Row_CAST(op);
     pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self));
-    if (PyObject_TypeCheck(_other, state->RowType)) {
-        pysqlite_Row *other = (pysqlite_Row *)_other;
+    if (PyObject_TypeCheck(opother, state->RowType)) {
+        pysqlite_Row *other = (pysqlite_Row *)opother;
         int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
         if (eq < 0) {
             return NULL;
index 229bfc3b5041650113edeee73bc7d08a5afc44c0..facced0dfbfafd7ad9c99c9e0235813e5b68c7db 100644 (file)
@@ -25,6 +25,8 @@
 #include "statement.h"
 #include "util.h"
 
+#define _pysqlite_Statement_CAST(op)    ((pysqlite_Statement *)(op))
+
 /* prototypes */
 static const char *lstrip_sql(const char *sql);
 
@@ -99,10 +101,11 @@ error:
 }
 
 static void
-stmt_dealloc(pysqlite_Statement *self)
+stmt_dealloc(PyObject *op)
 {
+    pysqlite_Statement *self = _pysqlite_Statement_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
-    PyObject_GC_UnTrack(self);
+    PyObject_GC_UnTrack(op);
     if (self->st) {
         Py_BEGIN_ALLOW_THREADS
         sqlite3_finalize(self->st);
@@ -114,7 +117,7 @@ stmt_dealloc(pysqlite_Statement *self)
 }
 
 static int
-stmt_traverse(pysqlite_Statement *self, visitproc visit, void *arg)
+stmt_traverse(PyObject *self, visitproc visit, void *arg)
 {
     Py_VISIT(Py_TYPE(self));
     return 0;