Skip to content

Commit e9e485b

Browse files
Fix highlight range computation for non-ascii characters (#2742)
Fixes #2740 We were previously matching on the less specific 2-byte unicode point values, but this meant that something with with a 3 or 4 byte value (asian characters or emoji) would be first offset by 2 then loop incorrectly looking at the next character. The fix is to look for the largest byte match first and then narrow down to the smaller bit matches.
1 parent c77e306 commit e9e485b

2 files changed

Lines changed: 18 additions & 8 deletions

File tree

GitUpKit/Interface/GIFunctions-Tests.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ - (void)testHighlightingRange {
176176
XCTAssertEqual(addedRange.location, 3);
177177
XCTAssertEqual(addedRange.length, 2);
178178
}
179+
{
180+
// Fix for issue #2740
181+
const char* before = "中文命名.md";
182+
const char* after = "中文命名1.md";
183+
GIComputeHighlightRanges(before, strlen(before), [[NSString stringWithUTF8String:before] length], &deletedRange, after, strlen(after), [[NSString stringWithUTF8String:after] length], &addedRange);
184+
XCTAssertEqual(deletedRange.location, 4);
185+
XCTAssertEqual(deletedRange.length, 0);
186+
XCTAssertEqual(addedRange.location, 4);
187+
XCTAssertEqual(addedRange.length, 1);
188+
}
179189
}
180190

181191
@end

GitUpKit/Interface/GIFunctions.m

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ void GIComputeHighlightRanges(const char* deletedBytes, NSUInteger deletedCount,
3535
}
3636
if (remaining == 0) {
3737
unsigned char byte = *(unsigned char*)deletedMin;
38-
if (TEST_BITS(byte, 0b11000000)) {
39-
remaining = 2;
40-
} else if (TEST_BITS(byte, 0b11100000)) {
41-
remaining = 3;
42-
} else if (TEST_BITS(byte, 0b11110000)) {
43-
remaining = 4;
38+
if (TEST_BITS(byte, 0b11111100)) {
39+
remaining = 6;
4440
} else if (TEST_BITS(byte, 0b11111000)) {
4541
remaining = 5;
46-
} else if (TEST_BITS(byte, 0b11111100)) {
47-
remaining = 6;
42+
} else if (TEST_BITS(byte, 0b11110000)) {
43+
remaining = 4;
44+
} else if (TEST_BITS(byte, 0b11100000)) {
45+
remaining = 3;
46+
} else if (TEST_BITS(byte, 0b11000000)) {
47+
remaining = 2;
4848
} else {
4949
XLOG_DEBUG_CHECK(!(byte & (1 << 7)));
5050
remaining = 1;

0 commit comments

Comments
 (0)