Created
June 8, 2015 10:25
-
-
Save Papipo/99de92cd99c8900439f2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Sandbox do | |
| defmacro __using__(_env) do | |
| quote do | |
| import Sandbox, only: [whitelist: 1] | |
| def run(code) do | |
| code | |
| |> Code.string_to_quoted! | |
| |> Macro.prewalk(&allow/1) | |
| |> Code.eval_quoted | |
| end | |
| Module.register_attribute(__MODULE__, :whitelist, accumulate: true) | |
| @before_compile Sandbox | |
| end | |
| end | |
| defmacro __before_compile__(env) do | |
| whitelist = Module.get_attribute(env.module, :whitelist) | |
| quote do | |
| for allowed <- unquote(whitelist) do | |
| def allow(expression = {allowed, _, _}) do | |
| expression | |
| end | |
| end | |
| def allow(exp) do | |
| raise "Expression not allowed: #{Macro.to_string(exp)}" | |
| end | |
| end | |
| end | |
| defmacro whitelist(exp) do | |
| quote do | |
| @whitelist unquote(exp) | |
| end | |
| end | |
| end | |
| defmodule ExternalCode do | |
| use Sandbox | |
| whitelist :+ | |
| end | |
| ExternalCode.run("1 + 2") | |
| # ExternalCode.run(""" | |
| # defmodule CustomCode do | |
| # send(self(), :msg) | |
| # receive do | |
| # :msg -> IO.puts "Received msg" | |
| # end | |
| # IO.puts "allowed" | |
| # end | |
| # """) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment