Skip to content

Commit

Permalink
Correctly determine the size of StgDictObject.ffi_type_pointer.elements.
Browse files Browse the repository at this point in the history
Now StgDictObject.length of Structure and Union is the number of all
fields, including fields of superclases.
  • Loading branch information
serhiy-storchaka committed Dec 26, 2023
1 parent f7c01a1 commit e294757
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 23 deletions.
10 changes: 5 additions & 5 deletions Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -4354,10 +4354,10 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
return index;
}

for (i = 0;
i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
for (i = index;
i < dict->length && i < PyTuple_GET_SIZE(args);
++i) {
PyObject *pair = PySequence_GetItem(fields, i);
PyObject *pair = PySequence_GetItem(fields, i - index);
PyObject *name, *val;
int res;
if (!pair)
Expand All @@ -4367,7 +4367,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
Py_DECREF(pair);
return -1;
}
val = PyTuple_GET_ITEM(args, i + index);
val = PyTuple_GET_ITEM(args, i);
if (kwds) {
res = PyDict_Contains(kwds, name);
if (res != 0) {
Expand All @@ -4388,7 +4388,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
if (res == -1)
return -1;
}
return index + dict->length;
return dict->length;
}

static int
Expand Down
26 changes: 8 additions & 18 deletions Modules/_ctypes/stgdict.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,7 @@ PyCStgDict_clone(StgDictObject *dst, StgDictObject *src)

if (src->ffi_type_pointer.elements == NULL)
return 0;
/* src->ffi_type_pointer.elements is an */
/* array of pointers to ffi_type that */
/* contains a trailing NULL pointer. */
/* src->size is the size of the array */
/* in bytes excluding the trailing NULL */
/* pointer, so we have to add it in to */
/* to compute how many bytes to copy. */
size = src->size + max(sizeof(ffi_type *), src->align);
size = sizeof(ffi_type *) * (src->length + 1);
dst->ffi_type_pointer.elements = PyMem_Malloc(size);
if (dst->ffi_type_pointer.elements == NULL) {
PyErr_NoMemory();
Expand Down Expand Up @@ -380,7 +373,7 @@ int
PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
{
StgDictObject *stgdict, *basedict;
Py_ssize_t len, offset, size, align, i, base_len;
Py_ssize_t len, offset, size, align, i;
Py_ssize_t union_size, total_align, aligned_size;
Py_ssize_t field_size = 0;
int bitofs;
Expand Down Expand Up @@ -472,22 +465,19 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
union_size = 0;
total_align = align ? align : 1;
stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
/* calculate the cumulative number of elements in the base class */
/* so that all elements get copied to the child class */
base_len = size / max(sizeof(ffi_type *), align);
stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, base_len + len + 1);
stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1);
if (stgdict->ffi_type_pointer.elements == NULL) {
PyErr_NoMemory();
return -1;
}
memset(stgdict->ffi_type_pointer.elements, 0,
sizeof(ffi_type *) * (base_len + len + 1));
if (size > 0) {
sizeof(ffi_type *) * (basedict->length + len + 1));
if (basedict->length > 0) {
memcpy(stgdict->ffi_type_pointer.elements,
basedict->ffi_type_pointer.elements,
size);
sizeof(ffi_type *) * (basedict->length));
}
ffi_ofs = base_len; /* index of the child class's first element */
ffi_ofs = basedict->length;
} else {
offset = 0;
size = 0;
Expand Down Expand Up @@ -705,7 +695,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct

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

/*
* The value of MAX_STRUCT_SIZE depends on the platform Python is running on.
Expand Down

0 comments on commit e294757

Please sign in to comment.