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
@ -1,6 +1,6 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import sys
|
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
|
from ._support import Py_TPFLAGS_IMMUTABLETYPE, StructCheckMixin
|
||||||
|
|
||||||
|
|
||||||
@ -75,6 +75,17 @@ class FieldsTestBase(StructCheckMixin):
|
|||||||
'ctypes state is not initialized'):
|
'ctypes state is not initialized'):
|
||||||
class Subclass(BrokenStructure): ...
|
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):
|
def test_max_field_size_gh126937(self):
|
||||||
# Classes for big structs should be created successfully.
|
# Classes for big structs should be created successfully.
|
||||||
# (But they most likely can't be instantiated.)
|
# (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);
|
"type of field %R must be a C type", name);
|
||||||
goto error;
|
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 bitfield_size = 0;
|
||||||
Py_ssize_t bit_offset = 0;
|
Py_ssize_t bit_offset = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user