sandbox v0.5.0 Sandbox View Source

--- Warning ---

This library is under heavy development and will have breaking changes until the 1.0.0 release.

Sandbox provides restricted, isolated scripting environments for Elixir through the use of embedded Lua.

This project is powered by Robert Virding's amazing Luerl, an Erlang library that lets one execute Lua scripts on the BEAM.

Luerl executes Lua code without running a Lua VM as a separate application! Rather, the state of the VM is used as a data structure that can be externally manipulated and processed.

The :luerl_sandbox module is utilized wherever possible. This limits access to dangerous core libraries. It also permits Lua scripts to be run with enforced CPU reduction limits. To work with Lua's full library, use Sandbox.unsafe_init/0 as opposed to Sandbox.init/0.

Conventions followed in this library:

  • Functions beginning with eval return a result from Lua.
  • Functions starting with play return a new Lua state.
  • Functions preceded by run return a tuple of {result, new_state}
  • All functions return ok-error tuples such as {:ok, value} or {:error, reason} unless followed by a bang.
  • Elixir functions exposed to Lua take two arguments: a Lua state and a list of Lua arguments. They should return a value corresponding to the eval, play or run responses.
  • The max_reductions argument defaults to 0, corresponding to unlimited reductions.

Link to this section Summary

Types

An Elixir function that can be invoked through Lua. It takes a Lua state and a list of Lua arguments and returns a result. The Lua state acts as a context but is not modified.

An Elixir function that can be invoked through Lua. It takes a Lua state and a list of Lua arguments and returns a new Lua state. The result of this function is not exposed to Lua.

An Elixir function that can be invoked through Lua. It takes a Lua state and a list of Lua arguments and returns a tuple containing a result and a new Lua state.

Compiled Lua code that can be transferred between Lua states.

Lua code as either a raw string or compile chunk.

A dot-delimited name or list of names representing a table path in Lua such as math.floor or ["math", "floor"].

The representation of an entire Lua virtual machine and its current state.

Lua values represented as Elixir data structures.

Functions

Create a compiled chunk of Lua code that can be transferred between Lua states, returned in an ok-error tuple.

Same as chunk/2, but will return the raw result or raise a RuntimeError.

Evaluates a Lua string or chunk against the given Lua state and returns the result in an ok-error tuple. The state itself is not modified.

Same as eval/3, but will return the raw result or raise a RuntimeError.

Evaluates a Lua file against the given Lua state and returns the result in an ok-error tuple. The state itself is not modified.

Same as eval_file/3, but will return the raw result or raise a RuntimeError.

Calls a function defined in the the Lua state and returns only the result. The state itself is not modified. Lua functions in the Lua state can be referenced by their lua_path, being a string or list such as math.floor or ["math", "floor"].

Gets a value from a Lua state.

Creates a Lua state with "dangerous" core library features such as file IO and networking removed.

Returns a Lua state modified to include an Elixir function, elixir_eval_fun(), at the given lua_path().

Returns a Lua state modified to include an Elixir function, elixir_play_fun(), at the given lua_path().

Returns a Lua state modified to include an Elixir function, elixir_run_fun(), at the given lua_path().

Runs a Lua string or chunk against a Lua state and returns a new Lua state in an ok-error tuple.

Same as play/3, but will return the raw result or raise a RuntimeError.

Runs a Lua file in the context of a Lua state and returns a new Lua state.

Runs a Lua function defined in the given Lua state and returns a new Lua state.

Runs a Lua string or chunk against the given Lua state and returns the result and the new Lua state in an ok-error tuple.

Same as run/3, but will return the raw {result, state} or raise a RuntimeError.

Runs a function defined in the the Lua state and returns the result and the new Lua state as {result, state}. Lua functions in the Lua state can be referenced by their lua_path, a string or list such as math.floor or ["math", "floor"].

Sets a value in a Lua state and returns the modified state. If force is set to true, new tables will be created automatically if they missing from the given lua_path.

Creates a Lua state with access to Lua's standard library. The max_reductions feature of Sandbox is still available, but "dangerous" core library features such as file IO and networking are still available.

Link to this section Types

Link to this type

elixir_eval_fun()

View Source
elixir_eval_fun() :: (lua_state(), [lua_value()] -> any())

An Elixir function that can be invoked through Lua. It takes a Lua state and a list of Lua arguments and returns a result. The Lua state acts as a context but is not modified.

Link to this type

elixir_play_fun()

View Source
elixir_play_fun() :: (lua_state(), [lua_value()] -> lua_state())

An Elixir function that can be invoked through Lua. It takes a Lua state and a list of Lua arguments and returns a new Lua state. The result of this function is not exposed to Lua.

Link to this type

elixir_run_fun()

View Source
elixir_run_fun() :: (lua_state(), [lua_value()] -> {any(), lua_state()})

An Elixir function that can be invoked through Lua. It takes a Lua state and a list of Lua arguments and returns a tuple containing a result and a new Lua state.

Link to this type

lua_chunk()

View Source
lua_chunk() :: {:lua_func, any(), any(), any(), any(), any()}

Compiled Lua code that can be transferred between Lua states.

Lua code as either a raw string or compile chunk.

Link to this type

lua_path()

View Source
lua_path() :: String.t() | [String.t()]

A dot-delimited name or list of names representing a table path in Lua such as math.floor or ["math", "floor"].

Link to this type

lua_state()

View Source
lua_state() ::
  {:luerl, any(), any(), any(), any(), any(), any(), any(), any(),
   any(), any(), any(), any(), any(), any()}

The representation of an entire Lua virtual machine and its current state.

Link to this type

lua_value()

