diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2007-09-24 08:13:55 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2007-09-24 08:13:55 +0000 |
commit | 4b33306c704d6429e42e317802c92bc57f0de61c (patch) | |
tree | d8486d2913a5433be9ab31c74fa8357f93a0e376 /actionpack | |
parent | 38454983b48a117737bcd25d3962e2578d6c38f0 (diff) | |
download | rails-4b33306c704d6429e42e317802c92bc57f0de61c.tar.gz rails-4b33306c704d6429e42e317802c92bc57f0de61c.tar.bz2 rails-4b33306c704d6429e42e317802c92bc57f0de61c.zip |
The tag helper may bypass escaping.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7608 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/CHANGELOG | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/tag_helper.rb | 43 | ||||
-rw-r--r-- | actionpack/test/template/tag_helper_test.rb | 4 |
3 files changed, 32 insertions, 17 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index a1173568d8..bd5e99ab16 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* The tag helper may bypass escaping. [Jeremy Kemper] + * Cache asset ids. [Jeremy Kemper] * Optimized named routes respect AbstractRequest.relative_url_root. #9612 [danielmorrison, Jeremy Kemper] diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 963f494760..999cbfb52a 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -11,9 +11,10 @@ module ActionView BOOLEAN_ATTRIBUTES = Set.new(%w(disabled readonly multiple)) # Returns an empty HTML tag of type +name+ which by default is XHTML - # compliant. Setting +open+ to true will create an open tag compatible + # compliant. Set +open+ to true to create an open tag compatible # with HTML 4.0 and below. Add HTML attributes by passing an attributes - # hash to +options+. + # hash to +options+. Set +escape+ to false to disable attribute value + # escaping. # # ==== Options # The +options+ hash is used with attributes with no value like (<tt>disabled</tt> and @@ -30,16 +31,20 @@ module ActionView # tag("input", { :type => 'text', :disabled => true }) # # => <input type="text" disabled="disabled" /> # - # tag("img", { :src => "open.png" }) - # # => <img src="open.png" /> - def tag(name, options = nil, open = false) - "<#{name}#{tag_options(options) if options}" + (open ? ">" : " />") + # tag("img", { :src => "open & shut.png" }) + # # => <img src="open & shut.png" /> + # + # tag("img", { :src => "open & shut.png" }, false, false) + # # => <img src="open & shut.png" /> + def tag(name, options = nil, open = false, escape = true) + "<#{name}#{tag_options(options, escape) if options}" + (open ? ">" : " />") end # Returns an HTML block tag of type +name+ surrounding the +content+. Add # HTML attributes by passing an attributes hash to +options+. # Instead of passing the content as an argument, you can also use a block # in which case, you pass your +options+ as the second parameter. + # Set escape to false to disable attribute value escaping. # # ==== Options # The +options+ hash is used with attributes with no value like (<tt>disabled</tt> and @@ -58,15 +63,15 @@ module ActionView # Hello world! # <% end -%> # # => <div class="strong"><p>Hello world!</p></div> - def content_tag(name, content_or_options_with_block = nil, options = nil, &block) + def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) if block_given? options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) content = capture(&block) - content_tag = content_tag_string(name, content, options) + content_tag = content_tag_string(name, content, options, escape) block_is_within_action_view?(block) ? concat(content_tag, block.binding) : content_tag else content = content_or_options_with_block - content_tag_string(name, content, options) + content_tag_string(name, content, options, escape) end end @@ -98,19 +103,23 @@ module ActionView end private - def content_tag_string(name, content, options) - tag_options = tag_options(options) if options + def content_tag_string(name, content, options, escape = true) + tag_options = tag_options(options, escape) if options "<#{name}#{tag_options}>#{content}</#{name}>" end - def tag_options(options) + def tag_options(options, escape = true) unless options.blank? attrs = [] - options.each do |key, value| - next unless value - key = key.to_s - value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value) - attrs << %(#{key}="#{value}") + if escape + options.each do |key, value| + next unless value + key = key.to_s + value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value) + attrs << %(#{key}="#{value}") + end + else + attrs = options.map { |key, value| %(#{key}="#{value}") } end " #{attrs.sort * ' '}" unless attrs.empty? end diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 1e8957d756..c7edc678ff 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -73,4 +73,8 @@ class TagHelperTest < Test::Unit::TestCase assert_equal %(<a href="#{escaped.gsub /&/, '&'}" />), tag('a', :href => escaped) end end + + def test_disable_escaping + assert_equal '<a href="&" />', tag('a', { :href => '&' }, false, false) + end end |