diff --git a/Lib/test/test_ctypes/test_struct_fields.py b/Lib/test/test_ctypes/test_struct_fields.py index 5c713247a0f418..b50bbcbb65c423 100644 --- a/Lib/test/test_ctypes/test_struct_fields.py +++ b/Lib/test/test_ctypes/test_struct_fields.py @@ -1,6 +1,6 @@ import unittest import sys -from ctypes import Structure, Union, sizeof, c_char, c_int, CField +from ctypes import Structure, Union, sizeof, c_byte, c_char, c_int, CField from ._support import Py_TPFLAGS_IMMUTABLETYPE, StructCheckMixin @@ -75,6 +75,17 @@ def __init_subclass__(cls, **kwargs): 'ctypes state is not initialized'): class Subclass(BrokenStructure): ... + def test_invalid_byte_size_raises_gh132470(self): + with self.assertRaisesRegex(ValueError, r"does not match type size"): + CField( + name="a", + type=c_byte, + byte_size=2, # Wrong size: c_byte is only 1 byte + byte_offset=2, + index=1, + _internal_use=True + ) + def test_max_field_size_gh126937(self): # Classes for big structs should be created successfully. # (But they most likely can't be instantiated.) diff --git a/Misc/NEWS.d/next/C_API/2025-04-13-20-52-39.gh-issue-132470.UqBQjN.rst b/Misc/NEWS.d/next/C_API/2025-04-13-20-52-39.gh-issue-132470.UqBQjN.rst new file mode 100644 index 00000000000000..5a03908fb91f03 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2025-04-13-20-52-39.gh-issue-132470.UqBQjN.rst @@ -0,0 +1,2 @@ +Creating a :class:`ctypes.CField` with a *byte_size* that does not match the actual +type size now raises a :exc:`ValueError` instead of crashing the interpreter. diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 056e6dfd883a56..f486cfb6a92f25 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -99,7 +99,12 @@ PyCField_new_impl(PyTypeObject *type, PyObject *name, PyObject *proto, "type of field %R must be a C type", name); goto error; } - assert(byte_size == info->size); + if (byte_size != info->size) { + PyErr_Format(PyExc_ValueError, + "byte size of field %R (%zd) does not match type size (%zd)", + name, byte_size, info->size); + goto error; + } Py_ssize_t bitfield_size = 0; Py_ssize_t bit_offset = 0;