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

Reply via email to