]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1499: using uninitialized memory with fuzzy matching v9.0.1499
authorBram Moolenaar <Bram@vim.org>
Sat, 29 Apr 2023 20:38:04 +0000 (21:38 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 29 Apr 2023 20:38:04 +0000 (21:38 +0100)
Problem:    Using uninitialized memory with fuzzy matching.
Solution:   Initialize the arrays used to store match positions.

src/quickfix.c
src/search.c
src/testdir/test_matchfuzzy.vim
src/version.c

index 13292e2f7515c6ba92ffb343f0659564e5ea1ed9..553ad457880a5d2c5de4a5bb07800b44090bf0cc 100644 (file)
@@ -6058,6 +6058,8 @@ vgr_match_buflines(
     long       lnum;
     colnr_T    col;
     int                pat_len = (int)STRLEN(spat);
+    if (pat_len > MAX_FUZZY_MATCHES)
+       pat_len = MAX_FUZZY_MATCHES;
 
     for (lnum = 1; lnum <= buf->b_ml.ml_line_count && *tomatch > 0; ++lnum)
     {
@@ -6066,7 +6068,7 @@ vgr_match_buflines(
        {
            // Regular expression match
            while (vim_regexec_multi(regmatch, curwin, buf, lnum,
-                       col, NULL) > 0)
+                                                               col, NULL) > 0)
            {
                // Pass the buffer number so that it gets used even for a
                // dummy buffer, unless duplicate_name is set, then the
@@ -6112,6 +6114,7 @@ vgr_match_buflines(
            int_u   sz = ARRAY_LENGTH(matches);
 
            // Fuzzy string match
+           CLEAR_FIELD(matches);
            while (fuzzy_match(str + col, spat, FALSE, &score, matches, sz) > 0)
            {
                // Pass the buffer number so that it gets used even for a
index 74ca8fefb2c56288da94c62f9f56ffc26538609c..5e38570780319e0bf59b482cd2261b04c2f90fac 100644 (file)
@@ -4422,14 +4422,14 @@ fuzzy_match_recursive(
        // Found match
        if (vim_tolower(c1) == vim_tolower(c2))
        {
-           int_u       recursiveMatches[MAX_FUZZY_MATCHES];
-           int         recursiveScore = 0;
-           char_u      *next_char;
-
            // Supplied matches buffer was too short
            if (nextMatch >= maxMatches)
                return 0;
 
+           int         recursiveScore = 0;
+           int_u       recursiveMatches[MAX_FUZZY_MATCHES];
+           CLEAR_FIELD(recursiveMatches);
+
            // "Copy-on-Write" srcMatches into matches
            if (first_match && srcMatches)
            {
@@ -4438,10 +4438,7 @@ fuzzy_match_recursive(
            }
 
            // Recursive call that "skips" this match
-           if (has_mbyte)
-               next_char = str + (*mb_ptr2len)(str);
-           else
-               next_char = str + 1;
+           char_u *next_char = str + (has_mbyte ? (*mb_ptr2len)(str) : 1);
            if (fuzzy_match_recursive(fuzpat, next_char, strIdx + 1,
                        &recursiveScore, strBegin, strLen, matches,
                        recursiveMatches,
@@ -4506,8 +4503,8 @@ fuzzy_match_recursive(
  * Uses char_u for match indices. Therefore patterns are limited to
  * MAX_FUZZY_MATCHES characters.
  *
- * Returns TRUE if 'pat_arg' matches 'str'. Also returns the match score in
- * 'outScore' and the matching character positions in 'matches'.
+ * Returns TRUE if "pat_arg" matches "str". Also returns the match score in
+ * "outScore" and the matching character positions in "matches".
  */
     int
 fuzzy_match(
index 502d136ccf2aa07aeb8d3fa94c1beaecc27cb57e..43eca8ff08af62852dba5df77493d81251e75264 100644 (file)
@@ -2,6 +2,7 @@
 
 source shared.vim
 source check.vim
+source term_util.vim
 
 " Test for matchfuzzy()
 func Test_matchfuzzy()
@@ -253,4 +254,30 @@ func Test_matchfuzzy_limit()
   call assert_equal([{'id': 5, 'val': 'crayon'}], l->matchfuzzy('c', #{key: 'val', limit: 1}))
 endfunc
 
+" This was using uninitialized memory
+func Test_matchfuzzy_initialized()
+  CheckRunVimInTerminal
+
+  " This can take a very long time (esp. when using valgrind).  Run in a
+  " separate Vim instance and kill it after two seconds.  We only check for
+  " memory errors.
+  let lines =<< trim END
+      lvimgrep [ss [fg*
+  END
+  call writefile(lines, 'XTest_matchfuzzy', 'D')
+
+  let buf = RunVimInTerminal('-u NONE -X -Z', {})
+  call term_sendkeys(buf, ":source XTest_matchfuzzy\n")
+  call TermWait(buf, 2000)
+
+  let job = term_getjob(buf)
+  if job_status(job) == "run"
+    call job_stop(job, "int")
+    call TermWait(buf, 50)
+  endif
+
+  " clean up
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index ce94bc80c0face356746812f8fa28d9c9e698e91..460b49b9e67b903ef1b3e9187e33edc3439b3e57 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1499,
 /**/
     1498,
 /**/