Techioz Blog

params ハッシュのキーとしてシンボルと文字列を使用する Rails

概要

文字列をハッシュキーとして使用する場合、Ruby は文字列を評価してその内容を確認し (そしてそれに対してハッシュ関数を計算し)、その結果をハッシュに既に格納されているキーの (ハッシュされた) 値と比較する必要があります。 。

シンボルをハッシュキーとして使用する場合、それが不変であることが暗黙的に示されるため、Ruby は基本的にオブジェクト ID (のハッシュ関数) と既に保存されているキーの (ハッシュされた) オブジェクト ID との比較を行うことができます。ハッシュ。 (はるかに高速)。

しかし、問題はHashWithIndependentAccessのインスタンスであるRailsのparamsにあり、params[:some_key]を記述すると、:some_keyを「some_key」に変換し、paramsハッシュでキーを検索しようとします。 159行目

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

では、ハッシュのキーとして文字列を使用すると検索が遅い場合、なぜ HashWithIndependentAccess がシンボル キーを文字列に変換するのでしょうか。

解決策

その理由は以前はセキュリティでした。 Ruby 2.2 以降では関係なくなりました。

Ruby 2.2 より前では、シンボルはガベージ コレクションされませんでした。これは、シンボルがリテラル (:my_symbol) または #to_sym によって作成されると、永久に存在することを意味します。

Rails が文字列の代わりにシンボルを使用した場合、リクエスト内のパラメータの名前に対応するシンボルが作成されます。攻撃者は、param1、param2、… という名前のパラメータを使用してリクエストを送信し、アプリに数十万のシンボルを割り当てさせてサーバーのメモリを使い果たす可能性があります。

Ruby 2.2 以降ではそうではなくなりました