gh-132775: Fix _PyFunctIon_VerifyStateless() (#134900)

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.
This commit is contained in:
Eric Snow 2025-05-29 14:13:12 -06:00 committed by GitHub
parent d96343679f
commit dafd14146f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

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