Mercurial > vim
changeset 18225:6c3a8312486d v8.1.2107
patch 8.1.2107: various memory leaks reported by asan
Commit: https://github.com/vim/vim/commit/8617348e2110c2c8387ea448a6258f1effa8d249
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Oct 1 17:02:16 2019 +0200
patch 8.1.2107: various memory leaks reported by asan
Problem: Various memory leaks reported by asan.
Solution: Free the memory. (Ozaki Kiichi, closes https://github.com/vim/vim/issues/5003)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 01 Oct 2019 17:15:04 +0200 |
parents | 96632a3c3d90 |
children | 78e84b457783 |
files | src/buffer.c src/change.c src/eval.c src/evalfunc.c src/option.c src/popupwin.c src/proto/change.pro src/scriptfile.c src/terminal.c src/testdir/test_method.vim src/version.c |
diffstat | 11 files changed, 46 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/buffer.c +++ b/src/buffer.c @@ -880,6 +880,7 @@ free_buffer(buf_T *buf) /* b:changedtick uses an item in buf_T, remove it now */ dictitem_remove(buf->b_vars, (dictitem_T *)&buf->b_ct_di); unref_var_dict(buf->b_vars); + remove_listeners(buf); #endif #ifdef FEAT_LUA lua_buffer_free(buf); @@ -908,6 +909,7 @@ free_buffer(buf_T *buf) #ifdef FEAT_JOB_CHANNEL vim_free(buf->b_prompt_text); free_callback(&buf->b_prompt_callback); + free_callback(&buf->b_prompt_interrupt); #endif buf_hashtab_remove(buf);
--- a/src/change.c +++ b/src/change.c @@ -300,7 +300,7 @@ f_listener_remove(typval_T *argvars, typ int id = tv_get_number(argvars); buf_T *buf; - for (buf = firstbuf; buf != NULL; buf = buf->b_next) + FOR_ALL_BUFFERS(buf) { prev = NULL; for (lnr = buf->b_listener; lnr != NULL; lnr = next) @@ -402,6 +402,24 @@ invoke_listeners(buf_T *buf) after_updating_screen(TRUE); recursive = FALSE; } + +/* + * Remove all listeners associated with "buf". + */ + void +remove_listeners(buf_T *buf) +{ + listener_T *lnr; + listener_T *next; + + for (lnr = buf->b_listener; lnr != NULL; lnr = next) + { + next = lnr->lr_next; + free_callback(&lnr->lr_callback); + vim_free(lnr); + } + buf->b_listener = NULL; +} #endif /*
--- a/src/eval.c +++ b/src/eval.c @@ -2914,9 +2914,17 @@ eval_lambda( semsg(_(e_missingparen), "lambda"); } clear_tv(rettv); - return FAIL; + ret = FAIL; } - return call_func_rettv(arg, rettv, evaluate, NULL, &base); + else + ret = call_func_rettv(arg, rettv, evaluate, NULL, &base); + + // Clear the funcref afterwards, so that deleting it while + // evaluating the arguments is possible (see test55). + if (evaluate) + clear_tv(&base); + + return ret; } /*
--- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2213,8 +2213,7 @@ f_expand(typval_T *argvars, typval_T *re { if (rettv_list_alloc(rettv) != FAIL && result != NULL) list_append_string(rettv->vval.v_list, result, -1); - else - vim_free(result); + vim_free(result); } else rettv->vval.v_string = result;
--- a/src/option.c +++ b/src/option.c @@ -686,7 +686,7 @@ set_local_options_default(win_T *wp, int && (do_buffer || (p->indir & PV_BUF) == 0) && !(options[i].flags & P_NODEFAULT) && !optval_default(p, varp, FALSE)) - set_option_default(i, OPT_LOCAL, FALSE); + set_option_default(i, OPT_FREE|OPT_LOCAL, FALSE); } unblock_autocmds();
--- a/src/popupwin.c +++ b/src/popupwin.c @@ -3365,6 +3365,7 @@ update_popups(void (*win_update)(win_T * trunc_string(wp->w_popup_title, title, total_width - 2, len); screen_puts(title, wp->w_winrow, wp->w_wincol + 1, wp->w_popup_border[0] > 0 ? border_attr[0] : popup_attr); + vim_free(title); } // Compute scrollbar thumb position and size.
--- a/src/proto/change.pro +++ b/src/proto/change.pro @@ -7,6 +7,7 @@ void f_listener_flush(typval_T *argvars, void f_listener_remove(typval_T *argvars, typval_T *rettv); void may_invoke_listeners(buf_T *buf, linenr_T lnum, linenr_T lnume, int added); void invoke_listeners(buf_T *buf); +void remove_listeners(buf_T *buf); void changed_bytes(linenr_T lnum, colnr_T col); void appended_lines(linenr_T lnum, long count); void appended_lines_mark(linenr_T lnum, long count);
--- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -1358,7 +1358,10 @@ free_scriptnames(void) int i; for (i = script_items.ga_len; i > 0; --i) + { vim_free(SCRIPT_ITEM(i).sn_name); + ga_clear(&SCRIPT_ITEM(i).sn_prl_ga); + } ga_clear(&script_items); }
--- a/src/terminal.c +++ b/src/terminal.c @@ -4602,6 +4602,7 @@ read_dump_file(FILE *fd, VTermPos *curso } ga_clear(&ga_text); + ga_clear(&ga_cell); vim_free(prev_char); return max_cells; @@ -4733,7 +4734,7 @@ term_load_dump(typval_T *argvars, typval buf = curbuf; while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) ml_delete((linenr_T)1, FALSE); - ga_clear(&curbuf->b_term->tl_scrollback); + free_scrollback(curbuf->b_term); redraw_later(NOT_VALID); } }
--- a/src/testdir/test_method.vim +++ b/src/testdir/test_method.vim @@ -140,6 +140,10 @@ func Test_method_lambda() " todo: lambda accepts more arguments than it consumes " call assert_fails('eval "text"->{x -> x .. " extended"}("more")', 'E99:') + + let l = [1, 2, 3] + eval l->{x -> x}() + call assert_equal(1, test_refcount(l)) endfunc func Test_method_not_supported()