bpo-29753: fix merging packed bitfields in ctypes struct/union (GH-19… · python/cpython@0d7ad9f (original) (raw)
`@@ -71,6 +71,18 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
`
71
71
`Py_DECREF(self);
`
72
72
`return NULL;
`
73
73
` }
`
``
74
+
``
75
`+
#ifndef MS_WIN32
`
``
76
`+
/* if we have a packed bitfield, calculate the minimum number of bytes we
`
``
77
`+
need to fit it. otherwise use the specified size. */
`
``
78
`+
if (pack && bitsize) {
`
``
79
`+
size = (bitsize - 1) / 8 + 1;
`
``
80
`+
} else
`
``
81
`+
#endif
`
``
82
`+
size = dict->size;
`
``
83
+
``
84
`+
proto = desc;
`
``
85
+
74
86
`if (bitsize /* this is a bitfield request */
`
75
87
`&& pfield_size / we have a bitfield open */
`
76
88
`#ifdef MS_WIN32
`
`@@ -87,25 +99,26 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
`
87
99
` } else if (bitsize /* this is a bitfield request */
`
88
100
`&& pfield_size / we have a bitfield open */
`
89
101
`&& dict->size * 8 >= *pfield_size
`
90
``
`-
&& (*pbitofs + bitsize) <= dict->size * 8) {
`
``
102
`+
/* if this is a packed bitfield, always expand it.
`
``
103
`+
otherwise calculate if we need to expand it. */
`
``
104
`+
&& (((*pbitofs + bitsize) <= dict->size * 8) || pack)) {
`
91
105
`/* expand bit field */
`
92
106
`fieldtype = EXPAND_BITFIELD;
`
93
107
`#endif
`
94
108
` } else if (bitsize) {
`
95
109
`/* start new bitfield */
`
96
110
`fieldtype = NEW_BITFIELD;
`
97
111
`*pbitofs = 0;
`
98
``
`-
*pfield_size = dict->size * 8;
`
``
112
`+
/* use our calculated size (size) instead of type size (dict->size),
`
``
113
`+
which can be different for packed bitfields */
`
``
114
`+
*pfield_size = size * 8;
`
99
115
` } else {
`
100
116
`/* not a bit field */
`
101
117
`fieldtype = NO_BITFIELD;
`
102
118
`*pbitofs = 0;
`
103
119
`*pfield_size = 0;
`
104
120
` }
`
105
121
``
106
``
`-
size = dict->size;
`
107
``
`-
proto = desc;
`
108
``
-
109
122
`/* Field descriptors for 'c_char * n' are be scpecial cased to
`
110
123
` return a Python string instead of an Array object instance...
`
111
124
` */
`
`@@ -170,10 +183,16 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
`
170
183
`break;
`
171
184
``
172
185
`case EXPAND_BITFIELD:
`
173
``
`-
*poffset += dict->size - *pfield_size/8;
`
174
``
`-
*psize += dict->size - *pfield_size/8;
`
``
186
`+
/* increase the size if it is a packed bitfield.
`
``
187
`+
EXPAND_BITFIELD should not be selected for non-packed fields if the
`
``
188
`+
current size isn't already enough. */
`
``
189
`+
if (pack)
`
``
190
`+
size = (*pbitofs + bitsize - 1) / 8 + 1;
`
``
191
+
``
192
`+
*poffset += size - *pfield_size/8;
`
``
193
`+
*psize += size - *pfield_size/8;
`
175
194
``
176
``
`-
*pfield_size = dict->size * 8;
`
``
195
`+
*pfield_size = size * 8;
`
177
196
``
178
197
`if (big_endian)
`
179
198
`self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
`