summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-02 18:42:33 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-02 18:42:33 +0000
commit9ac38129b6d409f73e29b1d51a5d459cf050410f (patch)
tree6425c200c8015001df1e61d3c633a32f48f6f6e2
parent69c76171f1a78b829196f72d7010fbe1d9ad2944 (diff)
downloadvim-git-9ac38129b6d409f73e29b1d51a5d459cf050410f.tar.gz
patch 8.2.3721: using memory freed by losing the clipboard selectionv8.2.3721
Problem: Using memory freed by losing the clipboard selection. (Dominique Pellé) Solution: Check y_array is still valid after calling changed_lines(). (closes #9253)
-rw-r--r--src/errors.h3
-rw-r--r--src/register.c10
-rw-r--r--src/version.c2
3 files changed, 14 insertions, 1 deletions
diff --git a/src/errors.h b/src/errors.h
index 1d6a3a3c6..047ff9c8f 100644
--- 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"));
diff --git a/src/register.c b/src/register.c
index 3fc8b6340..cd2e0e156 100644
--- 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.
diff --git a/src/version.c b/src/version.c
index 810567f40..30cd9bced 100644
--- 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,