Skip to content

Commit d61ba91

Browse files
authored
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`.
1 parent 2973af6 commit d61ba91

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

lib/elixir/lib/code.ex

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,11 +621,17 @@ defmodule Code do
621621
def eval_string(string, binding \\ [], opts \\ [])
622622

623623
def eval_string(string, binding, %Macro.Env{} = env) do
624-
validated_eval_string(string, binding, env)
624+
validated_eval_string(string, validate_binding(binding), env)
625625
end
626626

627627
def eval_string(string, binding, opts) when is_list(opts) do
628-
validated_eval_string(string, binding, opts)
628+
validated_eval_string(string, validate_binding(binding), opts)
629+
end
630+
631+
defp validate_binding(binding) when is_list(binding), do: binding
632+
633+
defp validate_binding(binding) do
634+
raise ArgumentError, "binding must be a list, got: #{inspect(binding)}"
629635
end
630636

631637
defp validated_eval_string(string, binding, opts_or_env) do

lib/elixir/test/elixir/code_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ defmodule CodeTest do
176176
{"1", [{:c, 2}, {:b, "1"}, {:a, 1}]}
177177
end
178178

179+
test "raises on invalid binding type" do
180+
assert_raise ArgumentError, "binding must be a list, got: :not_a_list", fn ->
181+
Code.eval_string("1 + 1", :not_a_list)
182+
end
183+
184+
assert_raise ArgumentError, "binding must be a list, got: %{}", fn ->
185+
Code.eval_string("1 + 1", %{}, __ENV__)
186+
end
187+
end
188+
179189
test "keeps caller in stacktrace" do
180190
try do
181191
Code.eval_string("<<a::size(b)>>", [a: :a, b: :b], file: "myfile")

0 commit comments

Comments
 (0)