将外部字符串转换为原子

时间:2018-11-27 01:24:06

标签: elixir phoenix-framework

在第在“ Programming Phoenix 1.4(电子书,测试版)”的第25页中,克里斯·麦考德(Chris McCord)有一旁说:

  

在控制器的世界行动中,外部参数具有   字符串键,“名称” => name,而内部我们使用name:name。   这是整个凤凰城都遵循的惯例。外部数据无法   安全地转换为原子,因为原子表不是   垃圾收集。相反,我们明确匹配字符串键,   然后我们的应用程序边界(例如控制器和通道)将   将它们转换为原子键,我们将在其他任何地方依赖它   在凤凰城内。

用语表达:

  

外部数据无法安全地转换为原子...因此您进行了转换   原子键的字符串键...

嗯?我想他想说的是,如果有人向您发送了带有1亿个(字符串)键的json数据,而您将整个json盲目转换为带有原子键的长生不老药地图,那么您将有可能溢出原子表。另一方面,如果您使用模式匹配从json数据中挑选出您感兴趣的键/值,然后将它们插入带有原子键的长生不老药图中,那么您显然会在原子表中创建更少的原子。

1 个答案:

答案 0 :(得分:1)

是正确的。 垃圾收集器安全地处置所有进程中未使用的所有数据,原子除外。这是因为一旦创建了原子,它们便会永久存储在Erlang Atom Table(具有固定限制)中。

来自Erlang manual

  

原子不会被垃圾收集。一旦创建了原子,就永远不会删除它。如果达到原子数限制(默认为1,048,576),则模拟器终止。

这意味着,如果您在外部数据上使用诸如String.to_atom/1之类的东西(例如,从套接字接收到的请求或在Web请求期间输入的信息),则恶意用户(甚至是常规用户,在不知不觉中)可以对您的符号表进行DoS ,导致您的应用程序崩溃。如果确实由于某种原因需要将外部字符串转换为原子,则应使用String.to_existing_atom/1,以确保原子确实是事先创建的。


其他资源:


在一个旁注中,由于这个原因,我实际上创建了一个package –我想安全地将原子用于Phoenix Web请求中的用户输入。