@@ -301,13 +301,24 @@ static int __Pyx_SetPackagePathFromImportLib(PyObject *module_name) {
301301#ifndef __PYX_HAVE_RT_ImportType_proto
302302#define __PYX_HAVE_RT_ImportType_proto
303303
304+ #if __STDC_VERSION__ >= 201112L
305+ #include <stdalign.h>
306+ #endif
307+
308+ #if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
309+ #define __PYX_GET_STRUCT_ALIGNMENT (s ) alignof(s)
310+ #else
311+ // best guess at what the alignment could be since we can't measure it
312+ #define __PYX_GET_STRUCT_ALIGNMENT (s ) sizeof(void*)
313+ #endif
314+
304315enum __Pyx_ImportType_CheckSize {
305316 __Pyx_ImportType_CheckSize_Error = 0 ,
306317 __Pyx_ImportType_CheckSize_Warn = 1 ,
307318 __Pyx_ImportType_CheckSize_Ignore = 2
308319};
309320
310- static PyTypeObject * __Pyx_ImportType (PyObject * module , const char * module_name , const char * class_name , size_t size , enum __Pyx_ImportType_CheckSize check_size ); /*proto*/
321+ static PyTypeObject * __Pyx_ImportType (PyObject * module , const char * module_name , const char * class_name , size_t size , size_t alignment , enum __Pyx_ImportType_CheckSize check_size ); /*proto*/
311322
312323#endif
313324
@@ -316,13 +327,15 @@ static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name,
316327#ifndef __PYX_HAVE_RT_ImportType
317328#define __PYX_HAVE_RT_ImportType
318329static PyTypeObject * __Pyx_ImportType (PyObject * module , const char * module_name , const char * class_name ,
319- size_t size , enum __Pyx_ImportType_CheckSize check_size )
330+ size_t size , size_t alignment , enum __Pyx_ImportType_CheckSize check_size )
320331{
321332 PyObject * result = 0 ;
322333 char warning [200 ];
323334 Py_ssize_t basicsize ;
335+ Py_ssize_t itemsize ;
324336#ifdef Py_LIMITED_API
325337 PyObject * py_basicsize ;
338+ PyObject * py_itemsize ;
326339#endif
327340
328341 result = PyObject_GetAttrString (module , class_name );
@@ -336,6 +349,7 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name,
336349 }
337350#ifndef Py_LIMITED_API
338351 basicsize = ((PyTypeObject * )result )-> tp_basicsize ;
352+ itemsize = ((PyTypeObject * )result )-> tp_itemsize ;
339353#else
340354 py_basicsize = PyObject_GetAttrString (result , "__basicsize__" );
341355 if (!py_basicsize )
@@ -345,8 +359,28 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name,
345359 py_basicsize = 0 ;
346360 if (basicsize == (Py_ssize_t )- 1 && PyErr_Occurred ())
347361 goto bad ;
362+ py_itemsize = PyObject_GetAttrString (result , "__itemsize__" );
363+ if (!py_itemsize )
364+ goto bad ;
365+ itemsize = PyLong_AsSsize_t (py_itemsize );
366+ Py_DECREF (py_itemsize );
367+ py_itemsize = 0 ;
368+ if (itemsize == (Py_ssize_t )- 1 && PyErr_Occurred ())
369+ goto bad ;
348370#endif
349- if ((size_t )basicsize < size ) {
371+ if (itemsize ) {
372+ // If itemsize is smaller than the alignment the struct can end up with some extra
373+ // padding at the end. In this case we need to work out the maximum size that
374+ // the padding could be when calculating the range of valid struct sizes.
375+ if (size % alignment ) {
376+ // if this is true we've probably calculated the alignment wrongly
377+ // (most likely because alignof isn't available)
378+ alignment = size % alignment ;
379+ }
380+ if (itemsize < (Py_ssize_t )alignment )
381+ itemsize = (Py_ssize_t )alignment ;
382+ }
383+ if ((size_t )(basicsize + itemsize ) < size ) {
350384 PyErr_Format (PyExc_ValueError ,
351385 "%.200s.%.200s size changed, may indicate binary incompatibility. "
352386 "Expected %zd from C header, got %zd from PyObject" ,
0 commit comments