Skip to content

Commit 0f38b89

Browse files
[3.13] gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (GH-127872) (#127917)
gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (GH-127872) (cherry picked from commit 6ff38fc) Co-authored-by: Victor Stinner <[email protected]>
1 parent b620e50 commit 0f38b89

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
@@ -1054,8 +1054,13 @@ CDataType_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
10541054
return NULL;
10551055
}
10561056
if (as_parameter) {
1057+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1058+
Py_DECREF(as_parameter);
1059+
return NULL;
1060+
}
10571061
value = CDataType_from_param_impl(type, cls, as_parameter);
10581062
Py_DECREF(as_parameter);
1063+
_Py_LeaveRecursiveCall();
10591064
return value;
10601065
}
10611066
PyErr_Format(PyExc_TypeError,
@@ -1842,8 +1847,13 @@ c_wchar_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
18421847
return NULL;
18431848
}
18441849
if (as_parameter) {
1850+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1851+
Py_DECREF(as_parameter);
1852+
return NULL;
1853+
}
18451854
value = c_wchar_p_from_param_impl(type, cls, as_parameter);
18461855
Py_DECREF(as_parameter);
1856+
_Py_LeaveRecursiveCall();
18471857
return value;
18481858
}
18491859
PyErr_Format(PyExc_TypeError,
@@ -1926,8 +1936,13 @@ c_char_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
19261936
return NULL;
19271937
}
19281938
if (as_parameter) {
1939+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1940+
Py_DECREF(as_parameter);
1941+
return NULL;
1942+
}
19291943
value = c_char_p_from_param_impl(type, cls, as_parameter);
19301944
Py_DECREF(as_parameter);
1945+
_Py_LeaveRecursiveCall();
19311946
return value;
19321947
}
19331948
PyErr_Format(PyExc_TypeError,
@@ -2078,8 +2093,13 @@ c_void_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
20782093
return NULL;
20792094
}
20802095
if (as_parameter) {
2096+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
2097+
Py_DECREF(as_parameter);
2098+
return NULL;
2099+
}
20812100
value = c_void_p_from_param_impl(type, cls, as_parameter);
20822101
Py_DECREF(as_parameter);
2102+
_Py_LeaveRecursiveCall();
20832103
return value;
20842104
}
20852105
PyErr_Format(PyExc_TypeError,
@@ -2435,9 +2455,9 @@ PyCSimpleType_from_param_impl(PyObject *type, PyTypeObject *cls,
24352455
return NULL;
24362456
}
24372457
value = PyCSimpleType_from_param_impl(type, cls, as_parameter);
2438-
_Py_LeaveRecursiveCall();
24392458
Py_DECREF(as_parameter);
24402459
Py_XDECREF(exc);
2460+
_Py_LeaveRecursiveCall();
24412461
return value;
24422462
}
24432463
if (exc) {

0 commit comments

Comments
 (0)