mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
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 <mail@sobolevn.me>
This commit is contained in:
parent
f663b2c56a
commit
3b4b56f46d
3 changed files with 20 additions and 2 deletions
|
@ -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.)
|
||||
|
|
|
@ -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.
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue