comparison src/evalvars.c @ 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 29191571eceb
children 90fa50a31994
comparison
equal deleted inserted replaced
25285:e1da7f3315fa 25286:946ef64ede70
3260 sv = ((svar_T *)si->sn_var_vals.ga_data) 3260 sv = ((svar_T *)si->sn_var_vals.ga_data)
3261 + import->imp_var_vals_idx; 3261 + import->imp_var_vals_idx;
3262 // TODO: check the type 3262 // TODO: check the type
3263 // TODO: check for const and locked 3263 // TODO: check for const and locked
3264 dest_tv = sv->sv_tv; 3264 dest_tv = sv->sv_tv;
3265 clear_tv(dest_tv);
3265 } 3266 }
3266 } 3267 }
3267 3268
3268 if (dest_tv == NULL) 3269 if (dest_tv == NULL)
3269 { 3270 {
3270 // Search in parent scope which is possible to reference from lambda 3271 // Search in parent scope which is possible to reference from lambda
3271 if (di == NULL) 3272 if (di == NULL)
3272 di = find_var_in_scoped_ht(name, TRUE); 3273 di = find_var_in_scoped_ht(name, TRUE);
3273 3274
3274 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) 3275 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
3275 && var_wrong_func_name(name, di == NULL)) 3276 && var_wrong_func_name(name, di == NULL))
3276 goto failed; 3277 goto failed;
3277 3278
3278 if (need_convert_to_bool(type, tv)) 3279 if (need_convert_to_bool(type, tv))
3279 { 3280 {
3280 // Destination is a bool and the value is not, but it can be converted. 3281 // Destination is a bool and the value is not, but it can be
3282 // converted.
3281 CLEAR_FIELD(bool_tv); 3283 CLEAR_FIELD(bool_tv);
3282 bool_tv.v_type = VAR_BOOL; 3284 bool_tv.v_type = VAR_BOOL;
3283 bool_tv.vval.v_number = tv2bool(tv) ? VVAL_TRUE : VVAL_FALSE; 3285 bool_tv.vval.v_number = tv2bool(tv) ? VVAL_TRUE : VVAL_FALSE;
3284 tv = &bool_tv; 3286 tv = &bool_tv;
3285 } 3287 }
3288 { 3290 {
3289 // Item already exists. Allowed to replace when reloading. 3291 // Item already exists. Allowed to replace when reloading.
3290 if ((di->di_flags & DI_FLAGS_RELOAD) == 0) 3292 if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
3291 { 3293 {
3292 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 3294 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
3293 && (flags & ASSIGN_FOR_LOOP) == 0) 3295 && (flags & ASSIGN_FOR_LOOP) == 0)
3294 { 3296 {
3295 emsg(_(e_cannot_mod)); 3297 emsg(_(e_cannot_mod));
3296 goto failed; 3298 goto failed;
3297 } 3299 }
3298 3300
3299 if (is_script_local && vim9script 3301 if (is_script_local && vim9script
3300 && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0) 3302 && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0)
3301 { 3303 {
3302 semsg(_(e_redefining_script_item_str), name); 3304 semsg(_(e_redefining_script_item_str), name);
3303 goto failed; 3305 goto failed;
3304 } 3306 }
3305 3307
3308 where_T where; 3310 where_T where;
3309 3311
3310 // check the type and adjust to bool if needed 3312 // check the type and adjust to bool if needed
3311 where.wt_index = var_idx; 3313 where.wt_index = var_idx;
3312 where.wt_variable = TRUE; 3314 where.wt_variable = TRUE;
3313 if (check_script_var_type(&di->di_tv, tv, name, where) == FAIL) 3315 if (check_script_var_type(&di->di_tv, tv, name, where)
3316 == FAIL)
3314 goto failed; 3317 goto failed;
3315 } 3318 }
3316 3319
3317 if (var_check_permission(di, name) == FAIL) 3320 if (var_check_permission(di, name) == FAIL)
3318 goto failed; 3321 goto failed;
3320 else 3323 else
3321 { 3324 {
3322 // can only redefine once 3325 // can only redefine once
3323 di->di_flags &= ~DI_FLAGS_RELOAD; 3326 di->di_flags &= ~DI_FLAGS_RELOAD;
3324 3327
3325 // A Vim9 script-local variable is also present in sn_all_vars and 3328 // A Vim9 script-local variable is also present in sn_all_vars
3326 // sn_var_vals. It may set "type" from "tv". 3329 // and sn_var_vals. It may set "type" from "tv".
3327 if (var_in_vim9script) 3330 if (var_in_vim9script)
3328 update_vim9_script_var(FALSE, di, flags, tv, &type, 3331 update_vim9_script_var(FALSE, di, flags, tv, &type,
3329 (flags & ASSIGN_NO_MEMBER_TYPE) == 0); 3332 (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
3330 } 3333 }
3331 3334
3332 // existing variable, need to clear the value 3335 // existing variable, need to clear the value
3333 3336
3334 // Handle setting internal di: variables separately where needed to 3337 // Handle setting internal di: variables separately where needed to
3340 VIM_CLEAR(di->di_tv.vval.v_string); 3343 VIM_CLEAR(di->di_tv.vval.v_string);
3341 if (copy || tv->v_type != VAR_STRING) 3344 if (copy || tv->v_type != VAR_STRING)
3342 { 3345 {
3343 char_u *val = tv_get_string(tv); 3346 char_u *val = tv_get_string(tv);
3344 3347
3345 // Careful: when assigning to v:errmsg and tv_get_string() 3348 // Careful: when assigning to v:errmsg and
3346 // causes an error message the variable will already be set. 3349 // tv_get_string() causes an error message the variable
3350 // will already be set.
3347 if (di->di_tv.vval.v_string == NULL) 3351 if (di->di_tv.vval.v_string == NULL)
3348 di->di_tv.vval.v_string = vim_strsave(val); 3352 di->di_tv.vval.v_string = vim_strsave(val);
3349 } 3353 }
3350 else 3354 else
3351 { 3355 {
3357 } 3361 }
3358 else if (di->di_tv.v_type == VAR_NUMBER) 3362 else if (di->di_tv.v_type == VAR_NUMBER)
3359 { 3363 {
3360 di->di_tv.vval.v_number = tv_get_number(tv); 3364 di->di_tv.vval.v_number = tv_get_number(tv);
3361 if (STRCMP(varname, "searchforward") == 0) 3365 if (STRCMP(varname, "searchforward") == 0)
3362 set_search_direction(di->di_tv.vval.v_number ? '/' : '?'); 3366 set_search_direction(di->di_tv.vval.v_number
3367 ? '/' : '?');
3363 #ifdef FEAT_SEARCH_EXTRA 3368 #ifdef FEAT_SEARCH_EXTRA
3364 else if (STRCMP(varname, "hlsearch") == 0) 3369 else if (STRCMP(varname, "hlsearch") == 0)
3365 { 3370 {
3366 no_hlsearch = !di->di_tv.vval.v_number; 3371 no_hlsearch = !di->di_tv.vval.v_number;
3367 redraw_all_later(SOME_VALID); 3372 redraw_all_later(SOME_VALID);
3380 } 3385 }
3381 else 3386 else
3382 { 3387 {
3383 // Item not found, check if a function already exists. 3388 // Item not found, check if a function already exists.
3384 if (is_script_local && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0 3389 if (is_script_local && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
3385 && lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK) 3390 && lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK)
3386 { 3391 {
3387 semsg(_(e_redefining_script_item_str), name); 3392 semsg(_(e_redefining_script_item_str), name);
3388 goto failed; 3393 goto failed;
3389 } 3394 }
3390 3395
3403 } 3408 }
3404 3409
3405 // Make sure the variable name is valid. In Vim9 script an autoload 3410 // Make sure the variable name is valid. In Vim9 script an autoload
3406 // variable must be prefixed with "g:". 3411 // variable must be prefixed with "g:".
3407 if (!valid_varname(varname, !vim9script 3412 if (!valid_varname(varname, !vim9script
3408 || STRNCMP(name, "g:", 2) == 0)) 3413 || STRNCMP(name, "g:", 2) == 0))
3409 goto failed; 3414 goto failed;
3410 3415
3411 di = alloc(sizeof(dictitem_T) + STRLEN(varname)); 3416 di = alloc(sizeof(dictitem_T) + STRLEN(varname));
3412 if (di == NULL) 3417 if (di == NULL)
3413 goto failed; 3418 goto failed;
3423 3428
3424 // A Vim9 script-local variable is also added to sn_all_vars and 3429 // A Vim9 script-local variable is also added to sn_all_vars and
3425 // sn_var_vals. It may set "type" from "tv". 3430 // sn_var_vals. It may set "type" from "tv".
3426 if (var_in_vim9script) 3431 if (var_in_vim9script)
3427 update_vim9_script_var(TRUE, di, flags, tv, &type, 3432 update_vim9_script_var(TRUE, di, flags, tv, &type,
3428 (flags & ASSIGN_NO_MEMBER_TYPE) == 0); 3433 (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
3429 } 3434 }
3430 3435
3431 dest_tv = &di->di_tv; 3436 dest_tv = &di->di_tv;
3432 } 3437 }
3433 3438