diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-09-23 12:44:25 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-09-23 12:44:25 +0100 |
commit | f8addf1ca1d8c7801f6dded2341b7084d2b93e5e (patch) | |
tree | 419cf1a57caa244652d839ea1b2331329c3f0c77 /src/eval.c | |
parent | f5f4e85f0189790ab81c0005b703604721db13d4 (diff) |
patch 9.0.0554: using freed memory when command follows lambdav9.0.0554
Problem: Using freed memory when command follows lambda.
Solution: Don't free what is still in use. (closes #11201)
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/eval.c b/src/eval.c index 77f0d7fb3c..bdf03896a4 100644 --- a/src/eval.c +++ b/src/eval.c @@ -382,23 +382,34 @@ clear_evalarg(evalarg_T *evalarg, exarg_T *eap) { if (evalarg != NULL) { - if (evalarg->eval_tofree != NULL) + garray_T *etga = &evalarg->eval_tofree_ga; + + if (evalarg->eval_tofree != NULL || evalarg->eval_using_cmdline) { if (eap != NULL) { // We may need to keep the original command line, e.g. for - // ":let" it has the variable names. But we may also need the - // new one, "nextcmd" points into it. Keep both. + // ":let" it has the variable names. But we may also need + // the new one, "nextcmd" points into it. Keep both. vim_free(eap->cmdline_tofree); eap->cmdline_tofree = *eap->cmdlinep; - *eap->cmdlinep = evalarg->eval_tofree; + + if (evalarg->eval_using_cmdline && etga->ga_len > 0) + { + // "nextcmd" points into the last line in eval_tofree_ga, + // need to keep it around. + --etga->ga_len; + *eap->cmdlinep = ((char_u **)etga->ga_data)[etga->ga_len]; + } + else + *eap->cmdlinep = evalarg->eval_tofree; } else vim_free(evalarg->eval_tofree); evalarg->eval_tofree = NULL; } - ga_clear_strings(&evalarg->eval_tofree_ga); + ga_clear_strings(etga); VIM_CLEAR(evalarg->eval_tofree_lambda); } } |