Skip to content

Commit 673fe4a

Browse files
authored
Fix crash in Macro.to_string/1 on invalid sigils (#13905)
1 parent e7ec9a0 commit 673fe4a

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

lib/elixir/lib/code/normalizer.ex

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,17 @@ defmodule Code.Normalizer do
174174

175175
# Sigils
176176
defp do_normalize({sigil, meta, [{:<<>>, _, args} = string, modifiers]} = quoted, state)
177-
when is_list(args) and is_atom(sigil) do
178-
case Atom.to_string(sigil) do
179-
"sigil_" <> _ ->
180-
meta =
181-
meta
182-
|> patch_meta_line(state.parent_meta)
183-
|> Keyword.put_new(:delimiter, "\"")
184-
185-
{sigil, meta, [do_normalize(string, %{state | parent_meta: meta}), modifiers]}
177+
when is_atom(sigil) and is_list(args) and is_list(modifiers) do
178+
with "sigil_" <> _ <- Atom.to_string(sigil),
179+
true <- binary_interpolated?(args),
180+
true <- List.ascii_printable?(modifiers) do
181+
meta =
182+
meta
183+
|> patch_meta_line(state.parent_meta)
184+
|> Keyword.put_new(:delimiter, "\"")
186185

186+
{sigil, meta, [do_normalize(string, %{state | parent_meta: meta}), modifiers]}
187+
else
187188
_ ->
188189
normalize_call(quoted, state)
189190
end

lib/elixir/test/elixir/code_normalizer/quoted_ast_test.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,20 @@ defmodule Code.Normalizer.QuotedASTTest do
172172
) == ~s[~S"""\n"123"\n"""]
173173
end
174174

175+
test "regression: invalid sigil calls" do
176+
assert quoted_to_string(quote do: sigil_r(<<"foo", 123>>, [])) ==
177+
"sigil_r(<<\"foo\", 123>>, [])"
178+
179+
assert quoted_to_string(quote do: sigil_r(<<"foo">>, :invalid_modifiers)) ==
180+
"sigil_r(\"foo\", :invalid_modifiers)"
181+
182+
assert quoted_to_string(quote do: sigil_r(<<"foo">>, [:invalid_modifier])) ==
183+
"sigil_r(\"foo\", [:invalid_modifier])"
184+
185+
assert quoted_to_string(quote do: sigil_r(<<"foo">>, [])) == "~r\"foo\""
186+
assert quoted_to_string(quote do: sigil_r(<<"foo">>, [?a, ?b, ?c])) == "~r\"foo\"abc"
187+
end
188+
175189
test "tuple" do
176190
assert quoted_to_string(quote do: {1, 2}) == "{1, 2}"
177191
assert quoted_to_string(quote do: {1}) == "{1}"

0 commit comments

Comments
 (0)