Skip to content

Commit

Permalink
pythongh-127870: Fix ctypes _as_parameter_ handling
Browse files Browse the repository at this point in the history
Detect recursive calls in ctypes _as_parameter_ handling: add
Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() calls.
  • Loading branch information
vstinner committed Dec 12, 2024
1 parent 487fdbe commit 7eab170
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
13 changes: 11 additions & 2 deletions Lib/test/test_ctypes/test_as_parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
c_short, c_int, c_long, c_longlong,
c_byte, c_wchar, c_float, c_double,
ArgumentError)
import ctypes

Check failure on line 8 in Lib/test/test_ctypes/test_as_parameter.py

View workflow job for this annotation

GitHub Actions / lint

Ruff (F811)

Lib/test/test_ctypes/test_as_parameter.py:8:8: F811 Redefinition of unused `ctypes` from line 1
from test.support import import_helper
_ctypes_test = import_helper.import_module("_ctypes_test")

Expand Down Expand Up @@ -198,8 +199,16 @@ class A:

a = A()
a._as_parameter_ = a
with self.assertRaises(RecursionError):
c_int.from_param(a)
for c_type in (
ctypes.c_wchar_p,
ctypes.c_char_p,
ctypes.c_void_p,
ctypes.c_int, # PyCSimpleType
POINT, # CDataType
):
with self.subTest(c_type=c_type):
with self.assertRaises(RecursionError):
c_type.from_param(a)


class AsParamWrapper:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix ctypes ``_as_parameter_`` handling: detect recursive calls. Patch by
Victor Stinner.
22 changes: 21 additions & 1 deletion Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,8 +1052,13 @@ CDataType_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
return NULL;
}
if (as_parameter) {
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
Py_DECREF(as_parameter);
return NULL;
}
value = CDataType_from_param_impl(type, cls, as_parameter);
Py_DECREF(as_parameter);
_Py_LeaveRecursiveCall();
return value;
}
PyErr_Format(PyExc_TypeError,
Expand Down Expand Up @@ -1843,8 +1848,13 @@ c_wchar_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
return NULL;
}
if (as_parameter) {
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
Py_DECREF(as_parameter);
return NULL;
}
value = c_wchar_p_from_param_impl(type, cls, as_parameter);
Py_DECREF(as_parameter);
_Py_LeaveRecursiveCall();
return value;
}
PyErr_Format(PyExc_TypeError,
Expand Down Expand Up @@ -1927,8 +1937,13 @@ c_char_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
return NULL;
}
if (as_parameter) {
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
Py_DECREF(as_parameter);
return NULL;
}
value = c_char_p_from_param_impl(type, cls, as_parameter);
Py_DECREF(as_parameter);
_Py_LeaveRecursiveCall();
return value;
}
PyErr_Format(PyExc_TypeError,
Expand Down Expand Up @@ -2079,8 +2094,13 @@ c_void_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
return NULL;
}
if (as_parameter) {
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
Py_DECREF(as_parameter);
return NULL;
}
value = c_void_p_from_param_impl(type, cls, as_parameter);
Py_DECREF(as_parameter);
_Py_LeaveRecursiveCall();
return value;
}
PyErr_Format(PyExc_TypeError,
Expand Down Expand Up @@ -2447,9 +2467,9 @@ PyCSimpleType_from_param_impl(PyObject *type, PyTypeObject *cls,
return NULL;
}
value = PyCSimpleType_from_param_impl(type, cls, as_parameter);
_Py_LeaveRecursiveCall();
Py_DECREF(as_parameter);
Py_XDECREF(exc);
_Py_LeaveRecursiveCall();
return value;
}
if (exc) {
Expand Down

0 comments on commit 7eab170

Please sign in to comment.