diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-07-27 08:08:02 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-07-27 08:08:02 -0700 |
commit | 72c116a11ca38a5edc84790404b8439796b4c40c (patch) | |
tree | ef4826d89bbd360db644fe51cd855012f475eee1 /ffi.c | |
parent | 87456836e1bd7d1e35a92d55a830e1c1f1f7ccff (diff) | |
download | txr-72c116a11ca38a5edc84790404b8439796b4c40c.tar.gz txr-72c116a11ca38a5edc84790404b8439796b4c40c.tar.bz2 txr-72c116a11ca38a5edc84790404b8439796b4c40c.zip |
FFI: bugfix: pointer "in" ops must map null to nil.
* ffi.c (ffi_ptr_in_in, ffi_ptr_in_d_in, ffi_ptr_out_in,
ffi_ptr_out_s_in): If the memory location which holds the
pointer to the C object is null, then just return nil.
If we don't do this, we then crash trying to extract
the object from a null pointer via the recursive tgtft->in or
tgtft->get call.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 8 |
1 files changed, 8 insertions, 0 deletions
@@ -1895,6 +1895,8 @@ static val ffi_ptr_in_in(struct txr_ffi_type *tft, int copy, mem_t *src, val tgttype = tft->eltype; struct txr_ffi_type *tgtft = ffi_type_struct(tgttype); mem_t **loc = coerce(mem_t **, src); + if (!*loc) + return nil; if (tgtft->in != 0 && tgtft->by_value_in) tgtft->in(tgtft, 0, *loc, obj, self); tgtft->free(*loc); @@ -1908,6 +1910,8 @@ static val ffi_ptr_in_d_in(struct txr_ffi_type *tft, int copy, mem_t *src, val tgttype = tft->eltype; struct txr_ffi_type *tgtft = ffi_type_struct(tgttype); mem_t **loc = coerce(mem_t **, src); + if (!*loc) + return nil; if (tgtft->in != 0 && tgtft->by_value_in) tgtft->in(tgtft, 0, *loc, obj, self); return obj; @@ -1930,6 +1934,8 @@ static val ffi_ptr_out_in(struct txr_ffi_type *tft, int copy, mem_t *src, val tgttype = tft->eltype; struct txr_ffi_type *tgtft = ffi_type_struct(tgttype); mem_t **loc = coerce(mem_t **, src); + if (!*loc) + return nil; if (tgtft->in != 0) obj = tgtft->in(tgtft, 1, *loc, obj, self); else @@ -2009,6 +2015,8 @@ static val ffi_ptr_out_s_in(struct txr_ffi_type *tft, int copy, val tgttype = tft->eltype; struct txr_ffi_type *tgtft = ffi_type_struct(tgttype); mem_t **loc = coerce(mem_t **, src); + if (!*loc) + return nil; if (tgtft->in != 0) obj = tgtft->in(tgtft, 1, *loc, obj, self); else |