import unittest
+import sys
from ctypes import Structure, Union, sizeof, c_char, c_int
from ._support import (CField, Py_TPFLAGS_DISALLOW_INSTANTIATION,
Py_TPFLAGS_IMMUTABLETYPE)
'ctypes state is not initialized'):
class Subclass(BrokenStructure): ...
+ def test_max_field_size_gh126937(self):
+ # Classes for big structs should be created successfully.
+ # (But they most likely can't be instantiated.)
+ # Here we test the exact limit: the number of *bits* must fit
+ # in Py_ssize_t.
+
+ class X(self.cls):
+ _fields_ = [('char', c_char),]
+ max_field_size = sys.maxsize // 8
+
+ class Y(self.cls):
+ _fields_ = [('largeField', X * max_field_size)]
+ class Z(self.cls):
+ _fields_ = [('largeField', c_char * max_field_size)]
+
+ with self.assertRaises(ValueError):
+ class TooBig(self.cls):
+ _fields_ = [('largeField', X * (max_field_size + 1))]
+ with self.assertRaises(ValueError):
+ class TooBig(self.cls):
+ _fields_ = [('largeField', c_char * (max_field_size + 1))]
+
# __set__ and __get__ should raise a TypeError in case their self
# argument is not a ctype instance.
def test___set__(self):
goto error;
}
- Py_ssize_t bit_size = NUM_BITS(size);
- if (bit_size) {
+ if (bit_size_obj != Py_None) {
+#ifdef Py_DEBUG
+ Py_ssize_t bit_size = NUM_BITS(size);
assert(bit_size > 0);
assert(bit_size <= info->size * 8);
+ // Currently, the bit size is specified redundantly
+ // in NUM_BITS(size) and bit_size_obj.
+ // Verify that they match.
+ assert(PyLong_AsSsize_t(bit_size_obj) == bit_size);
+#endif
switch(info->ffi_type_pointer.type) {
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
if (!tmp) {
goto error;
}
- Py_ssize_t total_align = PyLong_AsInt(tmp);
+ Py_ssize_t total_align = PyLong_AsSsize_t(tmp);
Py_DECREF(tmp);
if (total_align < 0) {
if (!PyErr_Occurred()) {
if (!tmp) {
goto error;
}
- Py_ssize_t total_size = PyLong_AsInt(tmp);
+ Py_ssize_t total_size = PyLong_AsSsize_t(tmp);
Py_DECREF(tmp);
if (total_size < 0) {
if (!PyErr_Occurred()) {