【问题标题】:Converting external strings to atoms将外部字符串转换为原子
【发布时间】:2019-02-04 02:49:03
【问题描述】:

在第页。 25 在“Programming Phoenix 1.4 (ebook, beta)”中,Chris McCord 的旁白说:

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

引述如下:

外部数据不能安全地转换为原子......所以你转换 字符串键到原子键...

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

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    没错。 垃圾收集器安全地处理所有未被任何进程使用的数据,除了原子。这是因为一旦创建了原子,它们就会永久存储在 Erlang 原子表中(有固定的限制)。

    来自Erlang manual

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

    这意味着如果您在外部数据(例如从套接字接收的输入或在 Web 请求期间)使用类似 String.to_atom/1 的东西,恶意用户(甚至是普通用户,在不知不觉中)可能会拒绝您的符号表,导致崩溃你的申请。如果出于某种原因,您确实需要将外部字符串转换为原子,则应使用String.to_existing_atom/1,以确保原子确实是事先创建的。


    其他资源:


    顺便说一句,我实际上创建了一个 package 正是因为这个原因——我想在 Phoenix Web 请求中安全地使用 atom 进行用户输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      • 2018-04-26
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多