How to change binary to atom

How ca I change binary to atom?

I found binary_to_atom/1 on some example, but I am getting compile error:

undefined function binary_to_atom/1

binary_to_atom/1 is an erlang BIF. You can access it via :erlang.binary_to_atom/1. But we also have String.to_atom/1 in elixir.

But that function is potentially insecure. Atoms are not GC’d and there is a hard limit of about a million of them to exist. Creating them dynamically can therefore render your system insecure for DoS attacks, especially when created directly or indirectly from user input.

You should always prefer String.to_existing_atom/1 or convert your strings manually from a whitelist:

defmodule M do
  [:foo, :bar, :baz]
  |> Enum.each(fn (atom) ->
    def convert(unquote(Atom.to_string(atom))), do: {:ok, unquote(atom)}
  end)
  def convert(_), do: :error
end

This whitelisting approach has the big plus that it can be used to semantically narrow down possible input, while the built in converters might still return an atom that your system isn’t designed to work with at a certain place.

4 Likes

Thanks.

I want to build function that will take json ( or some other data ) and convert it to map.

Something like this:

Is there a better way to do this type of things?

Have you considered using one of the many JSON packages available?

Check out the Jason library for that: it is the fastest pure-Elixir library out there for JSON parsing at the moment, and it does exactly what you want (and encodes, too!)

But to answer your original source question: you don’t have to use atoms as keys in maps. You can use pretty much anything you want: numbers, strings, … in that case instead of using the key: value syntax, you you use the key => value syntax. key: value is just syntatic sugar over :atom_key => value at the end of the day. So by way of example:

%{1 => "one", "one" => 1, :"1" => 1}

That is a map with the number 1, the string “one”, and the atom :1 as keys.

So when going from user supplied input to maps, you can just use the user input (e.g. strings) as keys in the map and then you avoid the stability / security issues @NobbZ mentioned of exhausting memory or the atoms table.

2 Likes