bpo-29753: fix merging packed bitfields in ctypes struct/union

When the structure is packed we should always expand when needed,
otherwise we will add some padding between the fields. This patch makes
sure we always merge bitfields together. It also changes the field merging
algorithm so that it handles bitfields correctly.

Signed-off-by: Filipe Laíns <lains@archlinux.org>
This commit is contained in:
Filipe Laíns 2020-05-01 19:01:02 +01:00
parent 40db798692
commit e435bfbdaa
No known key found for this signature in database
GPG Key ID: F893C674816AA95D
2 changed files with 14 additions and 4 deletions

View File

@ -0,0 +1,2 @@
Fixes packed bitfields not being calculated properly in some cases.
Fixes packed bitfileds not shrinking the first item.

View File

@ -87,7 +87,7 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
} else if (bitsize /* this is a bitfield request */
&& *pfield_size /* we have a bitfield open */
&& dict->size * 8 >= *pfield_size
&& (*pbitofs + bitsize) <= dict->size * 8) {
&& (((*pbitofs + bitsize) <= dict->size * 8) || pack)) {
/* expand bit field */
fieldtype = EXPAND_BITFIELD;
#endif
@ -172,10 +172,18 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
break;
case EXPAND_BITFIELD:
*poffset += dict->size - *pfield_size/8;
*psize += dict->size - *pfield_size/8;
if (pack) {
while(*pfield_size < (*pbitofs + bitsize)) {
*pfield_size += 8;
*poffset += 1;
*psize += 1;
}
} else {
*poffset += dict->size - *pfield_size/8;
*psize += dict->size - *pfield_size/8;
*pfield_size = dict->size * 8;
*pfield_size = dict->size * 8;
}
if (big_endian)
self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;