diff --git a/src/vs/base/common/filters.ts b/src/vs/base/common/filters.ts index e16f6f4c708af5723e2e1c47e4511a542ad6bcc8..71b78527b399bada1a044526380790e8f76433ba 100644 --- a/src/vs/base/common/filters.ts +++ b/src/vs/base/common/filters.ts @@ -559,6 +559,8 @@ export function fuzzyScore(pattern: string, patternLow: string, patternStart: nu let patternPos = patternStart; let wordPos = wordStart; + let hasStrongFirstMatch = false; + // There will be a match, fill in tables for (row = 1, patternPos = patternStart; patternPos < patternLen; row++, patternPos++) { @@ -566,6 +568,10 @@ export function fuzzyScore(pattern: string, patternLow: string, patternStart: nu const score = _doScore(pattern, patternLow, patternPos, patternStart, word, wordLow, wordPos); + if (patternPos === patternStart && score > 1) { + hasStrongFirstMatch = true; + } + _scores[row][column] = score; const diag = _table[row - 1][column - 1] + (score > 1 ? 1 : score); @@ -604,6 +610,10 @@ export function fuzzyScore(pattern: string, patternLow: string, patternStart: nu printTables(pattern, patternStart, word, wordStart); } + if (!hasStrongFirstMatch && !firstMatchCanBeWeak) { + return undefined; + } + _matchesCount = 0; _topScore = -100; _wordStart = wordStart; diff --git a/src/vs/base/test/common/filters.test.ts b/src/vs/base/test/common/filters.test.ts index 0cf70ae8555c5105b775f1266b0e706b67def39c..ffbe5c89c878957570f603d402e8290b06748305 100644 --- a/src/vs/base/test/common/filters.test.ts +++ b/src/vs/base/test/common/filters.test.ts @@ -343,6 +343,36 @@ suite('Filters', () => { ); }); + test('Freeze when fjfj -> jfjf, https://github.com/microsoft/vscode/issues/91807', function () { + assertMatches( + 'jfjfj', + 'fjfjfjfjfjfjfjfjfjfjfj', + undefined, fuzzyScore + ); + assertMatches( + 'jfjfjfjfjfjfjfjfjfj', + 'fjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfj', + undefined, fuzzyScore + ); + assertMatches( + 'jfjfjfjfjfjfjfjfjfjjfjfjfjfjfjfjfjfjfjjfjfjfjfjfjfjfjfjfjjfjfjfjfjfjfjfjfjfjjfjfjfjfjfjfjfjfjfjjfjfjfjfjfjfjfjfjfj', + 'fjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfj', + undefined, fuzzyScore + ); + assertMatches( + 'jfjfjfjfjfjfjfjfjfj', + 'fJfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfj', + 'f^J^f^j^f^j^f^j^f^j^f^j^f^j^f^j^f^j^f^jfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfj', // strong match + fuzzyScore + ); + assertMatches( + 'jfjfjfjfjfjfjfjfjfj', + 'fjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfj', + 'f^j^f^j^f^j^f^j^f^j^f^j^f^j^f^j^f^j^f^jfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfjfj', // any match + fuzzyScore, { firstMatchCanBeWeak: true } + ); + }); + test('fuzzyScore, issue #26423', function () { assertMatches('baba', 'abababab', undefined, fuzzyScore);