Skip to content

Commit 6ff38fc

Browse files
authored
gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (#127872)
1 parent e62e1ca commit 6ff38fc

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

Lib/test/test_ctypes/test_as_parameter.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,16 @@ class A:
198198

199199
a = A()
200200
a._as_parameter_ = a
201-
with self.assertRaises(RecursionError):
202-
c_int.from_param(a)
201+
for c_type in (
202+
ctypes.c_wchar_p,
203+
ctypes.c_char_p,
204+
ctypes.c_void_p,
205+
ctypes.c_int, # PyCSimpleType
206+
POINT, # CDataType
207+
):
208+
with self.subTest(c_type=c_type):
209+
with self.assertRaises(RecursionError):
210+
c_type.from_param(a)
203211

204212

205213
class AsParamWrapper:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Detect recursive calls in ctypes ``_as_parameter_`` handling.
2+
Patch by Victor Stinner.

Modules/_ctypes/_ctypes.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,8 +1052,13 @@ CDataType_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
10521052
return NULL;
10531053
}
10541054
if (as_parameter) {
1055+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1056+
Py_DECREF(as_parameter);
1057+
return NULL;
1058+
}
10551059
value = CDataType_from_param_impl(type, cls, as_parameter);
10561060
Py_DECREF(as_parameter);
1061+
_Py_LeaveRecursiveCall();
10571062
return value;
10581063
}
10591064
PyErr_Format(PyExc_TypeError,
@@ -1843,8 +1848,13 @@ c_wchar_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
18431848
return NULL;
18441849
}
18451850
if (as_parameter) {
1851+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1852+
Py_DECREF(as_parameter);
1853+
return NULL;
1854+
}
18461855
value = c_wchar_p_from_param_impl(type, cls, as_parameter);
18471856
Py_DECREF(as_parameter);
1857+
_Py_LeaveRecursiveCall();
18481858
return value;
18491859
}
18501860
PyErr_Format(PyExc_TypeError,
@@ -1927,8 +1937,13 @@ c_char_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
19271937
return NULL;
19281938
}
19291939
if (as_parameter) {
1940+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1941+
Py_DECREF(as_parameter);
1942+
return NULL;
1943+
}
19301944
value = c_char_p_from_param_impl(type, cls, as_parameter);
19311945
Py_DECREF(as_parameter);
1946+
_Py_LeaveRecursiveCall();
19321947
return value;
19331948
}
19341949
PyErr_Format(PyExc_TypeError,
@@ -2079,8 +2094,13 @@ c_void_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
20792094
return NULL;
20802095
}
20812096
if (as_parameter) {
2097+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
2098+
Py_DECREF(as_parameter);
2099+
return NULL;
2100+
}
20822101
value = c_void_p_from_param_impl(type, cls, as_parameter);
20832102
Py_DECREF(as_parameter);
2103+
_Py_LeaveRecursiveCall();
20842104
return value;
20852105
}
20862106
PyErr_Format(PyExc_TypeError,
@@ -2447,9 +2467,9 @@ PyCSimpleType_from_param_impl(PyObject *type, PyTypeObject *cls,
24472467
return NULL;
24482468
}
24492469
value = PyCSimpleType_from_param_impl(type, cls, as_parameter);
2450-
_Py_LeaveRecursiveCall();
24512470
Py_DECREF(as_parameter);
24522471
Py_XDECREF(exc);
2472+
_Py_LeaveRecursiveCall();
24532473
return value;
24542474
}
24552475
if (exc) {

0 commit comments

Comments
 (0)