[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