changeset 25286:946ef64ede70 v8.2.3180

patch 8.2.3180: Vim9: memory leak when concatenating to an imported string Commit: https://github.com/vim/vim/commit/f6488547e3c7e41ff2c12dd0b93c9ef04e4c8c6f Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 18 21:24:50 2021 +0200 patch 8.2.3180: Vim9: memory leak when concatenating to an imported string Problem: Vim9: memory leak when concatenating to an imported string. Solution: Clear the destination.
author Bram Moolenaar <Bram@vim.org>
date Sun, 18 Jul 2021 21:30:03 +0200
parents e1da7f3315fa
children 8c572a349cff
files src/evalvars.c src/version.c
diffstat 2 files changed, 21 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -3262,6 +3262,7 @@ set_var_const(
 	    // TODO: check the type
 	    // TODO: check for const and locked
 	    dest_tv = sv->sv_tv;
+	    clear_tv(dest_tv);
 	}
     }
 
@@ -3272,12 +3273,13 @@ set_var_const(
 	    di = find_var_in_scoped_ht(name, TRUE);
 
 	if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
-					  && var_wrong_func_name(name, di == NULL))
+				      && var_wrong_func_name(name, di == NULL))
 	    goto failed;
 
 	if (need_convert_to_bool(type, tv))
 	{
-	    // Destination is a bool and the value is not, but it can be converted.
+	    // Destination is a bool and the value is not, but it can be
+	    // converted.
 	    CLEAR_FIELD(bool_tv);
 	    bool_tv.v_type = VAR_BOOL;
 	    bool_tv.vval.v_number = tv2bool(tv) ? VVAL_TRUE : VVAL_FALSE;
@@ -3290,14 +3292,14 @@ set_var_const(
 	    if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
 	    {
 		if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
-						 && (flags & ASSIGN_FOR_LOOP) == 0)
+					     && (flags & ASSIGN_FOR_LOOP) == 0)
 		{
 		    emsg(_(e_cannot_mod));
 		    goto failed;
 		}
 
 		if (is_script_local && vim9script
-				  && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0)
+			      && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0)
 		{
 		    semsg(_(e_redefining_script_item_str), name);
 		    goto failed;
@@ -3310,7 +3312,8 @@ set_var_const(
 		    // check the type and adjust to bool if needed
 		    where.wt_index = var_idx;
 		    where.wt_variable = TRUE;
-		    if (check_script_var_type(&di->di_tv, tv, name, where) == FAIL)
+		    if (check_script_var_type(&di->di_tv, tv, name, where)
+								       == FAIL)
 			goto failed;
 		}
 
@@ -3322,11 +3325,11 @@ set_var_const(
 		// can only redefine once
 		di->di_flags &= ~DI_FLAGS_RELOAD;
 
-		// A Vim9 script-local variable is also present in sn_all_vars and
-		// sn_var_vals.  It may set "type" from "tv".
+		// A Vim9 script-local variable is also present in sn_all_vars
+		// and sn_var_vals.  It may set "type" from "tv".
 		if (var_in_vim9script)
 		    update_vim9_script_var(FALSE, di, flags, tv, &type,
-					     (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
+					 (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
 	    }
 
 	    // existing variable, need to clear the value
@@ -3342,8 +3345,9 @@ set_var_const(
 		    {
 			char_u *val = tv_get_string(tv);
 
-			// Careful: when assigning to v:errmsg and tv_get_string()
-			// causes an error message the variable will already be set.
+			// Careful: when assigning to v:errmsg and
+			// tv_get_string() causes an error message the variable
+			// will already be set.
 			if (di->di_tv.vval.v_string == NULL)
 			    di->di_tv.vval.v_string = vim_strsave(val);
 		    }
@@ -3359,7 +3363,8 @@ set_var_const(
 		{
 		    di->di_tv.vval.v_number = tv_get_number(tv);
 		    if (STRCMP(varname, "searchforward") == 0)
-			set_search_direction(di->di_tv.vval.v_number ? '/' : '?');
+			set_search_direction(di->di_tv.vval.v_number
+								  ? '/' : '?');
 #ifdef FEAT_SEARCH_EXTRA
 		    else if (STRCMP(varname, "hlsearch") == 0)
 		    {
@@ -3382,7 +3387,7 @@ set_var_const(
 	{
 	    // Item not found, check if a function already exists.
 	    if (is_script_local && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
-		       && lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK)
+		   && lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK)
 	    {
 		semsg(_(e_redefining_script_item_str), name);
 		goto failed;
@@ -3405,7 +3410,7 @@ set_var_const(
 	    // Make sure the variable name is valid.  In Vim9 script an autoload
 	    // variable must be prefixed with "g:".
 	    if (!valid_varname(varname, !vim9script
-						   || STRNCMP(name, "g:", 2) == 0))
+					       || STRNCMP(name, "g:", 2) == 0))
 		goto failed;
 
 	    di = alloc(sizeof(dictitem_T) + STRLEN(varname));
@@ -3425,7 +3430,7 @@ set_var_const(
 	    // sn_var_vals. It may set "type" from "tv".
 	    if (var_in_vim9script)
 		update_vim9_script_var(TRUE, di, flags, tv, &type,
-					     (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
+					 (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
 	}
 
 	dest_tv = &di->di_tv;
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3180,
+/**/
     3179,
 /**/
     3178,