]> granicus.if.org Git - python/commitdiff
Issue #25725: Fixed a reference leak in pickle.loads() when unpickling
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 25 Nov 2015 13:01:53 +0000 (15:01 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Wed, 25 Nov 2015 13:01:53 +0000 (15:01 +0200)
invalid data including tuple instructions.

Misc/NEWS
Modules/_pickle.c

index c98cd96151d40d2f2d75e4e7f60448b525470000..347ce48021cf95c4c1f1dd9a0fe5cf15fc1116eb 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -106,6 +106,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #25725: Fixed a reference leak in pickle.loads() when unpickling
+  invalid data including tuple instructions.
+
 - Issue #25663: In the Readline completer, avoid listing duplicate global
   names, and search the global namespace before searching builtins.
 
index d3bc42009615e09b4f3445b5b8e66764cb6f3ef3..6ff16bba7dfc4e2ce88950c6aaf1e2eb90d0da8e 100644 (file)
@@ -4915,15 +4915,14 @@ load_counted_binunicode(UnpicklerObject *self, int nbytes)
 }
 
 static int
-load_tuple(UnpicklerObject *self)
+load_counted_tuple(UnpicklerObject *self, int len)
 {
     PyObject *tuple;
-    Py_ssize_t i;
 
-    if ((i = marker(self)) < 0)
-        return -1;
+    if (Py_SIZE(self->stack) < len)
+        return stack_underflow();
 
-    tuple = Pdata_poptuple(self->stack, i);
+    tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len);
     if (tuple == NULL)
         return -1;
     PDATA_PUSH(self->stack, tuple, -1);
@@ -4931,24 +4930,14 @@ load_tuple(UnpicklerObject *self)
 }
 
 static int
-load_counted_tuple(UnpicklerObject *self, int len)
+load_tuple(UnpicklerObject *self)
 {
-    PyObject *tuple;
+    Py_ssize_t i;
 
-    tuple = PyTuple_New(len);
-    if (tuple == NULL)
+    if ((i = marker(self)) < 0)
         return -1;
 
-    while (--len >= 0) {
-        PyObject *item;
-
-        PDATA_POP(self->stack, item);
-        if (item == NULL)
-            return -1;
-        PyTuple_SET_ITEM(tuple, len, item);
-    }
-    PDATA_PUSH(self->stack, tuple, -1);
-    return 0;
+    return load_counted_tuple(self, Py_SIZE(self->stack) - i);
 }
 
 static int