gh-62260: Fix ctypes.Structure subclassing with multiple layers (GH-13374)

The length field of StgDictObject for Structure class contains now
the total number of items in ffi_type_pointer.elements (excluding
the trailing null).

The old behavior of using the number of elements in the parent class can
cause the array to be truncated when it is copied, especially when there
are multiple layers of subclassing.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Jeffrey Kintscher 2024-01-01 08:24:24 -08:00 • committed by GitHub
parent 4036e48d59
commit 5f3cc90a12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 7 deletions

View file

@ -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)
@ -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) {
@ -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

View file

@ -695,7 +695,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
stgdict->size = aligned_size;
stgdict->align = total_align;
stgdict->length = len; /* ADD ffi_ofs? */
stgdict->length = ffi_ofs + len;
/*
* The value of MAX_STRUCT_SIZE depends on the platform Python is running on.