diff options
-rw-r--r-- | ffi.c | 6 | ||||
-rw-r--r-- | gc.c | 14 | ||||
-rw-r--r-- | gc.h | 2 | ||||
-rw-r--r-- | txr.1 | 6 |
4 files changed, 27 insertions, 1 deletions
@@ -565,7 +565,11 @@ static void ffi_val_put(struct txr_ffi_type *tft, val v, mem_t *dst, val self) static val ffi_val_get(struct txr_ffi_type *tft, mem_t *src, val self) { - return *coerce(val *, src); + val v = *coerce(val *, src); + if (!valid_object_p(v)) + uw_throwf(error_s, lit("~a: bit pattern ~0,0*x isn't a valid Lisp object"), + self, num_fast(sizeof (v) * 2), bits(v), nao); + return v; } #if SIZEOF_WCHAR_T == SIZEOF_SHORT @@ -911,6 +911,20 @@ val gc_call_finalizers(val obj) return call_finalizers_impl(obj, is_matching_final); } +val valid_object_p(val obj) +{ + if (!is_ptr(obj)) + return t; + + if (!in_heap(obj)) + return nil; + + if (obj->t.type & (REACHABLE | FREE)) + return nil; + + return t; +} + void gc_late_init(void) { reg_fun(intern(lit("gc"), system_package), func_n0(gc_wrap)); @@ -47,6 +47,8 @@ val gc_mutated(val); extern int full_gc; #endif +val valid_object_p(val obj); + void unmark(void); void gc_cancel(void); void gc_hint_func(val *); @@ -53414,6 +53414,12 @@ values that aren't objects which came from a Lisp heap. Interpreting a Lisp value in foreign code requires a correct decoding of its type tag, and, if necessary, stripping the tag bits to recover a heap pointer and interpreting the type code stored in the heap object. + +The conversion from foreign bit pattern to Lisp value is subject to a +validity checks; an exception will be thrown if the bit pattern isn't a valid +Lisp object. Nevertheless, the checks has cases which report as false +positives: admit some invalid objects may be admitted into the Lisp realm, +possibly with catastrophic results. .ccIP @ cptr This type corresponds to a C pointer of any type, including a function pointer; \*(TX doesn't run on any exotic platforms in which there is a representational |