diff --git a/Lib/test/test_ctypes/test_pointers.py b/Lib/test/test_ctypes/test_pointers.py index a8d243a45de0f4..7cd99a19dbb770 100644 --- a/Lib/test/test_ctypes/test_pointers.py +++ b/Lib/test/test_ctypes/test_pointers.py @@ -3,6 +3,7 @@ import gc import sys import unittest +import os from ctypes import (CDLL, CFUNCTYPE, Structure, POINTER, pointer, _Pointer, byref, sizeof, @@ -472,6 +473,23 @@ class C(Structure): ptr.set_type(c_int) self.assertIs(ptr._type_, c_int) +class TestPointerStringProto(unittest.TestCase): + def test_pointer_string_proto_argtypes_error(self): + with self.assertWarns(DeprecationWarning): + BadType = ctypes.POINTER("BugTrigger") + + if os.name == "nt": + libc = ctypes.WinDLL("kernel32.dll") + func = libc.GetCurrentProcessId + else: + libc = ctypes.CDLL(None) + func = libc.getpid + + func.argtypes = (BadType,) + + with self.assertRaises(ctypes.ArgumentError): + func(ctypes.byref(ctypes.c_int(0))) + 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 00000000000000..7093b753141fb8 --- /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 563e95a762599b..f8af76ae915ed2 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1419,7 +1419,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 target type is unresolved" + ); + return NULL; + } switch (PyObject_IsInstance(value, typeinfo->proto)) { case 1: Py_INCREF(value); /* _byref steals a refcount */