From 6a680548ec3e81e9d228cb8ac9e4380368068387 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 30 Sep 2018 02:37:31 -0400 Subject: [PATCH] vim-patch:8.1.0066: nasty autocommand causes using freed memory Problem: Nasty autocommand causes using freed memory. (Dominique Pelle) Solution: Do not force executing autocommands if the value of 'syntax' or 'filetype' did not change. https://github.com/vim/vim/commit/c3ffc9b8d3015dc5280b297b4e3deb4f34944bd4 --- src/nvim/option.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/nvim/option.c b/src/nvim/option.c index b4ee89d128..1440180e4b 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2434,7 +2434,7 @@ did_set_string_option ( int did_chartab = FALSE; char_u **gvarp; bool free_oldval = (options[opt_idx].flags & P_ALLOCED); - int ft_changed = false; + bool value_changed = false; /* Get the global option to compare with, otherwise we would have to check * two values for all local options. */ @@ -3155,11 +3155,13 @@ did_set_string_option ( if (!valid_filetype(*varp)) { errmsg = e_invarg; } else { - ft_changed = STRCMP(oldval, *varp) != 0; + value_changed = STRCMP(oldval, *varp) != 0; } } else if (gvarp == &p_syn) { if (!valid_filetype(*varp)) { errmsg = e_invarg; + } else { + value_changed = STRCMP(oldval, *varp) != 0; } } else if (varp == &curwin->w_p_winhl) { if (!parse_winhl_opt(curwin)) { @@ -3235,14 +3237,20 @@ did_set_string_option ( */ /* When 'syntax' is set, load the syntax of that name */ if (varp == &(curbuf->b_p_syn)) { + // Only pass true for "force" when the value changed, to avoid + // endless recurrence. apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, - curbuf->b_fname, TRUE, curbuf); + curbuf->b_fname, value_changed, curbuf); } else if (varp == &(curbuf->b_p_ft)) { // 'filetype' is set, trigger the FileType autocommand - if (!(opt_flags & OPT_MODELINE) || ft_changed) { + // Skip this when called from a modeline and the filetype was + // already set to this value. + // Only pass true for "force" when the value changed, to avoid + // endless recurrence. + if (!(opt_flags & OPT_MODELINE) || value_changed) { did_filetype = true; apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, - curbuf->b_fname, true, curbuf); + curbuf->b_fname, value_changed, curbuf); // Just in case the old "curbuf" is now invalid if (varp != &(curbuf->b_p_ft)) { varp = NULL;