]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-106287: Do not write objects after an unmarshalling error (GH-132715) ...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 14 Jan 2026 11:52:20 +0000 (12:52 +0100)
committerGitHub <noreply@github.com>
Wed, 14 Jan 2026 11:52:20 +0000 (11:52 +0000)
Writing out an object may involve a slot lookup, which is not safe to do with
an exception raised. In debug mode an assertion failure will occur if this
happens.
(cherry picked from commit ce8f5f98c6fc95a1704360d986a4d0281eeada79)

Co-authored-by: Duane Griffin <duaneg@dghda.com>
Lib/test/test_marshal.py
Misc/NEWS.d/next/Library/2025-04-19-17-34-11.gh-issue-132715.XXl47F.rst [new file with mode: 0644]
Python/marshal.c

index 662bdfccc79125155f188083622ade6a82875092..28f24d0fc59cb0ac3fa912e4fcf511f43f30c3aa 100644 (file)
@@ -413,6 +413,26 @@ class BugsTestCase(unittest.TestCase):
                     _, dump_1, _ = assert_python_ok(*args, PYTHONHASHSEED="1")
                     self.assertEqual(dump_0, dump_1)
 
+    def test_unmarshallable(self):
+        # Check no crash after encountering unmarshallable objects.
+        # See https://github.com/python/cpython/issues/106287.
+        fset = frozenset([int])
+        code = compile("a = 1", "<string>", "exec")
+        code = code.replace(co_consts=(1, fset, None))
+        cases = (('tuple', (fset,)),
+                 ('list', [fset]),
+                 ('set', fset),
+                 ('dict key', {fset: 'x'}),
+                 ('dict value', {'x': fset}),
+                 ('dict key & value', {fset: fset}),
+                 ('slice', slice(fset, fset)),
+                 ('code', code))
+        for name, arg in cases:
+            with self.subTest(name, arg=arg):
+                with self.assertRaisesRegex(ValueError, "unmarshallable object"):
+                    marshal.dumps((arg, memoryview(b'')))
+
+
 LARGE_SIZE = 2**31
 pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
 
diff --git a/Misc/NEWS.d/next/Library/2025-04-19-17-34-11.gh-issue-132715.XXl47F.rst b/Misc/NEWS.d/next/Library/2025-04-19-17-34-11.gh-issue-132715.XXl47F.rst
new file mode 100644 (file)
index 0000000..191b4f1
--- /dev/null
@@ -0,0 +1 @@
+Skip writing objects during marshalling once a failure has occurred.
index 5130edc91fa6fc5500cab75b63549fcea719ece8..507e882e951a4e54300b524d4894bed37dd6099c 100644 (file)
@@ -432,6 +432,10 @@ w_object(PyObject *v, WFILE *p)
 {
     char flag = '\0';
 
+    if (p->error != WFERR_OK) {
+        return;
+    }
+
     p->depth++;
 
     if (p->depth > MAX_MARSHAL_STACK_DEPTH) {