From 8617d769fa1f2e79a58ff25acfef22cba7c1e79c Mon Sep 17 00:00:00 2001 From: VanshAgarwal24036 Date: Wed, 21 Jan 2026 19:40:05 +0530 Subject: [PATCH 1/2] gh-144100: Fix crash for POINTER(str) used in ctypes argtypes --- Lib/test/test_ctypes/test_pointers.py | 18 ++++++++++++++++++ ...6-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst | 3 +++ Modules/_ctypes/_ctypes.c | 8 +++++++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst diff --git a/Lib/test/test_ctypes/test_pointers.py b/Lib/test/test_ctypes/test_pointers.py index a8d243a45de0f4..65ba008a8fd327 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): + + 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 */ From bda79212cb60cc5f4cd44309df05aa8d2f7bed2c Mon Sep 17 00:00:00 2001 From: VanshAgarwal24036 Date: Wed, 21 Jan 2026 20:17:37 +0530 Subject: [PATCH 2/2] Test corrected --- Lib/test/test_ctypes/test_pointers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_ctypes/test_pointers.py b/Lib/test/test_ctypes/test_pointers.py index 65ba008a8fd327..7cd99a19dbb770 100644 --- a/Lib/test/test_ctypes/test_pointers.py +++ b/Lib/test/test_ctypes/test_pointers.py @@ -475,8 +475,8 @@ class C(Structure): class TestPointerStringProto(unittest.TestCase): def test_pointer_string_proto_argtypes_error(self): - - BadType = ctypes.POINTER("BugTrigger") + with self.assertWarns(DeprecationWarning): + BadType = ctypes.POINTER("BugTrigger") if os.name == "nt": libc = ctypes.WinDLL("kernel32.dll")