mirror of
https://github.com/python/cpython.git
synced 2026-01-06 23:42:34 +00:00
[3.13] gh-132673: Fix a crash with zero-alignment in ctypes.Structure (#132695)
This commit is contained in:
parent
38f305b9db
commit
47c8df6172
3 changed files with 40 additions and 2 deletions
|
|
@ -1,7 +1,7 @@
|
|||
from ctypes import (
|
||||
c_char, c_uint32, c_uint16, c_ubyte, c_byte, alignment, sizeof,
|
||||
BigEndianStructure, LittleEndianStructure,
|
||||
BigEndianUnion, LittleEndianUnion,
|
||||
BigEndianUnion, LittleEndianUnion, Structure
|
||||
)
|
||||
import struct
|
||||
import unittest
|
||||
|
|
@ -281,6 +281,41 @@ class Main(sbase):
|
|||
self.assertEqual(main.b.y, 3)
|
||||
self.assertEqual(main.c, 4)
|
||||
|
||||
def test_negative_align(self):
|
||||
for base in (Structure, LittleEndianStructure, BigEndianStructure):
|
||||
with (
|
||||
self.subTest(base=base),
|
||||
self.assertRaisesRegex(
|
||||
ValueError,
|
||||
'_align_ must be a non-negative integer',
|
||||
)
|
||||
):
|
||||
class MyStructure(base):
|
||||
_align_ = -1
|
||||
_fields_ = []
|
||||
|
||||
def test_zero_align_no_fields(self):
|
||||
for base in (Structure, LittleEndianStructure, BigEndianStructure):
|
||||
with self.subTest(base=base):
|
||||
class MyStructure(base):
|
||||
_align_ = 0
|
||||
_fields_ = []
|
||||
|
||||
self.assertEqual(alignment(MyStructure), 1)
|
||||
self.assertEqual(alignment(MyStructure()), 1)
|
||||
|
||||
def test_zero_align_with_fields(self):
|
||||
for base in (Structure, LittleEndianStructure, BigEndianStructure):
|
||||
with self.subTest(base=base):
|
||||
class MyStructure(base):
|
||||
_align_ = 0
|
||||
_fields_ = [
|
||||
("x", c_ubyte),
|
||||
]
|
||||
|
||||
self.assertEqual(alignment(MyStructure), 1)
|
||||
self.assertEqual(alignment(MyStructure()), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Fix a crash when using ``_align_ = 0`` and ``_fields_ = []`` in a
|
||||
:class:`ctypes.Structure`.
|
||||
|
|
@ -383,7 +383,7 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
|
|||
size = 0;
|
||||
align = 0;
|
||||
union_size = 0;
|
||||
total_align = forced_alignment;
|
||||
total_align = forced_alignment == 0 ? 1 : forced_alignment;
|
||||
stginfo->ffi_type_pointer.type = FFI_TYPE_STRUCT;
|
||||
stginfo->ffi_type_pointer.elements = PyMem_New(ffi_type *, len + 1);
|
||||
if (stginfo->ffi_type_pointer.elements == NULL) {
|
||||
|
|
@ -570,6 +570,7 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
|
|||
}
|
||||
|
||||
/* Adjust the size according to the alignment requirements */
|
||||
assert(total_align != 0);
|
||||
aligned_size = ((size + total_align - 1) / total_align) * total_align;
|
||||
|
||||
if (isStruct) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue