Loppers (loppers v1.0.0)

A code validator for the Elixir-AST.

It can operate on both white- and blacklists.

Basic example:

iex> quoted = quote do "hello" |> String.upcase |> String.pad_leading(4, "0") end
iex> whitelist = Loppers.special_forms ++ [{Kernel, :|>}, {String, :upcase}, {String, :pad_leading}]
iex> Loppers.validate(quoted, whitelist: whitelist)
:ok

Link to this section Summary

Functions

All functions and macros needed to define modules, functions and set attributes

Convenience list of commonly used operators

A list of all macros contained in Kernel.SpecialForms.

Validates a syntax tree against the given whitelist.

Link to this section Types

Specs

error() :: {:not_allowed, ast :: term()}
Link to this type

function_ref()

Specs

function_ref() ::
  {module :: atom(), :__all__}
  | {module :: atom(), :__submodules_all__}
  | {module :: atom(), function :: atom()}
  | (function :: atom())
Link to this type

validate_option()

Specs

validate_option() ::
  {:whitelist, [function_ref()]} | {:blacklist, [function_ref()]}

Link to this section Functions

Link to this function

module_support()

All functions and macros needed to define modules, functions and set attributes

Convenience list of commonly used operators

Link to this function

special_forms()

A list of all macros contained in Kernel.SpecialForms.

Without those it's going to be hard to write any elixir code.

Link to this function

validate(quoted, opts)

Specs

validate(quoted :: term(), opts :: [validate_option()]) ::
  :ok | {:error, [error()]}

Validates a syntax tree against the given whitelist.

Use Code.string_to_quoted/2 to get the syntax tree out of source code.

When no whitelist is defined, it is assumed that all function calls are ok, except when they exist in the blacklist.

Supplying both a white- and a blacklist can be useful, for example when you want to allow all functions of a module, except a few that you don't want:

iex> whitelist = Loppers.special_forms ++ [{Enum, :__all__}]
iex> blacklist = [{Enum, :map_reduce}]
iex> quoted = quote do Enum.map_reduce([], nil, &({&1, nil})) end
iex> Loppers.validate(quoted, [whitelist: whitelist, blacklist: blacklist])
{:error, [
  not_allowed: {{:., [parent_modules: []],
    [
      {:__aliases__, [parent_modules: [], alias: false], [:Enum]},
      :map_reduce
    ]}, [parent_modules: []],
   [
     [],
     nil,
     {:&, [parent_modules: []],
      [{{:&, [parent_modules: []], [1]}, nil}]}
   ]}
]}

Options

  • :whitelist - a list of function_refs that are allowed in the code
  • :blacklist - a list of function_refs that are forbidden in the code