From: Victor Stinner Date: Tue, 27 Jan 2026 11:59:55 +0000 (+0100) Subject: [3.13] gh-144100: Fix crash for POINTER(str) used in ctypes argtypes (#144108) (... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3df9e311421fddafdfbe10ad961218a2b577a9fd;p=thirdparty%2FPython%2Fcpython.git [3.13] gh-144100: Fix crash for POINTER(str) used in ctypes argtypes (#144108) (#144245) gh-144100: Fix crash for POINTER(str) used in ctypes argtypes (#144108) (cherry picked from commit 8f459255eba2b6639f1912e5c5e318a7cdafada1) Co-authored-by: VanshAgarwal24036 <148854295+VanshAgarwal24036@users.noreply.github.com> --- diff --git a/Lib/test/test_ctypes/test_pointers.py b/Lib/test/test_ctypes/test_pointers.py index ed4541335dfc..3e904e17fab8 100644 --- a/Lib/test/test_ctypes/test_pointers.py +++ b/Lib/test/test_ctypes/test_pointers.py @@ -235,6 +235,17 @@ class PointersTestCase(unittest.TestCase): ptr.set_type(c_int) self.assertIs(ptr._type_, c_int) + def test_pointer_proto_missing_argtypes_error(self): + class BadType(ctypes._Pointer): + # _type_ is intentionally missing + pass + + func = ctypes.pythonapi.Py_GetVersion + func.argtypes = (BadType,) + + with self.assertRaises(ctypes.ArgumentError): + func(object()) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst b/Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst new file mode 100644 index 000000000000..7093b753141f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst @@ -0,0 +1,3 @@ +Fixed a crash in ctypes when using a deprecated ``POINTER(str)`` type in +``argtypes``. Instead of aborting, ctypes now raises a proper Python +exception when the pointer target type is unresolved. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 7419d629399e..aac812813d95 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1338,7 +1338,13 @@ PyCPointerType_from_param_impl(PyObject *type, PyTypeObject *cls, /* If we expect POINTER(), but receive a instance, accept it by calling byref(). */ - assert(typeinfo->proto); + if (typeinfo->proto == NULL) { + PyErr_SetString( + PyExc_TypeError, + "cannot convert argument: POINTER _type_ type is not set" + ); + return NULL; + } switch (PyObject_IsInstance(value, typeinfo->proto)) { case 1: Py_INCREF(value); /* _byref steals a refcount */