Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails using Symbol vs String as key in params hash

If we use a string as a Hash key, Ruby needs to evaluate the string and look at it's contents (and compute a hash function on that) and compare the result against the (hashed) values of the keys which are already stored in the Hash.

If we use a symbol as a Hash key, it's implicit that it's immutable, so Ruby can basically just do a comparison of the (hash function of the) object-id against the (hashed) object-ids of keys which are already stored in the Hash. (much faster).

But the thing is in Rails params which is instance of HashWithIndifferentAccess, if we write params[:some_key] it converts :some_key to 'some_key' and then it tries to look for the key in params hash. line 159

 def convert_key(key)
    key.kind_of?(Symbol) ? key.to_s : key
  end

so if the lookup is slow with String as key in Hash, why does HashWithIndifferentAccess converts symbol key to string.

like image 829
Subhash Chandra Avatar asked May 17 '16 17:05

Subhash Chandra


1 Answers

The reason used to be security. It's no longer relevant in Ruby 2.2 or later.

Before Ruby 2.2 symbols were not garbage collected. This means that once a symbol was created via a literal (:my_symbol) or #to_sym it would be around forever.

If Rails used symbols instead of strings then it would create symbols corresponding to names of params in a request. An attacker could send requests with params named param1, param2, ... and exhaust server memory by making the app allocate hundreds of thousands of symbols.

It's no longer the case in Ruby 2.2 or later

like image 180
Greg Navis Avatar answered Sep 22 '22 18:09

Greg Navis