Rails3 での自動文字列エスケープの挙動
Rails3 での自動文字列エスケープの挙動
興味があったのでちょっと実装のぞいてみた。
Rails3 では、テンプレートで標準で文字列をHTMLエスケープするようになってる。
<%= "test" %> #=> エスケープされる
これを自動エスケープをやめるには
<%= raw "test" %> #=> エスケープされない
となるんだけど、たとえば以下のように h() でエスケープした文字列と通常の文字列を連結するとどちらもエスケープされる。
<%= h("test") + "secure string" %> # どちらのタグもエスケープされる
これを回避するには
<%= h("test").safe_concat("secure string") %>
<%= h("test") + "secure string".html_safe %>
としてやればよい。Rails3 (のActiveSupport) では、はたしてその文字が html のタグを含んでいても安全かどうかを調べるフラグ String#html_safe? が利用できるため、h() でエスケープしたり、"この文字列はまんま表示しても安全だよ" と明示的に String#html_safe を利用して ActiveSupport::SafeBuffer のクラスへ変換することで、そのまんまタグを表示することができる。
また、安全かどうかちゃんとフラグで持ってるため
h( h( "" ) )
としても一回目の h() で安全となるため自動で判断され多重エスケープされるケースがほぼ無くなる、というメリットも。