Skip to content

Commit 21c056e

Browse files
authored
[3.12] gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (#127872) (#127918)
gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (#127872) (cherry picked from commit 6ff38fc)
1 parent 6544f99 commit 21c056e

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

Lib/test/test_ctypes/test_as_parameter.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ctypes
12
import unittest
23
from ctypes import *
34
from test.test_ctypes import need_symbol
@@ -192,15 +193,21 @@ class S8I(Structure):
192193
(9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
193194

194195
def test_recursive_as_param(self):
195-
from ctypes import c_int
196-
197196
class A:
198197
pass
199198

200199
a = A()
201200
a._as_parameter_ = a
202-
with self.assertRaises(RecursionError):
203-
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)
204211

205212

206213
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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

+21-1
Original file line numberDiff line numberDiff line change
@@ -847,8 +847,13 @@ CDataType_from_param(PyObject *type, PyObject *value)
847847
return NULL;
848848
}
849849
if (as_parameter) {
850+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
851+
Py_DECREF(as_parameter);
852+
return NULL;
853+
}
850854
value = CDataType_from_param(type, as_parameter);
851855
Py_DECREF(as_parameter);
856+
_Py_LeaveRecursiveCall();
852857
return value;
853858
}
854859
PyErr_Format(PyExc_TypeError,
@@ -1716,8 +1721,13 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
17161721
return NULL;
17171722
}
17181723
if (as_parameter) {
1724+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1725+
Py_DECREF(as_parameter);
1726+
return NULL;
1727+
}
17191728
value = c_wchar_p_from_param(type, as_parameter);
17201729
Py_DECREF(as_parameter);
1730+
_Py_LeaveRecursiveCall();
17211731
return value;
17221732
}
17231733
/* XXX better message */
@@ -1780,8 +1790,13 @@ c_char_p_from_param(PyObject *type, PyObject *value)
17801790
return NULL;
17811791
}
17821792
if (as_parameter) {
1793+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1794+
Py_DECREF(as_parameter);
1795+
return NULL;
1796+
}
17831797
value = c_char_p_from_param(type, as_parameter);
17841798
Py_DECREF(as_parameter);
1799+
_Py_LeaveRecursiveCall();
17851800
return value;
17861801
}
17871802
/* XXX better message */
@@ -1915,8 +1930,13 @@ c_void_p_from_param(PyObject *type, PyObject *value)
19151930
return NULL;
19161931
}
19171932
if (as_parameter) {
1933+
if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
1934+
Py_DECREF(as_parameter);
1935+
return NULL;
1936+
}
19181937
value = c_void_p_from_param(type, as_parameter);
19191938
Py_DECREF(as_parameter);
1939+
_Py_LeaveRecursiveCall();
19201940
return value;
19211941
}
19221942
/* XXX better message */
@@ -2275,9 +2295,9 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
22752295
return NULL;
22762296
}
22772297
value = PyCSimpleType_from_param(type, as_parameter);
2278-
_Py_LeaveRecursiveCall();
22792298
Py_DECREF(as_parameter);
22802299
Py_XDECREF(exc);
2300+
_Py_LeaveRecursiveCall();
22812301
return value;
22822302
}
22832303
if (exc) {

0 commit comments

Comments
 (0)