]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0490: matchfuzzy() can crash on long multi-word patterns v9.2.0490
authorglepnir <glephunter@gmail.com>
Sat, 16 May 2026 08:36:39 +0000 (08:36 +0000)
committerChristian Brabandt <cb@256bit.org>
Sat, 16 May 2026 08:36:39 +0000 (08:36 +0000)
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: #20209

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/fuzzy.c
src/testdir/test_matchfuzzy.vim
src/version.c

index bb140fcace72c0c4599341f789849afbbc62c3b3..2847a2071cfdf5eb9b484c21df118cdc76462452 100644 (file)
@@ -85,6 +85,7 @@ fuzzy_match(
     int                complete = FALSE;
     int                score = 0;
     int                numMatches = 0;
+    int                pat_chars = 0;
     score_t    fzy_score;
 
     *outScore = 0;
@@ -118,6 +119,17 @@ fuzzy_match(
                complete = TRUE;
            *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;
+       }
 
        score = FUZZY_SCORE_NONE;
        if (has_match(pat, str))
@@ -143,7 +155,7 @@ fuzzy_match(
        else
            *outScore += score;
 
-       numMatches += MB_CHARLEN(pat);
+       numMatches += pat_chars;
 
        if (complete || numMatches >= maxMatches)
            break;
index eb4c8c656751d2fa7b8101ce558d1bf7e6f6d5eb..dfeb074d7fb43639cf836a756e48573c9d0c5bf3 100644 (file)
@@ -322,4 +322,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
index fb89edd04e7faf2f6c2bf1d6bb67968a375ebc3d..0a4a84e29fd13a39b6cd866e7846cf641ace5c61 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    490,
 /**/
     489,
 /**/