]> granicus.if.org Git - python/commitdiff
just sort the items tuple directly (closes #24094)
authorBenjamin Peterson <benjamin@python.org>
Sun, 3 May 2015 02:28:04 +0000 (22:28 -0400)
committerBenjamin Peterson <benjamin@python.org>
Sun, 3 May 2015 02:28:04 +0000 (22:28 -0400)
Lib/test/test_json/test_dump.py
Misc/NEWS
Modules/_json.c

index af1925888db4ceb0020edbd78225898bfcd01459..fd0d86b392cee9ef2db2175fc0b0768d09e71d8b 100644 (file)
@@ -28,6 +28,25 @@ class TestDump:
         self.assertEqual(self.dumps(a, default=crasher),
                  '[null, null, null, null, null]')
 
+    # Issue 24094
+    def test_encode_evil_dict(self):
+        class D(dict):
+            def keys(self):
+                return L
+
+        class X:
+            def __hash__(self):
+                del L[0]
+                return 1337
+
+            def __lt__(self, o):
+                return 0
+
+        L = [X() for i in range(1122)]
+        d = D()
+        d[1337] = "true.dat"
+        self.assertEqual(self.dumps(d, sort_keys=True), '{"1337": "true.dat"}')
+
 
 class TestPyDump(TestDump, PyTest): pass
 
index 1a313db82c9d09429b83190172dd11cf694ba17f..ca923fb18e3d4cbca7bc5a3d731651b50142e634 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -19,6 +19,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #24094: Fix possible crash in json.encode with poorly behaved dict
+  subclasses.
+
 - Issue #23367: Fix possible overflows in the unicodedata module.
 
 - Issue #23361: Fix possible overflow in Windows subprocess creation code.
index 397037e56b99ebd502c3c9bcf38c63fcd6b10771..6df08b555ddd55a9f5ab67122ed01f7cfe9edd09 100644 (file)
@@ -1527,35 +1527,11 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
         */
     }
 
-    if (PyObject_IsTrue(s->sort_keys)) {
-        /* First sort the keys then replace them with (key, value) tuples. */
-        Py_ssize_t i, nitems;
-        items = PyMapping_Keys(dct);
-        if (items == NULL)
-            goto bail;
-        if (!PyList_Check(items)) {
-            PyErr_SetString(PyExc_ValueError, "keys must return list");
-            goto bail;
-        }
-        if (PyList_Sort(items) < 0)
-            goto bail;
-        nitems = PyList_GET_SIZE(items);
-        for (i = 0; i < nitems; i++) {
-            PyObject *key, *value;
-            key = PyList_GET_ITEM(items, i);
-            value = PyDict_GetItem(dct, key);
-            item = PyTuple_Pack(2, key, value);
-            if (item == NULL)
-                goto bail;
-            PyList_SET_ITEM(items, i, item);
-            Py_DECREF(key);
-        }
-    }
-    else {
-        items = PyMapping_Items(dct);
-    }
+    items = PyMapping_Items(dct);
     if (items == NULL)
         goto bail;
+    if (PyObject_IsTrue(s->sort_keys) && PyList_Sort(items) < 0)
+        goto bail;
     it = PyObject_GetIter(items);
     Py_DECREF(items);
     if (it == NULL)