# HG changeset patch # User Christian Brabandt # Date 1498417203 -7200 # Node ID 439835c4b7aa1f2799ea7732d4ca45b40306fef3 # Parent c742c05d083cbffa5b99381bdbc0bf2f350de7e2 patch 8.0.0676: crash when closing quickfix window in autocmd commit https://github.com/vim/vim/commit/182a17b1e80b92826204d967808df0d30eb2ef27 Author: Bram Moolenaar Date: Sun Jun 25 20:57:18 2017 +0200 patch 8.0.0676: crash when closing quickfix window in autocmd Problem: Crash when closing the quickfix window in a FileType autocommand that triggers when the quickfix window is opened. Solution: Save the new value before triggering the OptionSet autocommand. Add the "starting" flag to test_override() to make the text work. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 8.0. Last change: 2017 Jun 24 +*eval.txt* For Vim version 8.0. Last change: 2017 Jun 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -7942,8 +7942,19 @@ test_override({name}, {val}) *test_ov name effect when {val} is non-zero ~ redraw disable the redrawing() function char_avail disable the char_avail() function + starting reset the "starting" variable, see below ALL clear all overrides ({val} is not used) + "starting" is to be used when a test should behave like + startup was done. Since the tests are run by sourcing a + script the "starting" variable is non-zero. This is usually a + good thing (tests run faster), but sometimes changes behavior + in a way that the test doesn't work properly. + When using: > + call test_override('starting', 1) +< The value of "starting" is saved. It is restored by: > + call test_override('starting', 0) + test_settime({expr}) *test_settime()* Set the time Vim uses internally. Currently only used for timestamps in the history, as they are used in viminfo, and diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -12398,6 +12398,7 @@ f_test_override(typval_T *argvars, typva { char_u *name = (char_u *)""; int val; + static int save_starting = -1; if (argvars[0].v_type != VAR_STRING || (argvars[1].v_type) != VAR_NUMBER) @@ -12411,10 +12412,29 @@ f_test_override(typval_T *argvars, typva disable_redraw_for_testing = val; else if (STRCMP(name, (char_u *)"char_avail") == 0) disable_char_avail_for_testing = val; + else if (STRCMP(name, (char_u *)"starting") == 0) + { + if (val) + { + if (save_starting < 0) + save_starting = starting; + starting = 0; + } + else + { + starting = save_starting; + save_starting = -1; + } + } else if (STRCMP(name, (char_u *)"ALL") == 0) { disable_char_avail_for_testing = FALSE; disable_redraw_for_testing = FALSE; + if (save_starting >= 0) + { + starting = save_starting; + save_starting = -1; + } } else EMSG2(_(e_invarg2), name); diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -4294,6 +4294,32 @@ set_title_defaults(void) } #endif +#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) + static void +trigger_optionsset_string( + int opt_idx, + int opt_flags, + char_u *oldval, + char_u *newval) +{ + if (oldval != NULL && newval != NULL) + { + char_u buf_type[7]; + + sprintf((char *)buf_type, "%s", + (opt_flags & OPT_LOCAL) ? "local" : "global"); + set_vim_var_string(VV_OPTION_OLD, oldval, -1); + set_vim_var_string(VV_OPTION_NEW, newval, -1); + set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); + apply_autocmds(EVENT_OPTIONSET, + (char_u *)options[opt_idx].fullname, NULL, FALSE, NULL); + reset_v_option_vars(); + } + vim_free(oldval); + vim_free(newval); +} +#endif + /* * Parse 'arg' for option settings. * @@ -4763,6 +4789,7 @@ do_set( char_u *origval = NULL; #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) char_u *saved_origval = NULL; + char_u *saved_newval = NULL; #endif unsigned newlen; int comma; @@ -5114,14 +5141,21 @@ do_set( # ifdef FEAT_CRYPT && options[opt_idx].indir != PV_KEY # endif - && origval != NULL) + && origval != NULL && newval != NULL) + { /* origval may be freed by * did_set_string_option(), make a copy. */ saved_origval = vim_strsave(origval); + /* newval (and varp) may become invalid if the + * buffer is closed by autocommands. */ + saved_newval = vim_strsave(newval); + } #endif /* Handle side effects, and set the global value for - * ":set" on local options. */ + * ":set" on local options. Note: when setting 'syntax' + * or 'filetype' autocommands may be triggered that can + * cause havoc. */ errmsg = did_set_string_option(opt_idx, (char_u **)varp, new_value_alloced, oldval, errbuf, opt_flags); @@ -5130,28 +5164,14 @@ do_set( { #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) vim_free(saved_origval); + vim_free(saved_newval); #endif goto skip; } #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) - if (saved_origval != NULL) - { - char_u buf_type[7]; - - sprintf((char *)buf_type, "%s", - (opt_flags & OPT_LOCAL) ? "local" : "global"); - set_vim_var_string(VV_OPTION_NEW, - *(char_u **)varp, -1); - set_vim_var_string(VV_OPTION_OLD, saved_origval, -1); - set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); - apply_autocmds(EVENT_OPTIONSET, - (char_u *)options[opt_idx].fullname, - NULL, FALSE, NULL); - reset_v_option_vars(); - vim_free(saved_origval); - } -#endif - + trigger_optionsset_string(opt_idx, opt_flags, + saved_origval, saved_newval); +#endif } else /* key code option */ { @@ -5922,6 +5942,7 @@ set_string_option( char_u *oldval; #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) char_u *saved_oldval = NULL; + char_u *saved_newval = NULL; #endif char_u *r = NULL; @@ -5945,26 +5966,19 @@ set_string_option( && options[opt_idx].indir != PV_KEY # endif ) + { saved_oldval = vim_strsave(oldval); + saved_newval = vim_strsave(s); + } #endif if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, opt_flags)) == NULL) did_set_option(opt_idx, opt_flags, TRUE); +#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) /* call autocommand after handling side effects */ -#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) - if (saved_oldval != NULL) - { - char_u buf_type[7]; - sprintf((char *)buf_type, "%s", - (opt_flags & OPT_LOCAL) ? "local" : "global"); - set_vim_var_string(VV_OPTION_NEW, *varp, -1); - set_vim_var_string(VV_OPTION_OLD, saved_oldval, -1); - set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); - apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname, NULL, FALSE, NULL); - reset_v_option_vars(); - vim_free(saved_oldval); - } + trigger_optionsset_string(opt_idx, opt_flags, + saved_oldval, saved_newval); #endif } return r; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 676, +/**/ 675, /**/ 674,