summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/redmine/helpers/diff.rb8
-rw-r--r--test/unit/lib/redmine/helpers/diff_test.rb12
2 files changed, 17 insertions, 3 deletions
diff --git a/lib/redmine/helpers/diff.rb b/lib/redmine/helpers/diff.rb
index aa1860ac7..a6d81620a 100644
--- a/lib/redmine/helpers/diff.rb
+++ b/lib/redmine/helpers/diff.rb
@@ -23,6 +23,7 @@ module Redmine
include ERB::Util
include ActionView::Helpers::TagHelper
include ActionView::Helpers::TextHelper
+ include ActionView::Helpers::OutputSafetyHelper
attr_reader :diff, :words
def initialize(content_to, content_from)
@@ -53,7 +54,7 @@ module Redmine
else
del_at = pos unless del_at
deleted << ' ' unless deleted.empty?
- deleted << h(change[2])
+ deleted << change[2]
words_del += 1
end
end
@@ -62,13 +63,14 @@ module Redmine
words[add_to] = words[add_to] + '</span>'.html_safe
end
if del_at
- words.insert del_at - del_off + dels + words_add, '<span class="diff_out">'.html_safe + deleted + '</span>'.html_safe
+ # deleted is not safe html at this point
+ words.insert del_at - del_off + dels + words_add, '<span class="diff_out">'.html_safe + h(deleted) + '</span>'.html_safe
dels += 1
del_off += words_del
words_del = 0
end
end
- words.join(' ').html_safe
+ safe_join(words, ' ')
end
end
end
diff --git a/test/unit/lib/redmine/helpers/diff_test.rb b/test/unit/lib/redmine/helpers/diff_test.rb
index c6654ceac..be74a9071 100644
--- a/test/unit/lib/redmine/helpers/diff_test.rb
+++ b/test/unit/lib/redmine/helpers/diff_test.rb
@@ -22,4 +22,16 @@ class DiffTest < ActiveSupport::TestCase
diff = Redmine::Helpers::Diff.new("foo", "bar")
assert_not_nil diff
end
+
+ def test_dont_double_escape
+ # 3 cases to test in the before: first word, last word, everything inbetween
+ before = "<stuff> with html & special chars</danger>"
+ # all words in after are treated equal
+ after = "other stuff <script>alert('foo');</alert>"
+
+ computed_diff = Redmine::Helpers::Diff.new(before, after).to_html
+ expected_diff = '<span class="diff_in">&lt;stuff&gt; with html &amp; special chars&lt;/danger&gt;</span> <span class="diff_out">other stuff &lt;script&gt;alert(&#39;foo&#39;);&lt;/alert&gt;</span>'
+
+ assert_equal computed_diff, expected_diff
+ end
end