]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-142218: Fix split table dictionary crash (gh-142229) (gh-142244)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 4 Dec 2025 00:03:18 +0000 (01:03 +0100)
committerGitHub <noreply@github.com>
Thu, 4 Dec 2025 00:03:18 +0000 (00:03 +0000)
This fixes a regression introduced in gh-140558. The interpreter would
crash if we inserted a non `str` key into a split table that matches an
existing key.
(cherry picked from commit 547d8daf780646e2800bec598ed32085817c8606)

Co-authored-by: Sam Gross <colesbury@gmail.com>
Lib/test/test_dict.py
Misc/NEWS.d/next/Core_and_Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst [new file with mode: 0644]
Objects/dictobject.c

index 2e6c2bbdf1940944cf59f9eb351c9bdbaab18343..665b3e843dd3a5dd2a9d5c1a26233589c254d9fc 100644 (file)
@@ -1621,6 +1621,14 @@ class DictTest(unittest.TestCase):
 
         self.assertEqual(len(d), 1)
 
+    def test_split_table_update_with_str_subclass(self):
+        class MyStr(str): pass
+        class MyClass: pass
+        obj = MyClass()
+        obj.attr = 1
+        obj.__dict__[MyStr('attr')] = 2
+        self.assertEqual(obj.attr, 2)
+
 
 class CAPITest(unittest.TestCase):
 
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst
new file mode 100644 (file)
index 0000000..a8ce0fc
--- /dev/null
@@ -0,0 +1,2 @@
+Fix crash when inserting into a split table dictionary with a non
+:class:`str` key that matches an existing key.
index 1b4640f9649569ac3543244984a8dcefbce33eff..0eb00410cf41ebed8aa18d31c713d414e9faef86 100644 (file)
@@ -1863,10 +1863,14 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
     if (old_value != value) {
         _PyDict_NotifyEvent(interp, PyDict_EVENT_MODIFIED, mp, key, value);
         assert(old_value != NULL);
-        assert(!_PyDict_HasSplitTable(mp));
         if (DK_IS_UNICODE(mp->ma_keys)) {
-            PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
-            STORE_VALUE(ep, value);
+            if (_PyDict_HasSplitTable(mp)) {
+                STORE_SPLIT_VALUE(mp, ix, value);
+            }
+            else {
+                PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
+                STORE_VALUE(ep, value);
+            }
         }
         else {
             PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];