Mercurial > vim
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". |