Mercurial > vim
changeset 11587:439835c4b7aa v8.0.0676
patch 8.0.0676: crash when closing quickfix window in autocmd
commit https://github.com/vim/vim/commit/182a17b1e80b92826204d967808df0d30eb2ef27
Author: Bram Moolenaar <Bram@vim.org>
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.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 25 Jun 2017 21:00:03 +0200 |
parents | c742c05d083c |
children | 9ea6a69996fe |
files | runtime/doc/eval.txt src/evalfunc.c src/option.c src/version.c |
diffstat | 4 files changed, 81 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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);
--- 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;