Skip to content

Commit

Permalink
patch 8.0.0676: crash when closing quickfix window in autocmd
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
brammool committed Jun 25, 2017
1 parent 774e5a9 commit 182a17b
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 33 deletions.
13 changes: 12 additions & 1 deletion 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 VIM REFERENCE MANUAL by Bram Moolenaar
Expand Down Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions src/evalfunc.c
Expand Up @@ -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)
Expand All @@ -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);
Expand Down
78 changes: 46 additions & 32 deletions src/option.c
Expand Up @@ -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.
* *
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);


Expand All @@ -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 */
{ {
Expand Down Expand Up @@ -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;


Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -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,
/**/ /**/
Expand Down

0 comments on commit 182a17b

Please sign in to comment.