Why does Rails' `HashWithIndifferentAccess` store keys as strings and not symbols?

爱⌒轻易说出口 提交于 2019-12-24 01:16:17

问题


I am using enum to map integers in my database to semantic values in my ruby code, however I noticed that the keys that it uses are strings. When I checked the type of the hash, I discovered that it was an ActiveSupport::HashWithIndifferentAccess, not a standard Hash, which makes sense, but lead to the question of why Rails chose to store and compare the values as strings, not symbols, internally.

The documentation states:

Internally symbols are mapped to strings when used as keys in the entire writing interface

Symbols are usually used in hashes because of their fast comparison, but Rails has chosen to use strings instead. Why have they chosen to do this, and how significant is the difference in performance?


回答1:


Why have they chosen to do this

ActiveSupport::HashWithIndifferentAccess is mainly used to handle parameters coming from outside. Symbols are stored in the ruby heap and in general, they are never released back to the system.

Using symbols as keys in something that gets keys from the outside, leads to the vulnerability against OutOfMemory attacks ([D]DoS, sending queries with randomly generated parameters names.) That’s why strings were chosen, AFAIU. For 100% assurance ask DHH.

how significant is the difference in performance?

Use Benchmark to check. This site is not supposed to be a “please do benchmarks for me” site.




回答2:


In the past, there were some implementations that were unable to collect symbols. IOW, a symbol, once created, would stay in memory until the end of time the process (which for a server process like a Rails app, can be months). Up until three weeks ago, YARV, the most popular implementation, happened to be one of those.

Ergo, you could DoS a Ruby system running one of those vulnerable implementations by generating lots of symbols, and since Rails uses HWIA for request params (which are fully under the attacker's control), among others, it is quite trivial to do so.

Now, that every single implementation supports collecting symbols (JRuby and Rubinius supported it years ago, YARV supports it since 2.4.0), that implementation strategy may change … or not: never change a running system.



来源:https://stackoverflow.com/questions/41592312/why-does-rails-hashwithindifferentaccess-store-keys-as-strings-and-not-symbol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!