]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] GH-140590: Fix setstate for functools.partial C-module (GH-140671) (#140698)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 28 Oct 2025 12:45:27 +0000 (13:45 +0100)
committerGitHub <noreply@github.com>
Tue, 28 Oct 2025 12:45:27 +0000 (18:15 +0530)
GH-140590: Fix setstate for functools.partial C-module (GH-140671)

(cherry picked from commit d26686a7f87d63499f7296c0811fa0535637a93b)

Co-authored-by: Sergey Miryanov <sergey.miryanov@gmail.com>
Co-authored-by: Mikhail Efimov <efimov.mikhail@gmail.com>
Lib/test/test_functools.py
Misc/NEWS.d/next/Library/2025-10-27-18-29-42.gh-issue-140590.LT9HHn.rst [new file with mode: 0644]
Modules/_functoolsmodule.c

index f7e09fd771eaf2d9a6a4adf817f22adfec3ab1f8..ce9e7f6d57dd3c8fbc05fa05f66c3a804cacc92d 100644 (file)
@@ -406,6 +406,7 @@ class TestPartial:
 
     def test_setstate_errors(self):
         f = self.partial(signature)
+
         self.assertRaises(TypeError, f.__setstate__, (capture, (), {}))
         self.assertRaises(TypeError, f.__setstate__, (capture, (), {}, {}, None))
         self.assertRaises(TypeError, f.__setstate__, [capture, (), {}, None])
@@ -413,6 +414,8 @@ class TestPartial:
         self.assertRaises(TypeError, f.__setstate__, (capture, None, {}, None))
         self.assertRaises(TypeError, f.__setstate__, (capture, [], {}, None))
         self.assertRaises(TypeError, f.__setstate__, (capture, (), [], None))
+        self.assertRaises(TypeError, f.__setstate__, (capture, (), {}, ()))
+        self.assertRaises(TypeError, f.__setstate__, (capture, (), {}, 'test'))
 
     def test_setstate_subclasses(self):
         f = self.partial(signature)
diff --git a/Misc/NEWS.d/next/Library/2025-10-27-18-29-42.gh-issue-140590.LT9HHn.rst b/Misc/NEWS.d/next/Library/2025-10-27-18-29-42.gh-issue-140590.LT9HHn.rst
new file mode 100644 (file)
index 0000000..8021836
--- /dev/null
@@ -0,0 +1,2 @@
+Fix arguments checking for the :meth:`!functools.partial.__setstate__` that
+may lead to internal state corruption and crash. Patch by Sergey Miryanov.
index 3d45da493f4b3d4a2d5d9a3ac710bfa9f2ed4c92..3420e7d8c37b745b7cd97e74384467631df278a8 100644 (file)
@@ -699,7 +699,8 @@ partial_setstate(PyObject *self, PyObject *state)
     if (!PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) ||
         !PyCallable_Check(fn) ||
         !PyTuple_Check(fnargs) ||
-        (kw != Py_None && !PyDict_Check(kw)))
+        (kw != Py_None && !PyDict_Check(kw)) ||
+        (dict != Py_None && !PyDict_Check(dict)))
     {
         PyErr_SetString(PyExc_TypeError, "invalid partial state");
         return NULL;