https://github.com/python/cpython/commit/3b4b56f46dbfc0c336a1f70704f127593ec1f4ce commit: 3b4b56f46dbfc0c336a1f70704f127593ec1f4ce branch: main author: dura0ok <slp...@gmail.com> committer: sobolevn <m...@sobolevn.me> date: 2025-04-22T16:13:00+03:00 summary:
gh-132470: Prevent crash in ctypes.CField when `byte_size` is incorrect (#132475) Fix: Prevent crash in ctypes.CField when byte_size does not match type size (gh-132470) When creating a ctypes.CField with an incorrect byte_size (e.g., using `byte_size=2` for `ctypes.c_byte`), the code would previously abort due to the failed assertion `byte_size == info->size`. This commit replaces the assertion with a proper error handling mechanism that raises a `ValueError` when `byte_size` does not match the expected type size. This prevents the crash and provides a more informative error message to the us Co-authored-by: sobolevn <m...@sobolevn.me> files: A Misc/NEWS.d/next/C_API/2025-04-13-20-52-39.gh-issue-132470.UqBQjN.rst M Lib/test/test_ctypes/test_struct_fields.py M Modules/_ctypes/cfield.c 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 ec35686f251320..6b63a08ed6eaa1 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; _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com