2017-05-24 4 views
0

私はActionViewのために存在する非常に貧弱なドキュメンテーション、特にビューファイルから呼び出されたときにだけ存在するselect_tagというメソッドを調べました。ActionViewの "select_tag"が直接呼び出されたときに、 "options"引数でHTMLをエスケープするのはなぜですか?

select_tag name, option_tags, options 

documentationoptionsについてほとんど全くnameについては何も、言わない、とだけ他から取得する必要があり、不透明な値として扱う例を挙げて説明しoption_tags:たぶん、このように呼ばれています機能。

いつものように、Railsについて何かを学ぶ唯一の方法は、それをリバースエンジニアリングすることです。

だから私は、Rubyはあなたが最初のクラスとオブジェクトを作成しない限り、モジュールで定義されているメソッドを呼び出すことはできませんので注意が必要ですRailsのコンソールから直接それを実行してみました:

class H 
    include ActionView::Helpers::FormOptionsHelper 
    include ActionView::Helpers::FormTagHelper 
end 

H.new.options_for_select ["foo","bar"] 

options_for_selectの上記の使用は、他の誰かが書いた実際のコードに由来します。戻り値は文字列です:

"<option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option>" 

だから、明らかに、あなたは私のような話をしたくないoption_for_select(または合併症を紹介し、他の多くの関連機能の1からの戻り値を渡すことになっていますActiveRecordオブジェクトからHTMLタグを生成する)select_tagoption_tagパラメータです。あなたのクリップボードにその文字列をコピーし、関数呼び出しに直接貼り付けた場合を除き、それはあなたが期待するもの行いません。

H.new.select_tag :my_name, "<option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option>" 

戻り値:

"<select name=\"my_name\" id=\"my_name\">&lt;option value=&quot;foo&quot;&gt;foo&lt;/option&gt;\n&lt;option value=&quot;bar&quot;&gt;bar&lt;/option&gt;</select>" 

は、少なくとも、これは明らかにnameのパラメータは次のとおりです。あなたはそれがコンソールに印刷させることなく、直接select_tagへの戻り値を渡す場合

でも奇妙、テキストがエスケープされていません。

H.new.select_tag :name, H.new.options_for_select(["foo","bar"]) 

戻り値:

"<select name=\"name\" id=\"name\"><option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option></select>" 

WTFされますここにいる?

答えて

0

この質問を書いているうちに、私は答えを見つけました。ルビーは私に横たわっています(いつものように)。

あなたは評価する:

H.new.options_for_select ["foo","bar"] 

Rubyは結果が文字列だったことを示しています。しかし、PryとIrbは両方とも暗黙のうちに.to_sをすべて呼び出し、options_for_selectから返されるものはto_sです。真実:

(H.new.options_for_select ["foo","bar"]).class 
=> ActiveSupport::SafeBuffer 
ActiveSupport::SafeBuffer.new("<foo>") 
=> "<foo>" 

したがって、これらの方法は、あなたの<select>タグに生、ユーザー提供の文字列を組み込みたい、そしてそれらの文字列は、HTML/JavaScriptのインジェクションの試みを含むことができ、その結果、それらはエスケープしなければならないことを前提と書いて誰でも。

ActiveViewはすべての文字列を疑わしいものとして扱いますが、特定の文字列をActiveSupport::SafeBufferでラップすることによって「安全」とマークすることは可能です。

関連する問題