Raise ArgumentError on invalid binding in Code.eval_string/3 (#15146)
Previously, passing a non-list binding to `Code.eval_string/3` would crash deep in Erlang code with a confusing `FunctionClauseError` in `:elixir_erl_var.load_binding/6`.
This commit is contained in:
@@ -621,11 +621,17 @@ defmodule Code do
|
||||
def eval_string(string, binding \\ [], opts \\ [])
|
||||
|
||||
def eval_string(string, binding, %Macro.Env{} = env) do
|
||||
validated_eval_string(string, binding, env)
|
||||
validated_eval_string(string, validate_binding(binding), env)
|
||||
end
|
||||
|
||||
def eval_string(string, binding, opts) when is_list(opts) do
|
||||
validated_eval_string(string, binding, opts)
|
||||
validated_eval_string(string, validate_binding(binding), opts)
|
||||
end
|
||||
|
||||
defp validate_binding(binding) when is_list(binding), do: binding
|
||||
|
||||
defp validate_binding(binding) do
|
||||
raise ArgumentError, "binding must be a list, got: #{inspect(binding)}"
|
||||
end
|
||||
|
||||
defp validated_eval_string(string, binding, opts_or_env) do
|
||||
|
||||
@@ -176,6 +176,16 @@ defmodule CodeTest do
|
||||
{"1", [{:c, 2}, {:b, "1"}, {:a, 1}]}
|
||||
end
|
||||
|
||||
test "raises on invalid binding type" do
|
||||
assert_raise ArgumentError, "binding must be a list, got: :not_a_list", fn ->
|
||||
Code.eval_string("1 + 1", :not_a_list)
|
||||
end
|
||||
|
||||
assert_raise ArgumentError, "binding must be a list, got: %{}", fn ->
|
||||
Code.eval_string("1 + 1", %{}, __ENV__)
|
||||
end
|
||||
end
|
||||
|
||||
test "keeps caller in stacktrace" do
|
||||
try do
|
||||
Code.eval_string("<<a::size(b)>>", [a: :a, b: :b], file: "myfile")
|
||||
|
||||
Reference in New Issue
Block a user