[Python-checkins] [3.11] gh-99886: Fix crash when freeing objects with managed dictionaries (#99902)

Fidget-Spinner webhook-mailer at python.org
Sun Dec 4 01:42:00 EST 2022


https://github.com/python/cpython/commit/9e38553132bf7c6fc13e9f268a54ac6533e6ad41
commit: 9e38553132bf7c6fc13e9f268a54ac6533e6ad41
branch: 3.11
author: Ken Jin <kenjin at python.org>
committer: Fidget-Spinner <kenjin at python.org>
date: 2022-12-04T14:41:23+08:00
summary:

[3.11] gh-99886: Fix crash when freeing objects with managed dictionaries (#99902)

Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com>

files:
A Misc/NEWS.d/next/Core and Builtins/2022-11-30-15-29-08.gh-issue-99886.feJkSv.rst
M Lib/test/test_sqlite3/test_regression.py
M Objects/dictobject.c

diff --git a/Lib/test/test_sqlite3/test_regression.py b/Lib/test/test_sqlite3/test_regression.py
index 0b727cecb0e8..9a07e02ae119 100644
--- a/Lib/test/test_sqlite3/test_regression.py
+++ b/Lib/test/test_sqlite3/test_regression.py
@@ -469,6 +469,18 @@ def test_executescript_step_through_select(self):
             con.executescript("select step(t) from t")
             self.assertEqual(steps, values)
 
+    def test_custom_cursor_object_crash_gh_99886(self):
+        # This test segfaults on GH-99886
+        class MyCursor(sqlite.Cursor):
+            def __init__(self, *args, **kwargs):
+                super().__init__(*args, **kwargs)
+                # this can go before or after the super call; doesn't matter
+                self.some_attr = None
+
+        with memory_database() as con:
+            cur = con.cursor(MyCursor)
+            cur.close()
+            del cur
 
 class RecursiveUseOfCursors(unittest.TestCase):
     # GH-80254: sqlite3 should not segfault for recursive use of cursors.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-11-30-15-29-08.gh-issue-99886.feJkSv.rst b/Misc/NEWS.d/next/Core and Builtins/2022-11-30-15-29-08.gh-issue-99886.feJkSv.rst
new file mode 100644
index 000000000000..8bdaa9462750
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-11-30-15-29-08.gh-issue-99886.feJkSv.rst	
@@ -0,0 +1 @@
+Fix a crash when an object which does not have a dictionary frees its instance values.
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index ebbd22ee7c14..4a214f8cf5b7 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -5573,14 +5573,16 @@ _PyObject_FreeInstanceAttributes(PyObject *self)
     PyTypeObject *tp = Py_TYPE(self);
     assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
     PyDictValues **values_ptr = _PyObject_ValuesPointer(self);
-    if (*values_ptr == NULL) {
+    PyDictValues *values = *values_ptr;
+    if (values == NULL) {
         return;
     }
+    *values_ptr = NULL;
     PyDictKeysObject *keys = CACHED_KEYS(tp);
     for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) {
-        Py_XDECREF((*values_ptr)->values[i]);
+        Py_XDECREF(values->values[i]);
     }
-    free_values(*values_ptr);
+    free_values(values);
 }
 
 PyObject *



More information about the Python-checkins mailing list