From 670d2b6e2bebdc84aaa4a525d164bf50f8f2eb4b Mon Sep 17 00:00:00 2001 From: Toshi MARUYAMA Date: Sun, 28 Jul 2013 11:00:02 +0000 Subject: [PATCH] fix diff of CJK(Chinese/Japanese/Korean) is broken on Ruby 1.8 (#14562) Contributed by Jun NAITOH. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@12046 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- lib/redmine/unified_diff.rb | 14 +++++-- test/fixtures/diffs/issue-13644-3.diff | 7 ++++ test/fixtures/diffs/issue-13644-4.diff | 7 ++++ test/fixtures/diffs/issue-13644-5.diff | 7 ++++ test/unit/lib/redmine/unified_diff_test.rb | 48 ++++++++++++++++++++++ 5 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/diffs/issue-13644-3.diff create mode 100644 test/fixtures/diffs/issue-13644-4.diff create mode 100644 test/fixtures/diffs/issue-13644-5.diff diff --git a/lib/redmine/unified_diff.rb b/lib/redmine/unified_diff.rb index 548003220..170ae1db8 100644 --- a/lib/redmine/unified_diff.rb +++ b/lib/redmine/unified_diff.rb @@ -205,12 +205,20 @@ module Redmine end end ending = -1 - while ending >= -(max - starting) && line_left[ending] == line_right[ending] + while ending >= -(max - starting) && (line_left[ending] == line_right[ending]) ending -= 1 end if (! "".respond_to?(:force_encoding)) && ending > (-1 * line_left.size) - while line_left[ending].ord.between?(128, 191) && ending > -1 - ending -= 1 + while line_left[ending].ord.between?(128, 255) && ending < -1 + if line_left[ending].ord.between?(128, 191) + if line_left[ending + 1].ord.between?(128, 191) + ending += 1 + else + break + end + else + ending += 1 + end end end unless starting == 0 && ending == -1 diff --git a/test/fixtures/diffs/issue-13644-3.diff b/test/fixtures/diffs/issue-13644-3.diff new file mode 100644 index 000000000..782b160ae --- /dev/null +++ b/test/fixtures/diffs/issue-13644-3.diff @@ -0,0 +1,7 @@ +--- a.txt 2013-07-27 06:03:49.133257759 +0900 ++++ b.txt 2013-07-27 06:03:58.791221118 +0900 +@@ -1,3 +1,3 @@ + aaaa +-日本記 ++日本娘 + bbbb diff --git a/test/fixtures/diffs/issue-13644-4.diff b/test/fixtures/diffs/issue-13644-4.diff new file mode 100644 index 000000000..6309a5b5a --- /dev/null +++ b/test/fixtures/diffs/issue-13644-4.diff @@ -0,0 +1,7 @@ +--- a.txt 2013-07-27 04:20:45.973229414 +0900 ++++ b.txt 2013-07-27 04:20:52.366228105 +0900 +@@ -1,3 +1,3 @@ + aaaa +-日本記 ++日本誘 + bbbb diff --git a/test/fixtures/diffs/issue-13644-5.diff b/test/fixtures/diffs/issue-13644-5.diff new file mode 100644 index 000000000..033d6ed25 --- /dev/null +++ b/test/fixtures/diffs/issue-13644-5.diff @@ -0,0 +1,7 @@ +--- a.txt 2013-07-27 05:52:11.415223830 +0900 ++++ b.txt 2013-07-27 05:52:18.249190358 +0900 +@@ -1,3 +1,3 @@ + aaaa +-日本記ok ++日本誘ok + bbbb diff --git a/test/unit/lib/redmine/unified_diff_test.rb b/test/unit/lib/redmine/unified_diff_test.rb index 7e1ccbdd9..4dd5357db 100644 --- a/test/unit/lib/redmine/unified_diff_test.rb +++ b/test/unit/lib/redmine/unified_diff_test.rb @@ -308,6 +308,54 @@ DIFF end end + def test_offset_range_japanese_3 + # UTF-8 The 1st byte differs. + ja1 = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xa8\x98" + ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) + ja2 = "\xe6\x97\xa5\xe6\x9c\xac\xe5\xa8\x98" + ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + with_settings :repositories_encodings => '' do + diff = Redmine::UnifiedDiff.new( + read_diff_fixture('issue-13644-3.diff'), :type => 'sbs') + assert_equal 1, diff.size + assert_equal 3, diff.first.size + assert_equal ja1, diff.first[1].html_line_left + assert_equal ja2, diff.first[1].html_line_right + end + end + + def test_offset_range_japanese_4 + # UTF-8 The 2nd byte differs. + ja1 = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xa8\x98" + ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) + ja2 = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x98" + ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + with_settings :repositories_encodings => '' do + diff = Redmine::UnifiedDiff.new( + read_diff_fixture('issue-13644-4.diff'), :type => 'sbs') + assert_equal 1, diff.size + assert_equal 3, diff.first.size + assert_equal ja1, diff.first[1].html_line_left + assert_equal ja2, diff.first[1].html_line_right + end + end + + def test_offset_range_japanese_5 + # UTF-8 The 2nd byte differs. + ja1 = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xa8\x98ok" + ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) + ja2 = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x98ok" + ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + with_settings :repositories_encodings => '' do + diff = Redmine::UnifiedDiff.new( + read_diff_fixture('issue-13644-5.diff'), :type => 'sbs') + assert_equal 1, diff.size + assert_equal 3, diff.first.size + assert_equal ja1, diff.first[1].html_line_left + assert_equal ja2, diff.first[1].html_line_right + end + end + private def read_diff_fixture(filename) -- 2.39.5