You could wrap the untrusted expression in a let expression that binds
every dangerous identifier in the report environment to something safe
and then evaluate the wrapped expression in the report environment:
(eval `(let ((set! '(no can do))
(vector-set! '(no can do))
(set-car! '(no can do))
(display '(no can do))
... many more ...
(eval '(no can do)))
,untrusted-expression)
(scheme-report-environment 5))
Something like that. This will raise an error if any of those
identifiers are used in untrusted-expression in a way that would have
had an effect during the evaluation.
Or can we now create environments with just the bindings that we want
to allow? That might be nicer.
Here is one approach in PLT Scheme:
http://www.cs.brown.edu/courses/csci1730/2008/Manual/reference/Sandboxed_Evaluation.html
>Snyder writes:
>> Is there any Scheme (or other Lisp) implementation that allows for
>> side-effect free evaluation of expressions? Like, when I receive an
>> expression from an untrusted source and I want to compute just its
>> value and be safe from any side-effects (such as mutation, IO,
>> etc.).
[...]
>Or can we now create environments with just the bindings that we want
>to allow? That might be nicer.
Yes, in R6RS you can do this. The solution is to define a library with
only the bindings you want to use. You can then evaluate your code however
you like using:
(eval code (environment '(my safe environment)))
Chez Scheme also allows you to copy an environment, selectively taking
the bindings you want from it. Other Schemes give you similar features.
Aaron W. Hsu
Thanks. R6RS was what I meant by "now".