diff --git a/lib/redmine/unified_diff.rb b/lib/redmine/unified_diff.rb index 3aa348f41..84c376764 100644 --- a/lib/redmine/unified_diff.rb +++ b/lib/redmine/unified_diff.rb @@ -112,11 +112,6 @@ module Redmine private - # Escape the HTML for the diff - def escapeHTML(line) - CGI.escapeHTML(line) - end - def diff_for_added_line if @type == 'sbs' && @removed > 0 && @added < @removed self[-(@removed - @added)] @@ -130,7 +125,7 @@ module Redmine def parse_line(line, type="inline") if line[0, 1] == "+" diff = diff_for_added_line - diff.line_right = escapeHTML line[1..-1] + diff.line_right = line[1..-1] diff.nb_line_right = @line_num_r diff.type_diff_right = 'diff_in' @line_num_r += 1 @@ -138,7 +133,7 @@ module Redmine true elsif line[0, 1] == "-" diff = Diff.new - diff.line_left = escapeHTML line[1..-1] + diff.line_left = line[1..-1] diff.nb_line_left = @line_num_l diff.type_diff_left = 'diff_out' self << diff @@ -149,9 +144,9 @@ module Redmine write_offsets if line[0, 1] =~ /\s/ diff = Diff.new - diff.line_right = escapeHTML line[1..-1] + diff.line_right = line[1..-1] diff.nb_line_right = @line_num_r - diff.line_left = escapeHTML line[1..-1] + diff.line_left = line[1..-1] diff.nb_line_left = @line_num_l self << diff @line_num_l += 1 @@ -224,27 +219,15 @@ module Redmine end def html_line_left - if offsets - line_left.dup.insert(offsets.first, '').insert(offsets.last, '') - else - line_left - end + line_to_html(line_left, offsets) end def html_line_right - if offsets - line_right.dup.insert(offsets.first, '').insert(offsets.last, '') - else - line_right - end + line_to_html(line_right, offsets) end def html_line - if offsets - line.dup.insert(offsets.first, '').insert(offsets.last, '') - else - line - end + line_to_html(line, offsets) end def inspect @@ -254,5 +237,23 @@ module Redmine puts self.nb_line_right puts self.line_right end + + private + + def line_to_html(line, offsets) + if offsets + s = '' + unless offsets.first == 0 + s << CGI.escapeHTML(line[0..offsets.first-1]) + end + s << '' + CGI.escapeHTML(line[offsets.first..offsets.last]) + '' + unless offsets.last == -1 + s << CGI.escapeHTML(line[offsets.last+1..-1]) + end + s + else + CGI.escapeHTML(line) + end + end end end diff --git a/test/unit/lib/redmine/unified_diff_test.rb b/test/unit/lib/redmine/unified_diff_test.rb index 8d3e70497..01b899a02 100644 --- a/test/unit/lib/redmine/unified_diff_test.rb +++ b/test/unit/lib/redmine/unified_diff_test.rb @@ -91,6 +91,29 @@ class Redmine::UnifiedDiffTest < ActiveSupport::TestCase end + def test_partials_with_html_entities + raw = <<-DIFF +--- test.orig.txt Wed Feb 15 16:10:39 2012 ++++ test.new.txt Wed Feb 15 16:11:25 2012 +@@ -1,5 +1,5 @@ + Semicolons were mysteriously appearing in code diffs in the repository + +-void DoSomething(std::auto_ptr myObj) ++void DoSomething(const MyClass& myObj) + +DIFF + + diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs') + assert_equal 1, diff.size + assert_equal 'void DoSomething(std::auto_ptr<MyClass> myObj)', diff.first[2].html_line_left + assert_equal 'void DoSomething(const MyClass& myObj)', diff.first[2].html_line_right + + diff = Redmine::UnifiedDiff.new(raw, :type => 'inline') + assert_equal 1, diff.size + assert_equal 'void DoSomething(std::auto_ptr<MyClass> myObj)', diff.first[2].html_line + assert_equal 'void DoSomething(const MyClass& myObj)', diff.first[3].html_line + end + def test_line_starting_with_dashes diff = Redmine::UnifiedDiff.new(<<-DIFF --- old.txt Wed Nov 11 14:24:58 2009