https://github.com/python/cpython/commit/6ff38fc4e2af8e795dc791be6ea596d2146d4119
commit: 6ff38fc4e2af8e795dc791be6ea596d2146d4119
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2024-12-13T13:53:47+01:00
summary:

gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (#127872)

files:
A Misc/NEWS.d/next/Library/2024-12-12-16-59-42.gh-issue-127870._NFG-3.rst
M Lib/test/test_ctypes/test_as_parameter.py
M Modules/_ctypes/_ctypes.c

diff --git a/Lib/test/test_ctypes/test_as_parameter.py 
b/Lib/test/test_ctypes/test_as_parameter.py
index cc62b1a22a3b06..c5e1840b0eb7af 100644
--- a/Lib/test/test_ctypes/test_as_parameter.py
+++ b/Lib/test/test_ctypes/test_as_parameter.py
@@ -198,8 +198,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:
diff --git 
a/Misc/NEWS.d/next/Library/2024-12-12-16-59-42.gh-issue-127870._NFG-3.rst 
b/Misc/NEWS.d/next/Library/2024-12-12-16-59-42.gh-issue-127870._NFG-3.rst
new file mode 100644
index 00000000000000..99b2df00032082
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-12-16-59-42.gh-issue-127870._NFG-3.rst
@@ -0,0 +1,2 @@
+Detect recursive calls in ctypes ``_as_parameter_`` handling.
+Patch by Victor Stinner.
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 34529bce496d88..bb4699884057ba 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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) {

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to