diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-07-11 06:36:21 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-07-11 06:36:21 -0700 |
commit | 46ae35f5b87efa3582aa8564839b30acbeeffe57 (patch) | |
tree | 246307d3b288bafd836c94e26c34a0df37c703be /txr.1 | |
parent | 22a0514369a0a377f8c5d40675fea68adaf1d333 (diff) | |
download | txr-46ae35f5b87efa3582aa8564839b30acbeeffe57.tar.gz txr-46ae35f5b87efa3582aa8564839b30acbeeffe57.tar.bz2 txr-46ae35f5b87efa3582aa8564839b30acbeeffe57.zip |
ffi: handle variable length types in buffer ops.
The motivating bug here is that
(ffi-put #(1 2 3 5) (ffi (array int)))
perpetrates a buffer overrun. The size of (array int) is zero,
and so a zero-length buffer is allocated. But then an array of
five ints is stored. This is made to work correctly:
allocating a buffer large enough.
A new virtual function is introduced into the txr_ffi_type
structure to calculate a type's dynamic size, from a prototype
Lisp object.
* ffi.c (struct txr_ffi_type): New function pointer member,
dynsize.
(ffi_fixed_dynsize, ffi_varray_dynsize): New static functions.
(make_ffi_type_builtin, make_ffi_type_pointer,
make_ffi_type_struct, make_ffi_type_union,
make_ffi_type_array): Initialize new dynsize member of type
structure with pointer to ffi_fixed_dynsize.
(ffi_type_compile): Initialize the dynsize pointer of variable
array types to ffi_varray_dynsize.
(ffi_put_into, ffi_put, ffi_in, ffi_out): Use dynsize to
calculate the real size required to store or extract the given
object.
* txr.1: Update doc for ffi-put, ffi-put-into and ffi-in.
Looks like we are missing ffi-out; it is not documented!
Diffstat (limited to 'txr.1')
-rw-r--r-- | txr.1 | 22 |
1 files changed, 19 insertions, 3 deletions
@@ -64622,6 +64622,12 @@ The .meta type argument must be a compiled FFI type. +If +.meta type +is has a variable length, then the actual size of the foreign representation is +calculated from +.metn obj . + The .meta obj argument must be an object compatible with the conversions @@ -64639,15 +64645,14 @@ is stored. The default value is zero. These functions perform the "put semantics" encoding action very similar to what happens to the arguments of an outgoing foreign function call. + Caution: incorrect use of this this function, or its use in isolation without a matching .code ffi-in call, can cause memory leaks, because, depending on .metn type , temporary resources may be allocated, and pointers to those resources -will be stored in the buffer. \*(TX's garbage collector doesn't know -about these resources; it doesn't traverse buffer contents looking for -pointers, and those pointers aren't references to Lisp heap objects anyway. +will be stored in the buffer. .coNP Function @ ffi-in .synb @@ -64706,6 +64711,12 @@ but that structure can have pointers to objects which are updated by the called function. Those indirect objects are passed by pointer. They get updated, but the parent structure cannot. +If +.meta type +is has a variable length, then the actual size of the foreign representation is +calculated from +.metn obj . + The .code ffi-in function returns either @@ -64753,6 +64764,11 @@ in order to extract the return value of foreign function calls, and by the FFI callback mechanism to extract the arguments coming into a callback. +The +.meta type +argument may not be a variable length type, such as an array of +unspecified size. + .coNP Functions @ file-get-buf and @ command-get-buf .synb .mets (file-get-buf << name ) |