[Python-checkins] cpython (merge 3.3 -> 3.4): merge 3.3 (#24094)

benjamin.peterson python-checkins at python.org
Sun May 3 04:37:19 CEST 2015


https://hg.python.org/cpython/rev/f9027b10b3c4
changeset:   95859:f9027b10b3c4
branch:      3.4
parent:      95855:3795daceff85
parent:      95858:0e8c9cf1fede
user:        Benjamin Peterson <benjamin at python.org>
date:        Sat May 02 22:36:26 2015 -0400
summary:
  merge 3.3 (#24094)

files:
  Lib/test/test_json/test_dump.py |  19 ++++++++++++
  Misc/NEWS                       |   3 ++
  Modules/_json.c                 |  31 ++------------------
  3 files changed, 25 insertions(+), 28 deletions(-)


diff --git a/Lib/test/test_json/test_dump.py b/Lib/test/test_json/test_dump.py
--- a/Lib/test/test_json/test_dump.py
+++ b/Lib/test/test_json/test_dump.py
@@ -28,6 +28,25 @@
         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
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,9 @@
 Library
 -------
 
+- Issue #24094: Fix possible crash in json.encode with poorly behaved dict
+  subclasses.
+
 - Asyncio issue 222 / PR 231 (Victor Stinner) -- fix @coroutine
   functions without __name__.
 
diff --git a/Modules/_json.c b/Modules/_json.c
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -1541,36 +1541,11 @@
         */
     }
 
-    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);
-            item = NULL;
-            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)

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list