]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (#127872...
authorVictor Stinner <vstinner@python.org>
Fri, 13 Dec 2024 13:21:30 +0000 (14:21 +0100)
committerGitHub <noreply@github.com>
Fri, 13 Dec 2024 13:21:30 +0000 (13:21 +0000)
gh-127870: Detect recursive calls in ctypes _as_parameter_ handling (#127872)

(cherry picked from commit 6ff38fc4e2af8e795dc791be6ea596d2146d4119)

Lib/test/test_ctypes/test_as_parameter.py
Misc/NEWS.d/next/Library/2024-12-12-16-59-42.gh-issue-127870._NFG-3.rst [new file with mode: 0644]
Modules/_ctypes/_ctypes.c

index 27a5d3ac06430b22f65774c2175d18dae6b7c0d2..ec51c68f6c0868beb39fa5af4b1cc24cec334751 100644 (file)
@@ -1,3 +1,4 @@
+import ctypes
 import unittest
 from ctypes import *
 from test.test_ctypes import need_symbol
@@ -192,15 +193,21 @@ class BasicWrapTestCase(unittest.TestCase):
                              (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
 
     def test_recursive_as_param(self):
-        from ctypes import c_int
-
         class A:
             pass
 
         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)
 
 
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 (file)
index 0000000..99b2df0
--- /dev/null
@@ -0,0 +1,2 @@
+Detect recursive calls in ctypes ``_as_parameter_`` handling.
+Patch by Victor Stinner.
index b6d45e926476843b9725085d34c8244f5f79e9aa..9bcf79fddfffb7d2ec4fabc224fb328cd38f4702 100644 (file)
@@ -847,8 +847,13 @@ CDataType_from_param(PyObject *type, PyObject *value)
         return NULL;
     }
     if (as_parameter) {
+        if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
+            Py_DECREF(as_parameter);
+            return NULL;
+        }
         value = CDataType_from_param(type, as_parameter);
         Py_DECREF(as_parameter);
+        _Py_LeaveRecursiveCall();
         return value;
     }
     PyErr_Format(PyExc_TypeError,
@@ -1716,8 +1721,13 @@ c_wchar_p_from_param(PyObject *type, 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(type, as_parameter);
         Py_DECREF(as_parameter);
+        _Py_LeaveRecursiveCall();
         return value;
     }
     /* XXX better message */
@@ -1780,8 +1790,13 @@ c_char_p_from_param(PyObject *type, 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(type, as_parameter);
         Py_DECREF(as_parameter);
+        _Py_LeaveRecursiveCall();
         return value;
     }
     /* XXX better message */
@@ -1915,8 +1930,13 @@ c_void_p_from_param(PyObject *type, 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(type, as_parameter);
         Py_DECREF(as_parameter);
+        _Py_LeaveRecursiveCall();
         return value;
     }
     /* XXX better message */
@@ -2275,9 +2295,9 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
             return NULL;
         }
         value = PyCSimpleType_from_param(type, as_parameter);
-        _Py_LeaveRecursiveCall();
         Py_DECREF(as_parameter);
         Py_XDECREF(exc);
+        _Py_LeaveRecursiveCall();
         return value;
     }
     if (exc) {