From 952de0d5bbda063b0458005e0ee1cbb247aea161 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 26 Apr 2017 19:45:20 -0700 Subject: 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. --- ffi.c | 17 +++++++++++------ 1 file 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; -- cgit v1.2.3