[pypy-commit] cffi calculate_variable_array_length: When using a variable length struct, calculate and enforce the length of the varsized_array when accessing this field.
coronafire
pypy.commits at gmail.com
Wed Oct 19 02:53:32 EDT 2016
Author: Andrew Leech <andrew at alelec.net>
Branch: calculate_variable_array_length
Changeset: r2789:d269f72d4a9a
Date: 2016-09-13 09:19 +1000
http://bitbucket.org/cffi/cffi/changeset/d269f72d4a9a/
Log: When using a variable length struct, calculate and enforce the
length of the varsized_array when accessing this field.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -906,6 +906,23 @@
return (PyObject *)cd;
}
+static PyObject *
+new_sized_cdata(char *data, CTypeDescrObject *ct, Py_ssize_t length)
+{
+ CDataObject_own_length *scd;
+
+ scd = (CDataObject_own_length *)PyObject_Malloc(
+ offsetof(CDataObject_own_length, alignment));
+ if (PyObject_Init((PyObject *)scd, &CData_Type) == NULL)
+ return NULL;
+ Py_INCREF(ct);
+ scd->head.c_type = ct;
+ scd->head.c_data = data;
+ scd->head.c_weakreflist = NULL;
+ scd->length = length;
+ return (PyObject *)scd;
+}
+
static CDataObject *_new_casted_primitive(CTypeDescrObject *ct); /*forward*/
static PyObject *
@@ -2387,7 +2404,15 @@
if (cf != NULL) {
/* read the field 'cf' */
char *data = cd->c_data + cf->cf_offset;
- if (cf->cf_bitshift == BS_REGULAR)
+
+ if ((cd->c_type->ct_flags & CT_IS_PTR_TO_OWNED) && // Is owned struct (or union)
+ (cf->cf_type->ct_flags & CT_ARRAY) && // field is an array
+ (cf->cf_type->ct_size == -1)) { // unknown length array
+ /* if reading variable length array from variable length struct, calculate array type from allocated length*/
+ Py_ssize_t array_len = (((CDataObject_own_structptr *)cd)->length - ct->ct_size) / cf->cf_type->ct_itemdescr->ct_size;
+ return new_sized_cdata(data, cf->cf_type, array_len);
+ }
+ else if (cf->cf_bitshift == BS_REGULAR)
return convert_to_object(data, cf->cf_type);
else if (cf->cf_bitshift == BS_EMPTY_ARRAY)
return new_simple_cdata(data,
More information about the pypy-commit
mailing list