]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-132470: Prevent crash in ctypes.CField when `byte_size` is incorrect (#132475)
authordura0ok <slpmcf@gmail.com>
Tue, 22 Apr 2025 13:13:00 +0000 (20:13 +0700)
committerGitHub <noreply@github.com>
Tue, 22 Apr 2025 13:13:00 +0000 (16:13 +0300)
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 <mail@sobolevn.me>
Lib/test/test_ctypes/test_struct_fields.py
Misc/NEWS.d/next/C_API/2025-04-13-20-52-39.gh-issue-132470.UqBQjN.rst [new file with mode: 0644]
Modules/_ctypes/cfield.c

index 5c713247a0f41805801c4a87269e4f9257cd4053..b50bbcbb65c4233865be8ba86c25f17f4bf93669 100644 (file)
@@ -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 @@ class FieldsTestBase(StructCheckMixin):
                                     '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 (file)
index 0000000..5a03908
--- /dev/null
@@ -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.
index ec35686f2513206c0dcf6bc29a37167e9732a257..6b63a08ed6eaa1bf6ede21cbc988a16efa9a6412 100644 (file)
@@ -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;