1
0
forked from aniani/vim

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.
This commit is contained in:
Bram Moolenaar
2017-06-25 20:57:18 +02:00
parent 774e5a9673
commit 182a17b1e8
4 changed files with 80 additions and 33 deletions

View File

@@ -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 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -7942,8 +7942,19 @@ test_override({name}, {val}) *test_override()*
name effect when {val} is non-zero ~ name effect when {val} is non-zero ~
redraw disable the redrawing() function redraw disable the redrawing() function
char_avail disable the char_avail() function char_avail disable the char_avail() function
starting reset the "starting" variable, see below
ALL clear all overrides ({val} is not used) 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()* test_settime({expr}) *test_settime()*
Set the time Vim uses internally. Currently only used for Set the time Vim uses internally. Currently only used for
timestamps in the history, as they are used in viminfo, and timestamps in the history, as they are used in viminfo, and

View File

@@ -12398,6 +12398,7 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
{ {
char_u *name = (char_u *)""; char_u *name = (char_u *)"";
int val; int val;
static int save_starting = -1;
if (argvars[0].v_type != VAR_STRING if (argvars[0].v_type != VAR_STRING
|| (argvars[1].v_type) != VAR_NUMBER) || (argvars[1].v_type) != VAR_NUMBER)
@@ -12411,10 +12412,29 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
disable_redraw_for_testing = val; disable_redraw_for_testing = val;
else if (STRCMP(name, (char_u *)"char_avail") == 0) else if (STRCMP(name, (char_u *)"char_avail") == 0)
disable_char_avail_for_testing = val; 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) else if (STRCMP(name, (char_u *)"ALL") == 0)
{ {
disable_char_avail_for_testing = FALSE; disable_char_avail_for_testing = FALSE;
disable_redraw_for_testing = FALSE; disable_redraw_for_testing = FALSE;
if (save_starting >= 0)
{
starting = save_starting;
save_starting = -1;
}
} }
else else
EMSG2(_(e_invarg2), name); EMSG2(_(e_invarg2), name);

View File

@@ -4294,6 +4294,32 @@ set_title_defaults(void)
} }
#endif #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. * Parse 'arg' for option settings.
* *
@@ -4763,6 +4789,7 @@ do_set(
char_u *origval = NULL; char_u *origval = NULL;
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
char_u *saved_origval = NULL; char_u *saved_origval = NULL;
char_u *saved_newval = NULL;
#endif #endif
unsigned newlen; unsigned newlen;
int comma; int comma;
@@ -5114,14 +5141,21 @@ do_set(
# ifdef FEAT_CRYPT # ifdef FEAT_CRYPT
&& options[opt_idx].indir != PV_KEY && options[opt_idx].indir != PV_KEY
# endif # endif
&& origval != NULL) && origval != NULL && newval != NULL)
{
/* origval may be freed by /* origval may be freed by
* did_set_string_option(), make a copy. */ * did_set_string_option(), make a copy. */
saved_origval = vim_strsave(origval); saved_origval = vim_strsave(origval);
/* newval (and varp) may become invalid if the
* buffer is closed by autocommands. */
saved_newval = vim_strsave(newval);
}
#endif #endif
/* Handle side effects, and set the global value for /* 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, errmsg = did_set_string_option(opt_idx, (char_u **)varp,
new_value_alloced, oldval, errbuf, opt_flags); new_value_alloced, oldval, errbuf, opt_flags);
@@ -5130,28 +5164,14 @@ do_set(
{ {
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
vim_free(saved_origval); vim_free(saved_origval);
vim_free(saved_newval);
#endif #endif
goto skip; goto skip;
} }
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (saved_origval != NULL) trigger_optionsset_string(opt_idx, opt_flags,
{ saved_origval, saved_newval);
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 #endif
} }
else /* key code option */ else /* key code option */
{ {
@@ -5922,6 +5942,7 @@ set_string_option(
char_u *oldval; char_u *oldval;
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
char_u *saved_oldval = NULL; char_u *saved_oldval = NULL;
char_u *saved_newval = NULL;
#endif #endif
char_u *r = NULL; char_u *r = NULL;
@@ -5945,26 +5966,19 @@ set_string_option(
&& options[opt_idx].indir != PV_KEY && options[opt_idx].indir != PV_KEY
# endif # endif
) )
{
saved_oldval = vim_strsave(oldval); saved_oldval = vim_strsave(oldval);
saved_newval = vim_strsave(s);
}
#endif #endif
if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
opt_flags)) == NULL) opt_flags)) == NULL)
did_set_option(opt_idx, opt_flags, TRUE); did_set_option(opt_idx, opt_flags, TRUE);
/* call autocommand after handling side effects */
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (saved_oldval != NULL) /* call autocommand after handling side effects */
{ trigger_optionsset_string(opt_idx, opt_flags,
char_u buf_type[7]; saved_oldval, saved_newval);
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);
}
#endif #endif
} }
return r; return r;

View File

@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
676,
/**/ /**/
675, 675,
/**/ /**/