Mercurial > vim
changeset 20657:a1e6d9353736 v8.2.0882
patch 8.2.0882: leaking memory when using reduce()
Commit: https://github.com/vim/vim/commit/48b1c21809553d3463b5ed6c2b3bc6d335663bb6
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jun 1 20:11:02 2020 +0200
patch 8.2.0882: leaking memory when using reduce()
Problem: Leaking memory when using reduce().
Solution: Free the intermediate value.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 01 Jun 2020 20:15:04 +0200 |
parents | d9b945841cba |
children | 0cbef5a89050 |
files | src/list.c src/version.c |
diffstat | 2 files changed, 22 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/list.c +++ b/src/list.c @@ -2311,7 +2311,7 @@ f_reverse(typval_T *argvars, typval_T *r void f_reduce(typval_T *argvars, typval_T *rettv) { - typval_T accum; + typval_T initial; char_u *func_name; partial_T *partial = NULL; funcexe_T funcexe; @@ -2343,6 +2343,7 @@ f_reduce(typval_T *argvars, typval_T *re { list_T *l = argvars[0].vval.v_list; listitem_T *li = NULL; + int r; CHECK_LIST_MATERIALIZE(l); if (argvars[2].v_type == VAR_UNKNOWN) @@ -2352,24 +2353,26 @@ f_reduce(typval_T *argvars, typval_T *re semsg(_(e_reduceempty), "List"); return; } - accum = l->lv_first->li_tv; + initial = l->lv_first->li_tv; li = l->lv_first->li_next; } else { - accum = argvars[2]; + initial = argvars[2]; if (l != NULL) li = l->lv_first; } - copy_tv(&accum, rettv); + copy_tv(&initial, rettv); for ( ; li != NULL; li = li->li_next) { - argv[0] = accum; + argv[0] = *rettv; argv[1] = li->li_tv; - if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) + rettv->v_type = VAR_UNKNOWN; + r = call_func(func_name, -1, rettv, 2, argv, &funcexe); + clear_tv(&argv[0]); + if (r == FAIL) return; - accum = *rettv; } } else @@ -2384,27 +2387,31 @@ f_reduce(typval_T *argvars, typval_T *re semsg(_(e_reduceempty), "Blob"); return; } - accum.v_type = VAR_NUMBER; - accum.vval.v_number = blob_get(b, 0); + initial.v_type = VAR_NUMBER; + initial.vval.v_number = blob_get(b, 0); i = 1; } + else if (argvars[2].v_type != VAR_NUMBER) + { + emsg(_(e_number_exp)); + return; + } else { - accum = argvars[2]; + initial = argvars[2]; i = 0; } - copy_tv(&accum, rettv); + copy_tv(&initial, rettv); if (b != NULL) { for ( ; i < b->bv_ga.ga_len; i++) { - argv[0] = accum; + argv[0] = *rettv; argv[1].v_type = VAR_NUMBER; argv[1].vval.v_number = blob_get(b, i); if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) return; - accum = *rettv; } } }