]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] bpo-41422: Visit the Pickler's and Unpickler's memo in tp_traverse (GH-21664...
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 27 Nov 2023 18:46:34 +0000 (20:46 +0200)
committerGitHub <noreply@github.com>
Mon, 27 Nov 2023 18:46:34 +0000 (18:46 +0000)
(cherry picked from commit 967f2a3052c2d22e31564b428a9aa8cc63dc2a9f)

Co-authored-by: kale-smoothie <34165060+kale-smoothie@users.noreply.github.com>
Misc/NEWS.d/next/Library/2020-07-28-20-48-05.bpo-41422.iMwnMu.rst [new file with mode: 0644]
Modules/_pickle.c

diff --git a/Misc/NEWS.d/next/Library/2020-07-28-20-48-05.bpo-41422.iMwnMu.rst b/Misc/NEWS.d/next/Library/2020-07-28-20-48-05.bpo-41422.iMwnMu.rst
new file mode 100644 (file)
index 0000000..8bde68f
--- /dev/null
@@ -0,0 +1,2 @@
+Fixed memory leaks of :class:`pickle.Pickler` and :class:`pickle.Unpickler` involving cyclic references via the
+internal memo mapping.
index 840877e2db643b2b8d366ca00c9b92526e4e486e..f0cb302184e00b1a9fa6b9cc8cda00ee33d21ff5 100644 (file)
@@ -4691,6 +4691,13 @@ Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)
     Py_VISIT(self->fast_memo);
     Py_VISIT(self->reducer_override);
     Py_VISIT(self->buffer_callback);
+    PyMemoTable *memo = self->memo;
+    if (memo && memo->mt_table) {
+        Py_ssize_t i = memo->mt_allocated;
+        while (--i >= 0) {
+            Py_VISIT(memo->mt_table[i].me_key);
+        }
+    }
     return 0;
 }
 
@@ -7215,6 +7222,13 @@ Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg)
     Py_VISIT(self->stack);
     Py_VISIT(self->pers_func);
     Py_VISIT(self->buffers);
+    PyObject **memo = self->memo;
+    if (memo) {
+        Py_ssize_t i = self->memo_size;
+        while (--i >= 0) {
+            Py_VISIT(memo[i]);
+        }
+    }
     return 0;
 }