changeset 26380:ac0e63cbf00b v8.2.3721

patch 8.2.3721: using memory freed by losing the clipboard selection Commit: https://github.com/vim/vim/commit/9ac38129b6d409f73e29b1d51a5d459cf050410f Author: Bram Moolenaar <Bram@vim.org> Date: Thu Dec 2 18:42:33 2021 +0000 patch 8.2.3721: using memory freed by losing the clipboard selection Problem: Using memory freed by losing the clipboard selection. (Dominique Pell?) Solution: Check y_array is still valid after calling changed_lines(). (closes #9253)
author Bram Moolenaar <Bram@vim.org>
date Thu, 02 Dec 2021 19:45:03 +0100
parents f6e050c67b71
children 2ad7829cf85a
files src/errors.h src/register.c src/version.c
diffstat 3 files changed, 14 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/errors.h
+++ b/src/errors.h
@@ -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"));
--- a/src/register.c
+++ b/src/register.c
@@ -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.
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3721,
+/**/
     3720,
 /**/
     3719,