View Source
lua_value() :: number() | String.t() | [tuple()] | nil

Lua values represented as Elixir data structures.

Link to this section Functions

Link to this function

chunk(state, code)

View Source
chunk(lua_state(), lua_code()) :: {:ok, lua_chunk()} | {:error, any()}

Create a compiled chunk of Lua code that can be transferred between Lua states, returned in an ok-error tuple.

Same as chunk/2, but will return the raw result or raise a RuntimeError.

Link to this function

eval(state, code, max_reductions \\ 0)

View Source
eval(lua_state(), lua_code(), non_neg_integer()) ::
  {:ok, lua_value()} | {:error, any()}

Evaluates a Lua string or chunk against the given Lua state and returns the result in an ok-error tuple. The state itself is not modified.

Examples

iex> Sandbox.init() |> Sandbox.eval("return 3 + 4")
{:ok, 7.0}

iex> Sandbox.init() |> Sandbox.eval("return math.floor(9.9)")
{:ok, 9.0}
Link to this function

eval!(state, code, max_reductions \\ 0)

View Source

Same as eval/3, but will return the raw result or raise a RuntimeError.

Examples

iex> Sandbox.init() |> Sandbox.eval!("return 3 + 4")
7.0

iex> Sandbox.init() |> Sandbox.eval!("return math.floor(9.9)")
9.0
Link to this function

eval_file(state, file_path, max_reductions \\ 0)

View Source
eval_file(lua_state(), String.t(), non_neg_integer()) ::
  {:ok, lua_value()} | {:error, any()}

Evaluates a Lua file against the given Lua state and returns the result in an ok-error tuple. The state itself is not modified.

Link to this function

eval_file!(state, file_path, max_reductions \\ 0)

View Source
eval_file!(lua_state(), String.t(), non_neg_integer()) :: lua_value()

Same as eval_file/3, but will return the raw result or raise a RuntimeError.

Link to this function

eval_function!(state, path, args \\ [], max_reductions \\ 0)

View Source

Calls a function defined in the the Lua state and returns only the result. The state itself is not modified. Lua functions in the Lua state can be referenced by their lua_path, being a string or list such as math.floor or ["math", "floor"].

Gets a value from a Lua state.

Creates a Lua state with "dangerous" core library features such as file IO and networking removed.

Link to this function

let_elixir_eval!(state, name, fun)

View Source
let_elixir_eval!(lua_state(), lua_path(), elixir_eval_fun()) :: lua_state()

Returns a Lua state modified to include an Elixir function, elixir_eval_fun(), at the given lua_path().

The elixir_eval_fun() takes two arguments, a Lua state and a list of calling arguments from Lua. Its return value is passed along to Lua. It will not mutate the Lua state against which it executes.

Link to this function

let_elixir_play!(state, path, fun)

View Source
let_elixir_play!(lua_state(), lua_path(), elixir_play_fun()) :: lua_state()

Returns a Lua state modified to include an Elixir function, elixir_play_fun(), at the given lua_path().

The elixir_play_fun() takes two arguments, a Lua state and a list of calling arguments from Lua. It should return a new Lua state.

This can be used to let Lua scripts use something like controlled inheritance, dynamically adding external functionality and settings.

Link to this function

let_elixir_run!(state, name, fun)

View Source
let_elixir_run!(lua_state(), lua_path(), elixir_run_fun()) :: lua_state()

Returns a Lua state modified to include an Elixir function, elixir_run_fun(), at the given lua_path().

The elixir_run_fun() takes two arguments, a Lua state and a list of calling arguments from Lua. It should return a tuple holding the result intended for the calling Lua function alongside a new Lua state.

Link to this function

play(state, code, max_reductions \\ 0)

View Source
play(lua_state(), lua_code(), non_neg_integer()) ::
  {:ok, lua_state()} | {:error, any()}

Runs a Lua string or chunk against a Lua state and returns a new Lua state in an ok-error tuple.

Link to this function

play!(state, code, max_reductions \\ 0)

View Source

Same as play/3, but will return the raw result or raise a RuntimeError.

Link to this function

play_file!(state, file_path, max_reductions \\ 0)

View Source
play_file!(lua_state(), String.t(), non_neg_integer()) :: lua_state()

Runs a Lua file in the context of a Lua state and returns a new Lua state.

Link to this function

play_function!(state, path, args \\ [], max_reductions \\ 0)

View Source

Runs a Lua function defined in the given Lua state and returns a new Lua state.

Link to this function

run(state, code, max_reductions \\ 0)

View Source
run(lua_state(), lua_code(), non_neg_integer()) ::
  {:ok, lua_state() | {lua_value(), lua_state()}} | {:error, any()}

Runs a Lua string or chunk against the given Lua state and returns the result and the new Lua state in an ok-error tuple.

Link to this function

run!(state, code, max_reductions \\ 0)

View Source

Same as run/3, but will return the raw {result, state} or raise a RuntimeError.

Link to this function

run_function!(state, path, args \\ [], max_reductions \\ 0)

View Source

Runs a function defined in the the Lua state and returns the result and the new Lua state as {result, state}. Lua functions in the Lua state can be referenced by their lua_path, a string or list such as math.floor or ["math", "floor"].

Link to this function

set!(state, path, value, force \\ false)

View Source
set!(lua_state(), lua_path(), any(), boolean()) :: lua_state()

Sets a value in a Lua state and returns the modified state. If force is set to true, new tables will be created automatically if they missing from the given lua_path.

Creates a Lua state with access to Lua's standard library. The max_reductions feature of Sandbox is still available, but "dangerous" core library features such as file IO and networking are still available.