]> granicus.if.org Git - vim/commitdiff
patch 8.2.3180: Vim9: memory leak when concatenating to an imported string v8.2.3180
authorBram Moolenaar <Bram@vim.org>
Sun, 18 Jul 2021 19:24:50 +0000 (21:24 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 18 Jul 2021 19:24:50 +0000 (21:24 +0200)
Problem:    Vim9: memory leak when concatenating to an imported string.
Solution:   Clear the destination.

src/evalvars.c
src/version.c

index 3f209ba2166f7f23b67474b42cb087ecf0292136..dcf1058dec73d2b6a1e41cfd459bab53dca6630d 100644 (file)
@@ -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;
index 48e6748aeb647949610c60c68df9ef483618c7e9..b59eca27a6ac1f26ba79ab442d3c8a6494f0a0e5 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3180,
 /**/
     3179,
 /**/