Skip to content

Rework anti-pattern doc about unsafe atom creation#15495

Merged
sabiwara merged 3 commits into
elixir-lang:mainfrom
sabiwara:unsafe_atom_docs
Jun 17, 2026
Merged

Rework anti-pattern doc about unsafe atom creation#15495
sabiwara merged 3 commits into
elixir-lang:mainfrom
sabiwara:unsafe_atom_docs

Conversation

@sabiwara

Copy link
Copy Markdown
Contributor

Following the introduction of to_exising_atom/2 variations in #15483 and #15493.

@lukaszsamson

Copy link
Copy Markdown
Contributor

Should we mention here other ways that can lead to dynamic atom creation like interpolation :#{foo}, ["#{foo}": 123], Code.string_to_quoted and other APIs?

@sabiwara

Copy link
Copy Markdown
Contributor Author

Good call, also ~w[foo bar]a. Not sure what the plan is, given they're all unsafe it would make sure to deprecate them too and have people call String.to_unsafe_atom("foo#{1}") etc explicitly?

Code probably has more implications anyway (esp. eval_, can create/redefine modules and be much worse than atom leaks), so perhaps wouldn't include it here.

@lukaszsamson

Copy link
Copy Markdown
Contributor

Code.compile*, assumes full trust as all other compiler APIs. AST/algebra operations like parsing or formatting are tricky because it is not obvious they may be unsafe

Updated the refactoring section to clarify the use of explicit conversions and pattern matching for string to atom conversions. Added examples and emphasized the importance of defining valid statuses within the same module.

@josevalim josevalim left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed some changes cause I think we can be more direct as we don't need to talk about to_existing_atom's pitfalls.

@sabiwara

Copy link
Copy Markdown
Contributor Author

AST/algebra operations like parsing or formatting are tricky because it is not obvious they may be unsafe

I think that's fair, it's probably one of the common vectors where it can happen.

I pushed some changes cause I think we can be more direct as we don't need to talk about to_existing_atom's pitfalls.

Looks much better indeed, thanks!


However, keep in mind using a module attribute or defining the atoms in the module body, outside of a function, are not sufficient, as the module body is only executed during compilation and it is not necessarily part of the compiled module loaded at runtime.
You may alternatively use `String.to_existing_atom/1`, but keep in mind it does have pitfalls related to code loading. Read the documentation for more information.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukaszsamson What about something like:

Suggested change
Finally, keep in mind that dynamic atoms could happen indirectly even if you are not calling `String.to_unsafe_atom/1` yourself. A typical example would be code parsing, using `Code.string_to_quoted/2` without the `:existing_atoms_only` or `:static_atoms_encoder` option.

@josevalim Also, this made me realize, would it be an interesting idea to support a list of atoms in existing_atoms_only? Assuming you're writing a sth like a calculator: [:cos, :sin, :exp, ...].

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sabiwara I don't think we need to talk about that here. But we can add disclaimers to string_to_quoted if necessary.

Also, this made me realize, would it be an interesting idea to support a list of atoms in existing_atoms_only? Assuming you're writing a sth like a calculator: [:cos, :sin, :exp, ...].

In this case, I think simply defining the atoms upfront (as suggested here) is enough, because you need to validate what was parsed anyway. The big benefit of to_existing_atom/2 is to parse and validate at once.

@sabiwara sabiwara merged commit a9976cc into elixir-lang:main Jun 17, 2026
13 of 16 checks passed
@sabiwara sabiwara deleted the unsafe_atom_docs branch June 17, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants