Skip to content

Commit

Permalink
Do not modify a safe buffer in helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Koziarski <michael@koziarski.com>
  • Loading branch information
nono authored and tenderlove committed Jun 7, 2011
1 parent 53a2c0b commit ed37964
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 31 deletions.
40 changes: 17 additions & 23 deletions actionpack/lib/action_view/helpers/text_helper.rb
Expand Up @@ -115,13 +115,12 @@ def highlight(text, phrases, *args)
end
options.reverse_merge!(:highlighter => '<strong class="highlight">\1</strong>')

text = sanitize(text) unless options[:sanitize] == false
if text.blank? || phrases.blank?
text
else
if text.present? && phrases.present?
match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
text.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter])
end.html_safe
text = text.to_str.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter])
end
text = sanitize(text) unless options[:sanitize] == false
text
end

# Extracts an excerpt from +text+ that matches the first instance of +phrase+.
Expand Down Expand Up @@ -251,14 +250,16 @@ def word_wrap(text, *args)
# simple_format("Look ma! A class!", :class => 'description')
# # => "<p class='description'>Look ma! A class!</p>"
def simple_format(text, html_options={}, options={})
text = ''.html_safe if text.nil?
text = text ? text.to_str : ''
text = text.dup if text.frozen?
start_tag = tag('p', html_options, true)
text = sanitize(text) unless options[:sanitize] == false
text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
text.insert 0, start_tag
text.html_safe.safe_concat("</p>")
text.concat("</p>")
text = sanitize(text) unless options[:sanitize] == false
text
end

# Turns all URLs and e-mail addresses into clickable links. The <tt>:link</tt> option
Expand Down Expand Up @@ -477,7 +478,7 @@ def set_cycle(name, cycle_object)
# is yielded and the result is used as the link text.
def auto_link_urls(text, html_options = {}, options = {})
link_attributes = html_options.stringify_keys
text.gsub(AUTO_LINK_RE) do
text.to_str.gsub(AUTO_LINK_RE) do
scheme, href = $1, $&
punctuation = []

Expand All @@ -494,33 +495,26 @@ def auto_link_urls(text, html_options = {}, options = {})
end
end

link_text = block_given?? yield(href) : href
link_text = block_given? ? yield(href) : href
href = 'http://' + href unless scheme

unless options[:sanitize] == false
link_text = sanitize(link_text)
href = sanitize(href)
end
content_tag(:a, link_text, link_attributes.merge('href' => href), !!options[:sanitize]) + punctuation.reverse.join('')
sanitize = options[:sanitize] != false
content_tag(:a, link_text, link_attributes.merge('href' => href), sanitize) + punctuation.reverse.join('')
end
end
end

# Turns all email addresses into clickable links. If a block is given,
# each email is yielded and the result is used as the link text.
def auto_link_email_addresses(text, html_options = {}, options = {})
text.gsub(AUTO_EMAIL_RE) do
text.to_str.gsub(AUTO_EMAIL_RE) do
text = $&

if auto_linked?($`, $')
text.html_safe
else
display_text = (block_given?) ? yield(text) : text

unless options[:sanitize] == false
text = sanitize(text)
display_text = sanitize(display_text) unless text == display_text
end
display_text = block_given? ? yield(text) : text
display_text = sanitize(display_text) unless options[:sanitize] == false
mail_to text, display_text, html_options
end
end
Expand Down
26 changes: 18 additions & 8 deletions actionpack/test/template/text_helper_test.rb
Expand Up @@ -48,6 +48,10 @@ def test_simple_format_should_not_sanitize_input_when_sanitize_option_is_false
assert_equal "<p><b> test with unsafe string </b><script>code!</script></p>", simple_format("<b> test with unsafe string </b><script>code!</script>", {}, :sanitize => false)
end

def test_simple_format_should_not_be_html_safe_when_sanitize_option_is_false
assert !simple_format("<b> test with unsafe string </b><script>code!</script>", {}, :sanitize => false).html_safe?
end

def test_truncate_should_not_be_html_safe
assert !truncate("Hello World!", :length => 12).html_safe?
end
Expand Down Expand Up @@ -166,6 +170,13 @@ def test_highlight_with_options_hash
)
end

def test_highlight_on_an_html_safe_string
assert_equal(
"<p>This is a <b>beautiful</b> morning, but also a <b>beautiful</b> day</p>",
highlight("<p>This is a beautiful morning, but also a beautiful day</p>".html_safe, "beautiful", :highlighter => '<b>\1</b>')
)
end

def test_highlight_with_html
assert_equal(
"<p>This is a <strong class=\"highlight\">beautiful</strong> morning, but also a <strong class=\"highlight\">beautiful</strong> day</p>",
Expand Down Expand Up @@ -306,13 +317,10 @@ def test_auto_link_parsing
end
end

def generate_result(link_text, href = nil, escape = false)
href ||= link_text
if escape
%{<a href="#{CGI::escapeHTML href}">#{CGI::escapeHTML link_text}</a>}
else
%{<a href="#{href}">#{link_text}</a>}
end
def generate_result(link_text, href = nil)
href = CGI::escapeHTML(href || link_text)
text = CGI::escapeHTML(link_text)
%{<a href="#{href}">#{text}</a>}
end

def test_auto_link_should_not_be_html_safe
Expand All @@ -323,6 +331,8 @@ def test_auto_link_should_not_be_html_safe
assert !auto_link('').html_safe?, 'should not be html safe'
assert !auto_link("#{link_raw} #{link_raw} #{link_raw}").html_safe?, 'should not be html safe'
assert !auto_link("hello #{email_raw}").html_safe?, 'should not be html safe'
assert !auto_link(link_raw.html_safe).html_safe?, 'should not be html safe'
assert !auto_link(email_raw.html_safe).html_safe?, 'should not be html safe'
end

def test_auto_link_email_address
Expand Down Expand Up @@ -425,7 +435,7 @@ def test_auto_link

def test_auto_link_should_sanitize_input_when_sanitize_option_is_not_false
link_raw = %{http://www.rubyonrails.com?id=1&num=2}
assert_equal %{<a href="http://www.rubyonrails.com?id=1&num=2">http://www.rubyonrails.com?id=1&num=2</a>}, auto_link(link_raw)
assert_equal %{<a href="http://www.rubyonrails.com?id=1&amp;num=2">http://www.rubyonrails.com?id=1&amp;num=2</a>}, auto_link(link_raw)
end

def test_auto_link_should_not_sanitize_input_when_sanitize_option_is_false
Expand Down

0 comments on commit ed37964

Please sign in to comment.