summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ffi.c6
-rw-r--r--gc.c14
-rw-r--r--gc.h2
-rw-r--r--txr.16
4 files changed, 27 insertions, 1 deletions
diff --git a/ffi.c b/ffi.c
index 84e891e5..d6326d4f 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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
diff --git a/gc.c b/gc.c
index cb67d156..ad3e25bc 100644
--- a/gc.c
+++ b/gc.c
@@ -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));
diff --git a/gc.h b/gc.h
index 1e67e723..326c5f87 100644
--- a/gc.h
+++ b/gc.h
@@ -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 *);
diff --git a/txr.1 b/txr.1
index ef497f22..a3277998 100644
--- a/txr.1
+++ b/txr.1
@@ -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