https://github.com/python/cpython/commit/0aabe44fa8a8159561c04a9b6e7450bfaa319e94 commit: 0aabe44fa8a8159561c04a9b6e7450bfaa319e94 branch: 3.13 author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com> committer: picnixz <10796600+picn...@users.noreply.github.com> date: 2025-04-12T09:14:07Z summary:
[3.13] GH-132417: ctypes: Fix potential `Py_DECREF(NULL)` when handling functions returning `PyObject *` (GH-132418) (#132425) GH-132417: ctypes: Fix potential `Py_DECREF(NULL)` when handling functions returning `PyObject *` (GH-132418) Some functions (such as `PyErr_Occurred`) with a `restype` set to `ctypes.py_object` may return NULL without setting an exception. (cherry picked from commit 2aab2db1461ef49b42549255af16a74b1bf8a5ef) Co-authored-by: Nicolas Trangez <i...@nicolast.be> files: A Misc/NEWS.d/next/Library/2025-04-11-21-48-49.gh-issue-132417.uILGdS.rst M Lib/test/test_ctypes/test_refcounts.py M Modules/_ctypes/callproc.c diff --git a/Lib/test/test_ctypes/test_refcounts.py b/Lib/test/test_ctypes/test_refcounts.py index 012722d8486218..9e87cfc661edf1 100644 --- a/Lib/test/test_ctypes/test_refcounts.py +++ b/Lib/test/test_ctypes/test_refcounts.py @@ -124,5 +124,20 @@ def test_finalize(self): script_helper.assert_python_ok("-c", script) +class PyObjectRestypeTest(unittest.TestCase): + def test_restype_py_object_with_null_return(self): + # Test that a function which returns a NULL PyObject * + # without setting an exception does not crash. + PyErr_Occurred = ctypes.pythonapi.PyErr_Occurred + PyErr_Occurred.argtypes = [] + PyErr_Occurred.restype = ctypes.py_object + + # At this point, there's no exception set, so PyErr_Occurred + # returns NULL. Given the restype is py_object, the + # ctypes machinery will raise a custom error. + with self.assertRaisesRegex(ValueError, "PyObject is NULL"): + PyErr_Occurred() + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2025-04-11-21-48-49.gh-issue-132417.uILGdS.rst b/Misc/NEWS.d/next/Library/2025-04-11-21-48-49.gh-issue-132417.uILGdS.rst new file mode 100644 index 00000000000000..878651c8a0ad5c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-11-21-48-49.gh-issue-132417.uILGdS.rst @@ -0,0 +1,3 @@ +Fix a ``NULL`` pointer dereference when a C function called using +:mod:`ctypes` with ``restype`` :class:`~ctypes.py_object` returns +``NULL``. diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index f9864ebb735ddf..8f94d19024e62c 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1016,11 +1016,12 @@ static PyObject *GetResult(ctypes_state *st, if (info->getfunc && !_ctypes_simple_instance(st, restype)) { retval = info->getfunc(result, info->size); /* If restype is py_object (detected by comparing getfunc with - O_get), we have to call Py_DECREF because O_get has already - called Py_INCREF. + O_get), we have to call Py_XDECREF because O_get has already + called Py_INCREF, unless the result was NULL, in which case + an error is set (by the called function, or by O_get). */ if (info->getfunc == _ctypes_get_fielddesc("O")->getfunc) { - Py_DECREF(retval); + Py_XDECREF(retval); } } else { _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com