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:
Panagiotis Nezis
2026-03-07 10:01:59 +01:00
committed by GitHub
parent 2973af6c97
commit d61ba915b0
2 changed files with 18 additions and 2 deletions
+8 -2
View File
@@ -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
+10
View File
@@ -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")