Skip to content

Commit 3b4b56f

Browse files
dura0oksobolevn
andauthored
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 <[email protected]>
1 parent f663b2c commit 3b4b56f

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

Lib/test/test_ctypes/test_struct_fields.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import unittest
22
import sys
3-
from ctypes import Structure, Union, sizeof, c_char, c_int, CField
3+
from ctypes import Structure, Union, sizeof, c_byte, c_char, c_int, CField
44
from ._support import Py_TPFLAGS_IMMUTABLETYPE, StructCheckMixin
55

66

@@ -75,6 +75,17 @@ def __init_subclass__(cls, **kwargs):
7575
'ctypes state is not initialized'):
7676
class Subclass(BrokenStructure): ...
7777

78+
def test_invalid_byte_size_raises_gh132470(self):
79+
with self.assertRaisesRegex(ValueError, r"does not match type size"):
80+
CField(
81+
name="a",
82+
type=c_byte,
83+
byte_size=2, # Wrong size: c_byte is only 1 byte
84+
byte_offset=2,
85+
index=1,
86+
_internal_use=True
87+
)
88+
7889
def test_max_field_size_gh126937(self):
7990
# Classes for big structs should be created successfully.
8091
# (But they most likely can't be instantiated.)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Creating a :class:`ctypes.CField` with a *byte_size* that does not match the actual
2+
type size now raises a :exc:`ValueError` instead of crashing the interpreter.

Modules/_ctypes/cfield.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,12 @@ PyCField_new_impl(PyTypeObject *type, PyObject *name, PyObject *proto,
9999
"type of field %R must be a C type", name);
100100
goto error;
101101
}
102-
assert(byte_size == info->size);
102+
if (byte_size != info->size) {
103+
PyErr_Format(PyExc_ValueError,
104+
"byte size of field %R (%zd) does not match type size (%zd)",
105+
name, byte_size, info->size);
106+
goto error;
107+
}
103108

104109
Py_ssize_t bitfield_size = 0;
105110
Py_ssize_t bit_offset = 0;

0 commit comments

Comments
 (0)