为什么Rails' `HashWithIndifferentAccess`将键存储为字符串而不是符号?

时间:2017-01-11 13:31:52

标签: ruby-on-rails ruby hashmap activesupport

我正在使用ActiveSupport::HashWithIndifferentAccess将我的数据库中的整数映射到我的ruby代码中的语义值,但是我注意到它使用的键是字符串。当我检查哈希的类型时,我发现它是Hash,而不是标准glReadPixels,这是有道理的,但是导致了为什么Rails选择存储和比较值的问题字符串,而不是符号,内部。

documentation州:

  

当在整个书写界面中用作键时,内部符号被映射到字符串

由于比较快,符号通常用在哈希中,但Rails选择使用字符串。为什么他们选择这样做,以及性能差异有多大?

2 个答案:

答案 0 :(得分:3)

  

为什么他们选择这样做

ActiveSupport::HashWithIndifferentAccess主要用于处理来自外部的参数。符号存储在ruby堆中,通常,它们永远不会释放回系统。

使用符号作为从外部获取密钥的密钥,会导致针对OutOfMemory攻击的漏洞([D]DoS,使用随机生成的参数名称发送查询。)这就是选择字符串的原因,AFAIU 。 100%保证要求DHH。

  

性能差异有多大?

使用Benchmark进行检查。这个网站不应该是“请为我做基准”网站。

答案 1 :(得分:3)

过去,有些实现无法收集符号。 IOW,一个符号,一旦创建,将留在内存中直到 time 结束(对于服务器进程,如Rails应用程序,可能是几个月)。直到三周前,YARV,最受欢迎的实施,恰好是其中之一。

Ergo,你可以通过生成大量符号来运行一个运行其中一个易受攻击的实现的Ruby系统,并且由于Rails使用HWIA作为请求参数(完全受攻击者的控制),其中包括这样做很简单。如此。

现在,每个实现都支持收集符号(多年前JRuby和Rubinius支持它,YARV支持2.4.0以后),实现策略可能会改变......或者不改变运行系统。