summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-26 19:45:20 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-26 19:45:20 -0700
commit952de0d5bbda063b0458005e0ee1cbb247aea161 (patch)
tree5b5d1209fa17bd61f929ebd7c131ceea429a362a
parent39c734f1a548f91b2559e6dacc3671153d818284 (diff)
downloadtxr-952de0d5bbda063b0458005e0ee1cbb247aea161.tar.gz
txr-952de0d5bbda063b0458005e0ee1cbb247aea161.tar.bz2
txr-952de0d5bbda063b0458005e0ee1cbb247aea161.zip
ffi: incorrect handling of struct element array.
* ffi.c (ffi_type_struct_destroy_op): Fix silly code. The size field most certainly doesn't indicate the number of elements, but rather the byte size. The array is documented by libffi as null-pointer terminated, so let's take advantage of that. (make_ffi_type_struct): Speaking of the array being null-terminated, it is we who are required to ensure this representation and we are not. Let's fix it. Also, we are here wrongly storing the number of elements into the struct type's size field, which is the basis for misusing that in the destroy op. The documentation says that the size field should be initialized to zero.
-rw-r--r--ffi.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/ffi.c b/ffi.c
index 911cf605..1ac342d0 100644
--- a/ffi.c
+++ b/ffi.c
@@ -131,10 +131,13 @@ static void ffi_type_struct_destroy_op(val obj)
ffi_type *ft = tft->ft;
if (ft != 0) {
- cnum size = ft->size, i;
-
- for (i = 0; i < size; i++)
- free(ft->elements[i]);
+ int i;
+ for (i = 0; ; i++) {
+ ffi_type *el = ft->elements[i];
+ if (!el)
+ break;
+ free(el);
+ }
ft->elements = 0;
}
@@ -781,13 +784,13 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
cnum nmemb = c_num(length(types)), i;
ffi_type **elements = coerce(ffi_type **, chk_malloc(sizeof *elements *
- nmemb));
+ (nmemb + 1)));
val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops);
cnum total_size = 0;
cnum most_align = 0;
ft->type = FFI_TYPE_STRUCT;
- ft->size = nmemb;
+ ft->size = 0;
tft->ft = ft;
tft->syntax = syntax;
@@ -812,6 +815,8 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
total_size = (total_size + align - 1) / align * align + size;
}
+ elements[i] = 0;
+
ft->elements = elements;
total_size = (total_size + most_align - 1) / most_align * most_align;