Mercurial > vim
changeset 24190:5f3a2d31c48d v8.2.2636
patch 8.2.2636: memory leak when compiling inline function
Commit: https://github.com/vim/vim/commit/67da21a14726b106b49744f9773eba132fedd5f2
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Mar 21 22:12:34 2021 +0100
patch 8.2.2636: memory leak when compiling inline function
Problem: Memory leak when compiling inline function.
Solution: Free the prefetched line.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 21 Mar 2021 22:15:03 +0100 |
parents | 60c5b6cb5130 |
children | a464593df512 |
files | src/eval.c src/globals.h src/structs.h src/userfunc.c src/version.c src/vim9compile.c |
diffstat | 6 files changed, 26 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -2179,8 +2179,8 @@ clear_evalarg(evalarg_T *evalarg, exarg_ evalarg->eval_tofree = NULL; } - vim_free(evalarg->eval_tofree_lambda); - evalarg->eval_tofree_lambda = NULL; + VIM_CLEAR(evalarg->eval_tofree_cmdline); + VIM_CLEAR(evalarg->eval_tofree_lambda); } }
--- a/src/globals.h +++ b/src/globals.h @@ -1898,7 +1898,8 @@ EXTERN listitem_T range_list_item; // Passed to an eval() function to enable evaluation. EXTERN evalarg_T EVALARG_EVALUATE # ifdef DO_INIT - = {EVAL_EVALUATE, 0, NULL, NULL, NULL, {0, 0, 0, 0, NULL}, NULL, NULL} + = {EVAL_EVALUATE, 0, NULL, NULL, NULL, {0, 0, 0, 0, NULL}, + NULL, NULL, NULL} # endif ; #endif
--- a/src/structs.h +++ b/src/structs.h @@ -1882,6 +1882,9 @@ typedef struct { // pointer to the last line obtained with getsourceline() char_u *eval_tofree; + // pointer to the last line of an inline function + char_u *eval_tofree_cmdline; + // pointer to the lines concatenated for a lambda. char_u *eval_tofree_lambda; } evalarg_T;
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -970,17 +970,18 @@ lambda_function_body( ga_init2(&newlines, (int)sizeof(char_u *), 10); if (get_function_body(&eap, &newlines, NULL, &line_to_free) == FAIL) + { + vim_free(cmdline); goto erret; + } if (cmdline != NULL) { // Something comes after the "}". *arg = eap.nextcmd; - if (evalarg->eval_cctx == NULL) - { - // Need to keep the line and free it/ later. - vim_free(evalarg->eval_tofree_lambda); - evalarg->eval_tofree_lambda = cmdline; - } + + // "arg" points into cmdline, need to keep the line and free it later. + vim_free(evalarg->eval_tofree_cmdline); + evalarg->eval_tofree_cmdline = cmdline; } else *arg = (char_u *)"";
--- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2636, +/**/ 2635, /**/ 2634,
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3202,6 +3202,16 @@ compile_lambda(char_u **arg, cctx_T *cct // Compile the function into instructions. compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx); + // evalarg.eval_tofree_cmdline may have a copy of the last line and "*arg" + // points into it. Point to the original line to avoid a dangling pointer. + if (evalarg.eval_tofree_cmdline != NULL) + { + size_t off = *arg - evalarg.eval_tofree_cmdline; + + *arg = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum] + + off; + } + clear_evalarg(&evalarg, NULL); if (ufunc->uf_def_status == UF_COMPILED)