mirror of
https://github.com/python/cpython.git
synced 2026-01-04 14:32:21 +00:00
GH-132417: ctypes: Fix potential Py_DECREF(NULL) when handling functions returning PyObject * (#132418)
Some functions (such as `PyErr_Occurred`) with a `restype` set to `ctypes.py_object` may return NULL without setting an exception.
This commit is contained in:
parent
e0dffc54b8
commit
2aab2db146
3 changed files with 22 additions and 3 deletions
|
|
@ -123,5 +123,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()
|
||||
|
|
|
|||
|
|
@ -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``.
|
||||
|
|
@ -1022,11 +1022,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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue