vim-patch:9.2.0490: matchfuzzy() can crash on long multi-word patterns (#39809)

Problem:  matchfuzzy() can crash on long multi-word patterns.
Solution: Clamp pat_chars to maxMatches and stop before calling
          match_positions() when the buffer is full (glepnir).

closes: vim/vim#20209

88b00d1c57

Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
zeertzjq
2026-05-16 18:28:42 +08:00
committed by GitHub
parent b62c1049c0
commit b92ca58d69
2 changed files with 22 additions and 1 deletions

View File

@@ -78,6 +78,7 @@ bool fuzzy_match(char *const str, const char *const pat_arg, const bool matchseq
{
bool complete = false;
int numMatches = 0;
int pat_chars = 0;
*outScore = 0;
@@ -104,6 +105,17 @@ bool fuzzy_match(char *const str, const char *const pat_arg, const bool matchseq
}
*p = NUL;
}
// match_positions() always writes pat_chars entries,
// so bail if they won't fit.
pat_chars = mb_charlen(pat);
if (pat_chars > maxMatches) {
pat_chars = maxMatches;
}
if (numMatches > maxMatches - pat_chars) {
numMatches = 0;
*outScore = FUZZY_SCORE_NONE;
break;
}
int score = FUZZY_SCORE_NONE;
if (has_match(pat, str)) {
@@ -131,7 +143,7 @@ bool fuzzy_match(char *const str, const char *const pat_arg, const bool matchseq
*outScore += score;
}
numMatches += mb_charlen(pat);
numMatches += pat_chars;
if (complete || numMatches >= maxMatches) {
break;

View File

@@ -333,4 +333,13 @@ func Test_matchfuzzy_initialized()
call StopVimInTerminal(buf)
endfunc
func Test_matchfuzzy_long_multiword_no_overflow()
let word = repeat('a', 100)
let pat_ok = repeat(word . ' ', 9) . word
call assert_equal([word], matchfuzzy([word], pat_ok))
let pat_overflow = repeat(word . ' ', 14) . word
call assert_equal([[], [], []], matchfuzzypos([word], pat_overflow))
endfunc
" vim: shiftwidth=2 sts=2 expandtab