Skip to content

Commit 60da9d8

Browse files
authored
Merge pull request microsoft#100482 from IllusionMH/search-step-over-surrogates-100134
Step over surrogate pairs on zero-lenth matches (fixes microsoft#100134)
2 parents 1f06ff4 + 206c06b commit 60da9d8

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

src/vs/editor/common/model/textModelSearch.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,12 @@ export class Searcher {
548548
if (matchStartIndex === this._prevMatchStartIndex && matchLength === this._prevMatchLength) {
549549
if (matchLength === 0) {
550550
// the search result is an empty string and won't advance `regex.lastIndex`, so `regex.exec` will stuck here
551-
// we attempt to recover from that by advancing by one
552-
this._searchRegex.lastIndex += 1;
551+
// we attempt to recover from that by advancing by two if surrogate pair found and by one otherwise
552+
if (strings.getNextCodePoint(text, textLength, this._searchRegex.lastIndex) > 0xFFFF) {
553+
this._searchRegex.lastIndex += 2;
554+
} else {
555+
this._searchRegex.lastIndex += 1;
556+
}
553557
continue;
554558
}
555559
// Exit early if the regex matches the same range twice

src/vs/editor/test/common/model/textModelSearch.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,4 +781,29 @@ suite('TextModelSearch', () => {
781781

782782
model.dispose();
783783
});
784+
785+
test('issue #100134. Zero-length matches should properly step over surrogate pairs', () => {
786+
// 1[Laptop]1 - there shoud be no matches inside of [Laptop] emoji
787+
assertFindMatches('1\uD83D\uDCBB1', '()', true, false, null,
788+
[
789+
[1, 1, 1, 1],
790+
[1, 2, 1, 2],
791+
[1, 4, 1, 4],
792+
[1, 5, 1, 5],
793+
794+
]
795+
);
796+
// 1[Hacker Cat]1 = 1[Cat Face][ZWJ][Laptop]1 - there shoud be matches between emoji and ZWJ
797+
// there shoud be no matches inside of [Cat Face] and [Laptop] emoji
798+
assertFindMatches('1\uD83D\uDC31\u200D\uD83D\uDCBB1', '()', true, false, null,
799+
[
800+
[1, 1, 1, 1],
801+
[1, 2, 1, 2],
802+
[1, 4, 1, 4],
803+
[1, 5, 1, 5],
804+
[1, 7, 1, 7],
805+
[1, 8, 1, 8]
806+
]
807+
);
808+
});
784809
});

0 commit comments

Comments
 (0)