patch 9.1.1628: fuzzy.c has a few issues

Commit: 
https://github.com/vim/vim/commit/17a6d696bd2f9526f2c4beae95208626d0e8d922
Author: glepnir <glephun...@gmail.com>
Date:   Wed Aug 13 22:02:30 2025 +0200

    patch 9.1.1628: fuzzy.c has a few issues
    
    Problem:  fuzzy.c has a few issues
    Solution: Use Vims memory management, update style
              (glepnir)
    
    Problem:
    - Missing cleanup of lmatchpos lists causing memory leaks
    - Missing error handling for list operations
    - Use of malloc() instead of Vim's alloc() functions
    - Inconsistent C-style comments
    - Missing null pointer checks for memory allocation
    - Incorrect use of vim_free() for list objects
    
    Solution:
    - Add proper cleanup of lmatchpos in done section using list_free()
    - Set lmatchpos to NULL after successful transfer to avoid confusion
    - Add error handling for list_append_tv() failures
    - Replace malloc() with alloc() and add null pointer checks
    - Convert C-style comments to C++ style for consistency
    - Fix vim_free() calls to use list_free() for list objects
    
    closes: #17984
    
    Signed-off-by: glepnir <glephun...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/fuzzy.c b/src/fuzzy.c
index 6ebfa5b21..c1b216ce5 100644
--- a/src/fuzzy.c
+++ b/src/fuzzy.c
@@ -49,7 +49,7 @@ static score_t match_positions(char_u *needle, char_u 
*haystack, int_u *position
 static int has_match(char_u *needle, char_u *haystack);
 
 #define SCORE_MAX INFINITY
-#define SCORE_MIN -INFINITY
+#define SCORE_MIN (-INFINITY)
 #define SCORE_SCALE 1000
 
 typedef struct
@@ -72,12 +72,12 @@ typedef struct
  */
     int
 fuzzy_match(
-       char_u          *str,
-       char_u          *pat_arg,
-       int             matchseq,
-       int             *outScore,
-       int_u           *matches,
-       int             maxMatches)
+    char_u     *str,
+    char_u     *pat_arg,
+    int                matchseq,
+    int                *outScore,
+    int_u      *matches,
+    int                maxMatches)
 {
     char_u     *save_pat;
     char_u     *pat;
@@ -206,21 +206,20 @@ fuzzy_match_item_compare(const void *s1, const void *s2)
  */
     static void
 fuzzy_match_in_list(
-       list_T          *l,
-       char_u          *str,
-       int             matchseq,
-       char_u          *key,
-       callback_T      *item_cb,
-       int             retmatchpos,
-       list_T          *fmatchlist,
-       long            max_matches)
+    list_T     *l,
+    char_u     *str,
+    int                matchseq,
+    char_u     *key,
+    callback_T *item_cb,
+    int                retmatchpos,
+    list_T     *fmatchlist,
+    long       max_matches)
 {
-    long       len;
-    fuzzyItem_T        *items;
-    listitem_T *li;
-    int                i = 0;
-    long       match_count = 0;
-    int_u      matches[FUZZY_MATCH_MAX_LEN];
+    long           len;
+    fuzzyItem_T            *items;
+    listitem_T     *li;
+    long           match_count = 0;
+    int_u          matches[FUZZY_MATCH_MAX_LEN];
 
     len = list_len(l);
     if (len == 0)
@@ -285,13 +284,13 @@ fuzzy_match_in_list(
            items[match_count].score = score;
            items[match_count].pat = str;
            items[match_count].startpos = matches[0];
-           if (itemstr_allocate)
-               items[match_count].itemstr = vim_strsave(itemstr);
-           else
-               items[match_count].itemstr = itemstr;
+           items[match_count].itemstr = itemstr_allocate
+                                           ? vim_strsave(itemstr) : itemstr;
            items[match_count].itemstr_allocated = itemstr_allocate;
 
-           // Copy the list of matching positions in itemstr to a list
+           // Copy the list of matching positions in itemstr to a list, if
+           // "retmatchpos" is set.
+           if (retmatchpos)
            {
                int     j = 0;
                char_u  *p;
@@ -347,8 +346,11 @@ fuzzy_match_in_list(
            retlist = fmatchlist;
 
        // Copy the matching strings to the return list
-       for (i = 0; i < match_count; i++)
-           list_append_tv(retlist, &items[i].item->li_tv);
+       for (int i = 0; i < match_count; i++)
+       {
+           if (list_append_tv(retlist, &items[i].item->li_tv) == FAIL)
+               goto done;
+       }
 
        // next copy the list of matching positions
        if (retmatchpos)
@@ -358,26 +360,40 @@ fuzzy_match_in_list(
                goto done;
            retlist = li->li_tv.vval.v_list;
 
-           for (i = 0; i < match_count; i++)
-               if (items[i].lmatchpos != NULL
-                     && list_append_list(retlist, items[i].lmatchpos) == FAIL)
-                   goto done;
+           for (int i = 0; i < match_count; i++)
+           {
+               if (items[i].lmatchpos != NULL)
+               {
+                   if (list_append_list(retlist, items[i].lmatchpos) == OK)
+                       items[i].lmatchpos = NULL;
+                   else
+                       goto done;
+
+               }
+           }
 
            // copy the matching scores
            li = list_find(fmatchlist, -1);
            if (li == NULL || li->li_tv.vval.v_list == NULL)
                goto done;
            retlist = li->li_tv.vval.v_list;
-           for (i = 0; i < match_count; i++)
+           for (int i = 0; i < match_count; i++)
+           {
                if (list_append_number(retlist, items[i].score) == FAIL)
                    goto done;
+           }
        }
     }
 
 done:
-    for (i = 0; i < match_count; i++)
+    for (int i = 0; i < match_count; i++)
+    {
        if (items[i].itemstr_allocated)
            vim_free(items[i].itemstr);
+
+       if (items[i].lmatchpos)
+           list_free(items[i].lmatchpos);
+    }
     vim_free(items);
 }
 
@@ -480,7 +496,7 @@ do_fuzzymatch(typval_T *argvars, typval_T *rettv, int 
retmatchpos)
            goto done;
        if (list_append_list(rettv->vval.v_list, l) == FAIL)
        {
-           vim_free(l);
+           list_free(l);
            goto done;
        }
        l = list_alloc();
@@ -488,7 +504,7 @@ do_fuzzymatch(typval_T *argvars, typval_T *rettv, int 
retmatchpos)
            goto done;
        if (list_append_list(rettv->vval.v_list, l) == FAIL)
        {
-           vim_free(l);
+           list_free(l);
            goto done;
        }
        l = list_alloc();
@@ -496,7 +512,7 @@ do_fuzzymatch(typval_T *argvars, typval_T *rettv, int 
retmatchpos)
            goto done;
        if (list_append_list(rettv->vval.v_list, l) == FAIL)
        {
-           vim_free(l);
+           list_free(l);
            goto done;
        }
     }
@@ -1020,7 +1036,7 @@ match_row(const match_struct *match, int row, score_t 
*curr_D,
     score_t prev_score = SCORE_MIN;
     score_t gap_score = i == n - 1 ? SCORE_GAP_TRAILING : SCORE_GAP_INNER;
 
-    /* These will not be used with this value, but not all compilers see it */
+    // These will not be used with this value, but not all compilers see it
     score_t prev_M = SCORE_MIN, prev_D = SCORE_MIN;
 
     for (int j = 0; j < m; j++)
@@ -1036,7 +1052,7 @@ match_row(const match_struct *match, int row, score_t 
*curr_D,
            { /* i > 0 && j > 0*/
                score = MAX(
                        prev_M + match_bonus[j],
-                       /* consecutive match, doesn't stack with match_bonus */
+                       // consecutive match, doesn't stack with match_bonus
                        prev_D + SCORE_MATCH_CONSECUTIVE);
            }
            prev_D = last_D[j];
@@ -1068,38 +1084,37 @@ match_positions(char_u *needle, char_u *haystack, int_u 
*positions)
 
     if (m > MATCH_MAX_LEN || n > m)
     {
-       /*
-        * Unreasonably large candidate: return no score
-        * If it is a valid match it will still be returned, it will
-        * just be ranked below any reasonably sized candidates
-        */
+       // Unreasonably large candidate: return no score
+       // If it is a valid match it will still be returned, it will
+       // just be ranked below any reasonably sized candidates
        return SCORE_MIN;
     }
     else if (n == m)
     {
-       /* Since this method can only be called with a haystack which
-        * matches needle. If the lengths of the strings are equal the
-        * strings themselves must also be equal (ignoring case).
-        */
+       // Since this method can only be called with a haystack which
+       // matches needle. If the lengths of the strings are equal the
+       // strings themselves must also be equal (ignoring case).
        if (positions)
            for (int i = 0; i < n; i++)
                positions[i] = i;
        return SCORE_MAX;
     }
 
-    /*
-     * D[][] Stores the best score for this position ending with a match.
-     * M[][] Stores the best possible score at this position.
-     */
+    // D[][] Stores the best score for this position ending with a match.
+    // M[][] Stores the best possible score at this position.
     score_t (*D)[MATCH_MAX_LEN], (*M)[MATCH_MAX_LEN];
-    M = malloc(sizeof(score_t) * MATCH_MAX_LEN * n);
-    D = malloc(sizeof(score_t) * MATCH_MAX_LEN * n);
+    M = alloc(sizeof(score_t) * MATCH_MAX_LEN * n);
+    if (!M)
+       return SCORE_MIN;
+    D = alloc(sizeof(score_t) * MATCH_MAX_LEN * n);
+    if (!D)
+       return SCORE_MIN;
 
     match_row(&match, 0, D[0], M[0], D[0], M[0]);
     for (int i = 1; i < n; i++)
        match_row(&match, i, D[i], M[i], D[i - 1], M[i - 1]);
 
-    /* backtrace to find the positions of optimal matching */
+    // backtrace to find the positions of optimal matching
     if (positions)
     {
        int match_required = 0;
@@ -1107,23 +1122,19 @@ match_positions(char_u *needle, char_u *haystack, int_u 
*positions)
        {
            for (; j >= 0; j--)
            {
-               /*
-                * There may be multiple paths which result in
-                * the optimal weight.
-                *
-                * For simplicity, we will pick the first one
-                * we encounter, the latest in the candidate
-                * string.
-                */
+               // There may be multiple paths which result in
+               // the optimal weight.
+               //
+               // For simplicity, we will pick the first one
+               // we encounter, the latest in the candidate
+               // string.
                if (D[i][j] != SCORE_MIN &&
                        (match_required || D[i][j] == M[i][j]))
                {
-                   /* If this score was determined using
-                    * SCORE_MATCH_CONSECUTIVE, the
-                    * previous character MUST be a match
-                    */
-                   match_required =
-                       i && j &&
+                   // If this score was determined using
+                   // SCORE_MATCH_CONSECUTIVE, the
+                   // previous character MUST be a match
+                   match_required = i && j &&
                        M[i][j] == D[i - 1][j - 1] + SCORE_MATCH_CONSECUTIVE;
                    positions[i] = j--;
                    break;
diff --git a/src/version.c b/src/version.c
index 87550542e..01eadc2f0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -719,6 +719,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1628,
 /**/
     1627,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1umHsF-00D51h-Tb%40256bit.org.

Raspunde prin e-mail lui