summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-10-01 17:02:16 +0200
committerBram Moolenaar <Bram@vim.org>2019-10-01 17:02:16 +0200
commit8617348e2110c2c8387ea448a6258f1effa8d249 (patch)
treefab9e6b710dba337eb5439160f84e2fead1103cf
parentb4367b7fb65f6a88f76ef99f79342341af0b1017 (diff)
downloadvim-git-8.1.2107.tar.gz
patch 8.1.2107: various memory leaks reported by asanv8.1.2107
Problem: Various memory leaks reported by asan. Solution: Free the memory. (Ozaki Kiichi, closes #5003)
-rw-r--r--src/buffer.c2
-rw-r--r--src/change.c20
-rw-r--r--src/eval.c12
-rw-r--r--src/evalfunc.c3
-rw-r--r--src/option.c2
-rw-r--r--src/popupwin.c1
-rw-r--r--src/proto/change.pro1
-rw-r--r--src/scriptfile.c3
-rw-r--r--src/terminal.c3
-rw-r--r--src/testdir/test_method.vim4
-rw-r--r--src/version.c2
11 files changed, 46 insertions, 7 deletions
diff --git a/src/buffer.c b/src/buffer.c
index aa1770a94..86f6ffced 100644
--- 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);
diff --git a/src/change.c b/src/change.c
index 6b402f189..0eb00c283 100644
--- a/src/change.c
+++ b/src/change.c
@@ -300,7 +300,7 @@ f_listener_remove(typval_T *argvars, typval_T *rettv)
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
/*
diff --git a/src/eval.c b/src/eval.c
index 680ca1af7..954e07fb4 100644
--- 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;
}
/*
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 159b874bf..26d8691cc 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -2213,8 +2213,7 @@ f_expand(typval_T *argvars, typval_T *rettv)
{
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;
diff --git a/src/option.c b/src/option.c
index 51e75c330..3d408143e 100644
--- a/src/option.c
+++ b/src/option.c
@@ -686,7 +686,7 @@ set_local_options_default(win_T *wp, int do_buffer)
&& (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();
diff --git a/src/popupwin.c b/src/popupwin.c
index d4b3d7c33..a77d98b67 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -3365,6 +3365,7 @@ update_popups(void (*win_update)(win_T *wp))
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.
diff --git a/src/proto/change.pro b/src/proto/change.pro
index f6b3599eb..c31c442a5 100644
--- a/src/proto/change.pro
+++ b/src/proto/change.pro
@@ -7,6 +7,7 @@ void f_listener_flush(typval_T *argvars, typval_T *rettv);
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);
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 92db59c2d..611be04c8 100644
--- 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);
}
diff --git a/src/terminal.c b/src/terminal.c
index 4f2b8bb25..52487a3cf 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -4602,6 +4602,7 @@ read_dump_file(FILE *fd, VTermPos *cursor_pos)
}
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_T *rettv, int do_diff)
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);
}
}
diff --git a/src/testdir/test_method.vim b/src/testdir/test_method.vim
index 69adc30c0..b82dbb494 100644
--- 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()
diff --git a/src/version.c b/src/version.c
index cfd70c8ae..e2f0c9200 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2107,
+/**/
2106,
/**/
2105,