Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
42 lines
1.5 KiB
Erlang
42 lines
1.5 KiB
Erlang
-module(sandbox).
|
|
-export([eval_pure/2, eval_pure/3]).
|
|
|
|
%% Sandboxed evaluation of an Erlang fun.
|
|
%%
|
|
%% eval_pure/2(Fun, Arg) -> {ok, Result} | {error, Reason}
|
|
%% eval_pure/3(Fun, Arg1, Arg2) -> {ok, Result} | {error, Reason}
|
|
%%
|
|
%% The 3-arity variant matches the (Activity, State) -> NewState
|
|
%% shape of projection folds. The projection scheduler can wrap
|
|
%% every fold call in `sandbox:eval_pure(Fun, Act, State)` to
|
|
%% ensure a misbehaving fold body can't crash the projection
|
|
%% gen_server.
|
|
%%
|
|
%% v1 sandboxing is just the try/catch envelope: no gas budget,
|
|
%% no IO denial, no environment stripping. Real sandboxing lands
|
|
%% with SX-source eval (the fold body would then be an SX form
|
|
%% evaluated under the spec/harness platform). The API shape is
|
|
%% stable — callers don't need to change when that arrives.
|
|
|
|
%% Port note: this Erlang implementation catches by explicit
|
|
%% class names (throw, error, exit) rather than the open
|
|
%% `Class:Reason` pattern. The wrappers below enumerate the three.
|
|
|
|
eval_pure(Fun, Arg) ->
|
|
try Fun(Arg) of
|
|
Result -> {ok, Result}
|
|
catch
|
|
throw:Reason -> {error, {throw, Reason}};
|
|
error:Reason -> {error, {error, Reason}};
|
|
exit:Reason -> {error, {exit, Reason}}
|
|
end.
|
|
|
|
eval_pure(Fun, Arg1, Arg2) ->
|
|
try Fun(Arg1, Arg2) of
|
|
Result -> {ok, Result}
|
|
catch
|
|
throw:Reason -> {error, {throw, Reason}};
|
|
error:Reason -> {error, {error, Reason}};
|
|
exit:Reason -> {error, {exit, Reason}}
|
|
end.
|