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:
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
78
src/option.c
78
src/option.c
@@ -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;
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user