Skip to content

Commit e294757

Browse files
Correctly determine the size of StgDictObject.ffi_type_pointer.elements.
Now StgDictObject.length of Structure and Union is the number of all fields, including fields of superclases.
1 parent f7c01a1 commit e294757

File tree

2 files changed

+13
-23
lines changed

2 files changed

+13
-23
lines changed

Modules/_ctypes/_ctypes.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4354,10 +4354,10 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
43544354
return index;
43554355
}
43564356

4357-
for (i = 0;
4358-
i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
4357+
for (i = index;
4358+
i < dict->length && i < PyTuple_GET_SIZE(args);
43594359
++i) {
4360-
PyObject *pair = PySequence_GetItem(fields, i);
4360+
PyObject *pair = PySequence_GetItem(fields, i - index);
43614361
PyObject *name, *val;
43624362
int res;
43634363
if (!pair)
@@ -4367,7 +4367,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
43674367
Py_DECREF(pair);
43684368
return -1;
43694369
}
4370-
val = PyTuple_GET_ITEM(args, i + index);
4370+
val = PyTuple_GET_ITEM(args, i);
43714371
if (kwds) {
43724372
res = PyDict_Contains(kwds, name);
43734373
if (res != 0) {
@@ -4388,7 +4388,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
43884388
if (res == -1)
43894389
return -1;
43904390
}
4391-
return index + dict->length;
4391+
return dict->length;
43924392
}
43934393

43944394
static int

Modules/_ctypes/stgdict.c

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,7 @@ PyCStgDict_clone(StgDictObject *dst, StgDictObject *src)
119119

120120
if (src->ffi_type_pointer.elements == NULL)
121121
return 0;
122-
/* src->ffi_type_pointer.elements is an */
123-
/* array of pointers to ffi_type that */
124-
/* contains a trailing NULL pointer. */
125-
/* src->size is the size of the array */
126-
/* in bytes excluding the trailing NULL */
127-
/* pointer, so we have to add it in to */
128-
/* to compute how many bytes to copy. */
129-
size = src->size + max(sizeof(ffi_type *), src->align);
122+
size = sizeof(ffi_type *) * (src->length + 1);
130123
dst->ffi_type_pointer.elements = PyMem_Malloc(size);
131124
if (dst->ffi_type_pointer.elements == NULL) {
132125
PyErr_NoMemory();
@@ -380,7 +373,7 @@ int
380373
PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
381374
{
382375
StgDictObject *stgdict, *basedict;
383-
Py_ssize_t len, offset, size, align, i, base_len;
376+
Py_ssize_t len, offset, size, align, i;
384377
Py_ssize_t union_size, total_align, aligned_size;
385378
Py_ssize_t field_size = 0;
386379
int bitofs;
@@ -472,22 +465,19 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
472465
union_size = 0;
473466
total_align = align ? align : 1;
474467
stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
475-
/* calculate the cumulative number of elements in the base class */
476-
/* so that all elements get copied to the child class */
477-
base_len = size / max(sizeof(ffi_type *), align);
478-
stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, base_len + len + 1);
468+
stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1);
479469
if (stgdict->ffi_type_pointer.elements == NULL) {
480470
PyErr_NoMemory();
481471
return -1;
482472
}
483473
memset(stgdict->ffi_type_pointer.elements, 0,
484-
sizeof(ffi_type *) * (base_len + len + 1));
485-
if (size > 0) {
474+
sizeof(ffi_type *) * (basedict->length + len + 1));
475+
if (basedict->length > 0) {
486476
memcpy(stgdict->ffi_type_pointer.elements,
487477
basedict->ffi_type_pointer.elements,
488-
size);
478+
sizeof(ffi_type *) * (basedict->length));
489479
}
490-
ffi_ofs = base_len; /* index of the child class's first element */
480+
ffi_ofs = basedict->length;
491481
} else {
492482
offset = 0;
493483
size = 0;
@@ -705,7 +695,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
705695

706696
stgdict->size = aligned_size;
707697
stgdict->align = total_align;
708-
stgdict->length = len; /* the number of elements in the child class */
698+
stgdict->length = ffi_ofs + len;
709699

710700
/*
711701
* The value of MAX_STRUCT_SIZE depends on the platform Python is running on.

0 commit comments

Comments
 (0)