]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Merged revisions 88147 via svnmerge from
authorAntoine Pitrou <solipsis@pitrou.net>
Sun, 23 Jan 2011 17:21:28 +0000 (17:21 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Sun, 23 Jan 2011 17:21:28 +0000 (17:21 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r88147 | antoine.pitrou | 2011-01-23 18:12:25 +0100 (dim., 23 janv. 2011) | 3 lines

  Issue #10987: Fix the recursion limit handling in the _pickle module.
........

Misc/NEWS
Modules/_pickle.c
Tools/scripts/find_recursionlimit.py

index 4ab4c1cd6613a4b6741010e4ef48d02d2b8552ad..94cb5bbd6cbec53530b72cc4b2b8448f050a0525 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -37,6 +37,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #10987: Fix the recursion limit handling in the _pickle module.
+
 - Issue #10949: Improved robustness of rotating file handlers.
 
 - Issue #10955: Fix a potential crash when trying to mmap() a file past its
index c47a8445f34fade8aed34717f47363fc8be13b2d..4eb74ffe04f90761cf5ba622fdcb1d189bc86ad1 100644 (file)
@@ -1566,7 +1566,12 @@ save_list(PicklerObject *self, PyObject *obj)
         iter = PyObject_GetIter(obj);
         if (iter == NULL)
             goto error;
+        if (Py_EnterRecursiveCall(" while pickling an object")) {
+            Py_DECREF(iter);
+            goto error;
+        }
         status = batch_list(self, iter);
+        Py_LeaveRecursiveCall();
         Py_DECREF(iter);
     }
 
@@ -1814,10 +1819,10 @@ save_dict(PicklerObject *self, PyObject *obj)
         if (PyDict_CheckExact(obj) && self->proto > 0) {
             /* We can take certain shortcuts if we know this is a dict and
                not a dict subclass. */
-            if (Py_EnterRecursiveCall(" while pickling an object") == 0) {
-                status = batch_dict_exact(self, obj);
-                Py_LeaveRecursiveCall();
-            }
+            if (Py_EnterRecursiveCall(" while pickling an object"))
+                goto error;
+            status = batch_dict_exact(self, obj);
+            Py_LeaveRecursiveCall();
         } else {
             items = PyObject_CallMethod(obj, "items", "()");
             if (items == NULL)
@@ -1826,7 +1831,12 @@ save_dict(PicklerObject *self, PyObject *obj)
             Py_DECREF(items);
             if (iter == NULL)
                 goto error;
+            if (Py_EnterRecursiveCall(" while pickling an object")) {
+                Py_DECREF(iter);
+                goto error;
+            }
             status = batch_dict(self, iter);
+            Py_LeaveRecursiveCall();
             Py_DECREF(iter);
         }
     }
@@ -2353,7 +2363,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
     PyObject *memo_key = NULL;
     int status = 0;
 
-    if (Py_EnterRecursiveCall(" while pickling an object") < 0)
+    if (Py_EnterRecursiveCall(" while pickling an object"))
         return -1;
 
     /* The extra pers_save argument is necessary to avoid calling save_pers()
index 2e202bec6474d408fb759101da3ad1cd6edb8af8..6f75d6da8bbd572996102be9ce7daa9bf6727b75 100644 (file)
@@ -77,14 +77,15 @@ def test_cpickle(_cache={}):
     except ImportError:
         print("cannot import _pickle, skipped!")
         return
-    l = None
+    k, l = None, None
     for n in itertools.count():
         try:
             l = _cache[n]
             continue  # Already tried and it works, let's save some time
         except KeyError:
             for i in range(100):
-                l = [l]
+                l = [k, l]
+                k = {i: l}
         _pickle.Pickler(io.BytesIO(), protocol=-1).dump(l)
         _cache[n] = l