Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9e38553

Browse files
[3.11] gh-99886: Fix crash when freeing objects with managed dictionaries (#99902)
Co-authored-by: Erlend E. Aasland <[email protected]>
1 parent 27218d0 commit 9e38553

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

Lib/test/test_sqlite3/test_regression.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,18 @@ def test_executescript_step_through_select(self):
469469
con.executescript("select step(t) from t")
470470
self.assertEqual(steps, values)
471471

472+
def test_custom_cursor_object_crash_gh_99886(self):
473+
# This test segfaults on GH-99886
474+
class MyCursor(sqlite.Cursor):
475+
def __init__(self, *args, **kwargs):
476+
super().__init__(*args, **kwargs)
477+
# this can go before or after the super call; doesn't matter
478+
self.some_attr = None
479+
480+
with memory_database() as con:
481+
cur = con.cursor(MyCursor)
482+
cur.close()
483+
del cur
472484

473485
class RecursiveUseOfCursors(unittest.TestCase):
474486
# GH-80254: sqlite3 should not segfault for recursive use of cursors.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a crash when an object which does not have a dictionary frees its instance values.

Objects/dictobject.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5573,14 +5573,16 @@ _PyObject_FreeInstanceAttributes(PyObject *self)
55735573
PyTypeObject *tp = Py_TYPE(self);
55745574
assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
55755575
PyDictValues **values_ptr = _PyObject_ValuesPointer(self);
5576-
if (*values_ptr == NULL) {
5576+
PyDictValues *values = *values_ptr;
5577+
if (values == NULL) {
55775578
return;
55785579
}
5580+
*values_ptr = NULL;
55795581
PyDictKeysObject *keys = CACHED_KEYS(tp);
55805582
for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) {
5581-
Py_XDECREF((*values_ptr)->values[i]);
5583+
Py_XDECREF(values->values[i]);
55825584
}
5583-
free_values(*values_ptr);
5585+
free_values(values);
55845586
}
55855587

55865588
PyObject *

0 commit comments

Comments
 (0)