Skip to content

Don't treat continuation tokens of interpolated sigils as sigils#40

Merged
josevalim merged 1 commit into
elixir-makeup:masterfrom
ericmj:fix-sigil-lexer-interpolation-crash
Jul 9, 2026
Merged

Don't treat continuation tokens of interpolated sigils as sigils#40
josevalim merged 1 commit into
elixir-makeup:masterfrom
ericmj:fix-sigil-lexer-interpolation-crash

Conversation

@ericmj

@ericmj ericmj commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

A sigil containing interpolation is split into multiple :string_sigil tokens, one chunk before and one after each interpolation. The custom sigil lexer postprocessing matches any :string_sigil token, reads the element at index 1 to look up a registered sigil lexer, and then asserts the token starts with "~" — which only holds for the opening chunk.

If the element at index 1 of a later chunk happens to be a registered sigil character, the lookup succeeds and the assertion crashes with a MatchError. This happens in the wild: with makeup_eex registering a lexer for ~H, lexing credo's first_run_hint.ex crashes on

~w"symbolic-ref refs/remotes/#{remote_name}/HEAD"

because the chunk after the interpolation is /HEAD", whose element at index 1 is H:

** (MatchError) no match of right hand side value: [47, 72, 69, 65, 68, "\""]

The custom sigil clause now only matches tokens that start with "~", so continuation chunks fall through to the catch-all clause and are kept as plain sigil content.

A sigil containing interpolation is split into multiple :string_sigil
tokens, one before and one after each interpolation. The custom sigil
lexer postprocessing matched any :string_sigil token and read the
element at index 1 to look up a registered sigil lexer, so a
continuation token whose second element happened to be a registered
sigil character (for example the H in the /HEAD" chunk of
~w"refs/remotes/#{remote}/HEAD", with makeup_eex registering ~H)
crashed with a MatchError when asserting the token starts with "~".

Only apply custom sigil lexers to tokens that start with "~" and let
continuation tokens fall through to the catch-all clause.
@josevalim josevalim merged commit ae1018a into elixir-makeup:master Jul 9, 2026
1 of 2 checks passed
@josevalim

Copy link
Copy Markdown
Collaborator

💚 💙 💜 💛 ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants