]> granicus.if.org Git - vim/commitdiff
patch 9.0.0026: accessing freed memory with diff put v9.0.0026
authorBram Moolenaar <Bram@vim.org>
Sat, 2 Jul 2022 14:10:00 +0000 (15:10 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 2 Jul 2022 14:10:00 +0000 (15:10 +0100)
Problem:    Accessing freed memory with diff put.
Solution:   Bail out when diff pointer is no longer valid.

src/diff.c
src/version.c

index 91e5ae2f2f6890cbcba1901d12cb1babdeeb94fc..e4bafe2c934e24f30d8f52e85940b959ffecec41 100644 (file)
@@ -2642,6 +2642,20 @@ nv_diffgetput(int put, long count)
     ex_diffgetput(&ea);
 }
 
+/*
+ * Return TRUE if "diff" appears in the list of diff blocks of the current tab.
+ */
+    static int
+valid_diff(diff_T *diff)
+{
+    diff_T     *dp;
+
+    for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+       if (dp == diff)
+           return TRUE;
+    return FALSE;
+}
+
 /*
  * ":diffget"
  * ":diffput"
@@ -2899,9 +2913,9 @@ ex_diffgetput(exarg_T *eap)
                }
            }
 
-           // Adjust marks.  This will change the following entries!
            if (added != 0)
            {
+               // Adjust marks.  This will change the following entries!
                mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added);
                if (curwin->w_cursor.lnum >= lnum)
                {
@@ -2923,7 +2937,13 @@ ex_diffgetput(exarg_T *eap)
 #endif
                vim_free(dfree);
            }
-           else
+
+           // mark_adjust() may have made "dp" invalid.  We don't know where
+           // to continue then, bail out.
+           if (added != 0 && !valid_diff(dp))
+               break;
+
+           if (dfree == NULL)
                // mark_adjust() may have changed the count in a wrong way
                dp->df_count[idx_to] = new_count;
 
index 8c9325d9410e20f1a9a6bf880ddd5da0ab2ddc6c..0eb586396781103ca7148953abea5883ecb3501a 100644 (file)
@@ -735,6 +735,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    26,
 /**/
     25,
 /**/