mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-111178: fix UBSan failures in Modules/_sqlite
(GH-129087)
* 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
This commit is contained in:
parent
9d63ae5fe5
commit
881984b41a
7 changed files with 101 additions and 55 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue