comparison src/userfunc.c @ 24448:faac16c365b6 v8.2.2764

patch 8.2.2764: memory leak when default function argument is allocated Commit: https://github.com/vim/vim/commit/b47bed2f7ada4dfae78f76f27473b83507e40315 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Apr 14 17:06:43 2021 +0200 patch 8.2.2764: memory leak when default function argument is allocated Problem: Memory leak when default function argument is allocated. Solution: Free the expression result.
author Bram Moolenaar <Bram@vim.org>
date Wed, 14 Apr 2021 17:15:05 +0200
parents ccdd5e9a3763
children 5dea95170907
comparison
equal deleted inserted replaced
24447:bbe84a902d14 24448:faac16c365b6
2186 int i; 2186 int i;
2187 int ai; 2187 int ai;
2188 int islambda = FALSE; 2188 int islambda = FALSE;
2189 char_u numbuf[NUMBUFLEN]; 2189 char_u numbuf[NUMBUFLEN];
2190 char_u *name; 2190 char_u *name;
2191 typval_T *tv_to_free[MAX_FUNC_ARGS];
2192 int tv_to_free_len = 0;
2191 #ifdef FEAT_PROFILE 2193 #ifdef FEAT_PROFILE
2192 profinfo_T profile_info; 2194 profinfo_T profile_info;
2193 #endif 2195 #endif
2194 ESTACK_CHECK_DECLARATION 2196 ESTACK_CHECK_DECLARATION
2195 2197
2331 && (i >= argcount || (argvars[i].v_type == VAR_SPECIAL 2333 && (i >= argcount || (argvars[i].v_type == VAR_SPECIAL
2332 && argvars[i].vval.v_number == VVAL_NONE)); 2334 && argvars[i].vval.v_number == VVAL_NONE));
2333 if (isdefault) 2335 if (isdefault)
2334 { 2336 {
2335 char_u *default_expr = NULL; 2337 char_u *default_expr = NULL;
2338
2336 def_rettv.v_type = VAR_NUMBER; 2339 def_rettv.v_type = VAR_NUMBER;
2337 def_rettv.vval.v_number = -1; 2340 def_rettv.vval.v_number = -1;
2338 2341
2339 default_expr = ((char_u **)(fp->uf_def_args.ga_data)) 2342 default_expr = ((char_u **)(fp->uf_def_args.ga_data))
2340 [ai + fp->uf_def_args.ga_len]; 2343 [ai + fp->uf_def_args.ga_len];
2371 2374
2372 // Note: the values are copied directly to avoid alloc/free. 2375 // Note: the values are copied directly to avoid alloc/free.
2373 // "argvars" must have VAR_FIXED for v_lock. 2376 // "argvars" must have VAR_FIXED for v_lock.
2374 v->di_tv = isdefault ? def_rettv : argvars[i]; 2377 v->di_tv = isdefault ? def_rettv : argvars[i];
2375 v->di_tv.v_lock = VAR_FIXED; 2378 v->di_tv.v_lock = VAR_FIXED;
2379
2380 if (isdefault)
2381 // Need to free this later, no matter where it's stored.
2382 tv_to_free[tv_to_free_len++] = &v->di_tv;
2376 2383
2377 if (addlocal) 2384 if (addlocal)
2378 { 2385 {
2379 // Named arguments should be accessed without the "a:" prefix in 2386 // Named arguments should be accessed without the "a:" prefix in
2380 // lambda expressions. Add to the l: dict. 2387 // lambda expressions. Add to the l: dict.
2561 --no_wait_return; 2568 --no_wait_return;
2562 } 2569 }
2563 2570
2564 did_emsg |= save_did_emsg; 2571 did_emsg |= save_did_emsg;
2565 funcdepth_decrement(); 2572 funcdepth_decrement();
2573 for (i = 0; i < tv_to_free_len; ++i)
2574 clear_tv(tv_to_free[i]);
2566 cleanup_function_call(fc); 2575 cleanup_function_call(fc);
2567 } 2576 }
2568 2577
2569 /* 2578 /*
2570 * Check the argument count for user function "fp". 2579 * Check the argument count for user function "fp".