]> granicus.if.org Git - vim/commitdiff
patch 8.2.3721: using memory freed by losing the clipboard selection v8.2.3721
authorBram Moolenaar <Bram@vim.org>
Thu, 2 Dec 2021 18:42:33 +0000 (18:42 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 2 Dec 2021 18:42:33 +0000 (18:42 +0000)
Problem:    Using memory freed by losing the clipboard selection. (Dominique
            PellĂ©)
Solution:   Check y_array is still valid after calling changed_lines().
            (closes #9253)

src/errors.h
src/register.c
src/version.c

index 1d6a3a3c661819622bd145cb8212368b55513142..047ff9c8f1dfb8772b8205466324921a3c53e4fd 100644 (file)
@@ -316,7 +316,8 @@ EXTERN char e_cannot_index_number[]
        INIT(= N_("E1062: Cannot index a Number"));
 EXTERN char e_type_mismatch_for_v_variable[]
        INIT(= N_("E1063: Type mismatch for v: variable"));
-// E1064 unused
+EXTERN char e_yank_register_changed_while_using_it[]
+       INIT(= N_("E1064: Yank register changed while using it"));
 // E1065 unused
 EXTERN char e_cannot_declare_a_register_str[]
        INIT(= N_("E1066: Cannot declare a register: %s"));
index 3fc8b6340c2730a76db85ff26b963a7eb2ab6030..cd2e0e1567f3b32daa5a8dd6d6dcaec4a0d5d2dc 100644 (file)
@@ -1550,6 +1550,7 @@ do_put(
     long       j;
     struct block_def bd;
     char_u     **y_array = NULL;
+    yankreg_T  *y_current_used = NULL;
     long       nr_lines = 0;
     pos_T      new_cursor;
     int                indent;
@@ -1660,6 +1661,7 @@ do_put(
        y_width = y_current->y_width;
        y_size = y_current->y_size;
        y_array = y_current->y_array;
+       y_current_used = y_current;
     }
 
     if (y_type == MLINE)
@@ -2208,6 +2210,14 @@ error:
            else
                changed_lines(curbuf->b_op_start.lnum, 0,
                                           curbuf->b_op_start.lnum, nr_lines);
+           if (y_current_used != NULL && (y_current_used != y_current
+                                            || y_current->y_array != y_array))
+           {
+               // Something invoked through changed_lines() has changed the
+               // yank buffer, e.g. a GUI clipboard callback.
+               emsg(_(e_yank_register_changed_while_using_it));
+               goto end;
+           }
 
            // Put the '] mark on the first byte of the last inserted character.
            // Correct the length for change in indent.
index 810567f40ea638d617dc8a644a72ca1bd0e3e300..30cd9bced06a622bcaa5d91d2eec06c8609709c6 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3721,
 /**/
     3720,
 /**/