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 以降ではそうではなくなりました