]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-132775: Fix _PyFunctIon_VerifyStateless() (#134900)
authorEric Snow <ericsnowcurrently@gmail.com>
Thu, 29 May 2025 20:13:12 +0000 (14:13 -0600)
committerGitHub <noreply@github.com>
Thu, 29 May 2025 20:13:12 +0000 (20:13 +0000)
The problem we're fixing here is that we were using PyDict_Size() on "defaults",
which it is actually a tuple.  We're also adding some explicit type checks.

This is a follow-up to gh-133221/gh-133528.

Objects/funcobject.c

index 27214a129c2fb8c23779fdf06fd0b676ddad5d30..f87b0e5d8f1e47f4e3e61f1d399ddc16f79ee181 100644 (file)
@@ -1264,26 +1264,32 @@ _PyFunction_VerifyStateless(PyThreadState *tstate, PyObject *func)
     }
     // Disallow __defaults__.
     PyObject *defaults = PyFunction_GET_DEFAULTS(func);
-    if (defaults != NULL && defaults != Py_None && PyDict_Size(defaults) > 0)
-    {
-        _PyErr_SetString(tstate, PyExc_ValueError, "defaults not supported");
-        return -1;
+    if (defaults != NULL) {
+        assert(PyTuple_Check(defaults));  // per PyFunction_New()
+        if (PyTuple_GET_SIZE(defaults) > 0) {
+            _PyErr_SetString(tstate, PyExc_ValueError,
+                             "defaults not supported");
+            return -1;
+        }
     }
     // Disallow __kwdefaults__.
     PyObject *kwdefaults = PyFunction_GET_KW_DEFAULTS(func);
-    if (kwdefaults != NULL && kwdefaults != Py_None
-            && PyDict_Size(kwdefaults) > 0)
-    {
-        _PyErr_SetString(tstate, PyExc_ValueError,
-                         "keyword defaults not supported");
-        return -1;
+    if (kwdefaults != NULL) {
+        assert(PyDict_Check(kwdefaults));  // per PyFunction_New()
+        if (PyDict_Size(kwdefaults) > 0) {
+            _PyErr_SetString(tstate, PyExc_ValueError,
+                             "keyword defaults not supported");
+            return -1;
+        }
     }
     // Disallow __closure__.
     PyObject *closure = PyFunction_GET_CLOSURE(func);
-    if (closure != NULL && closure != Py_None && PyTuple_GET_SIZE(closure) > 0)
-    {
-        _PyErr_SetString(tstate, PyExc_ValueError, "closures not supported");
-        return -1;
+    if (closure != NULL) {
+        assert(PyTuple_Check(closure));  // per PyFunction_New()
+        if (PyTuple_GET_SIZE(closure) > 0) {
+            _PyErr_SetString(tstate, PyExc_ValueError, "closures not supported");
+            return -1;
+        }
     }
     // Check the code.
     PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);