summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-07-11 06:36:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-07-11 06:36:21 -0700
commit46ae35f5b87efa3582aa8564839b30acbeeffe57 (patch)
tree246307d3b288bafd836c94e26c34a0df37c703be /txr.1
parent22a0514369a0a377f8c5d40675fea68adaf1d333 (diff)
downloadtxr-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.122
1 files changed, 19 insertions, 3 deletions
diff --git a/txr.1 b/txr.1
index ef91d850..8f826635 100644
--- a/txr.1
+++ b/txr.1
@@ -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 )