Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Lib/sqlite3/test/userfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import unittest
import unittest.mock
import gc
import sqlite3 as sqlite

def func_returntext():
Expand Down Expand Up @@ -322,6 +323,22 @@ def test_func_deterministic_keyword_only(self):
with self.assertRaises(TypeError):
self.con.create_function("deterministic", 0, int, True)

def test_function_destructor_via_gc(self):
# See bpo-44304: The destructor of the user function can
# crash if is called without the GIL from the gc functions
dest = sqlite.connect(':memory:')
def md5sum(t):
return

dest.create_function("md5", 1, md5sum)
x = dest("create table lang (name, first_appeared)")
del md5sum, dest

y = [x]
y.append(y)

del x,y
gc.collect()

class AggregateTests(unittest.TestCase):
def setUp(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a crash in the :mod:`sqlite3` module that happened when the garbage
collector clears :class:`sqlite.Statement` objects. Patch by Pablo Galindo
11 changes: 4 additions & 7 deletions Modules/_sqlite/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ stmt_dealloc(pysqlite_Statement *self)
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*)self);
}
if (self->st) {
sqlite3_finalize(self->st);
self->st = 0;
}
tp->tp_clear((PyObject *)self);
tp->tp_free(self);
Py_DECREF(tp);
Expand All @@ -405,13 +409,6 @@ stmt_dealloc(pysqlite_Statement *self)
static int
stmt_clear(pysqlite_Statement *self)
{
if (self->st) {
Py_BEGIN_ALLOW_THREADS
sqlite3_finalize(self->st);
Py_END_ALLOW_THREADS
self->st = 0;
}

Py_CLEAR(self->sql);
return 0;
}
Expand Down