A Day in the Life

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() で安全となるため自動で判断され多重エスケープされるケースがほぼ無くなる、というメリットも。

関連するかもエントリー

String を継承したクラスでのブロック内部の正規表現後方参照の挙動
String を継承したクラスでのブロック内部の正規表現後方参照の挙動class MyString < String def gsub(*args, &block) super end end puts String.new('123').gsub(...
String を継承したクラスでのブロック内部の正規表現後方参照の挙動class MyString < String def gsub...
Ruby でエスケープシーケンスを HTML にする
Ruby でエスケープシーケンスを HTML にするansi-sysという gem でできるんだけど、速度がすこぶる遅いので(なんであんなに遅いか解らないぐらい遅い…)ので、普段使ってる Term::ANSIColor に to_html を実装した。https://github...
Ruby でエスケープシーケンスを HTML にするansi-sysという gem でできるんだけど、速度がすこぶる遅いので(なんであんなに...