nhpip
1
Hi,
As the title states, I want to reject an AST with function calls. This seems to work, is there a better way?
@invalid_ast_ops [:., :import, :apply, :__block__]
defp sanitize_args(args) do
Macro.prewalk(args, fn {call, _, _} when call in @invalid_ast_ops ->
raise "Invalid arguments"
{call, _, args} when is_atom(call) and is_list(args) ->
Macro.special_form?(call, length(args)) || raise "Invalid arguments"
v -> v
end)
Thanks
fuelen
2
A couple of years ago, I wrote this code that works a bit differently – it allows only a whitelist and collects all invalid nodes for error reporting:
def ensure_ast_safe(ast) do
Macro.prewalk(
ast,
[],
fn
{fn_name, _, _} = node, acc
when fn_name in [:%{}, :sigil_D, :=, :sigil_U, :<<>>, :{}, :<>] ->
{node, acc}
{atom, _} = node, acc when is_atom(atom) ->
{node, acc}
node, acc
when is_atom(node) or is_binary(node) or is_integer(node) or is_list(node) or
is_float(node) ->
{node, acc}
node, acc ->
{nil, [node | acc]}
end
)
|> elem(1)
|> case do
[] ->
:ok
expressions ->
{:error, {:unsupported_expressions, expressions}}
end
end
Hope it helps
1 Like