Skip to content

Commit 182a17b

Browse files
committed
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.
1 parent 774e5a9 commit 182a17b

4 files changed

Lines changed: 80 additions & 33 deletions

File tree

runtime/doc/eval.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 8.0. Last change: 2017 Jun 24
1+
*eval.txt* For Vim version 8.0. Last change: 2017 Jun 25
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -7942,8 +7942,19 @@ test_override({name}, {val}) *test_override()*
79427942
name effect when {val} is non-zero ~
79437943
redraw disable the redrawing() function
79447944
char_avail disable the char_avail() function
7945+
starting reset the "starting" variable, see below
79457946
ALL clear all overrides ({val} is not used)
79467947

7948+
"starting" is to be used when a test should behave like
7949+
startup was done. Since the tests are run by sourcing a
7950+
script the "starting" variable is non-zero. This is usually a
7951+
good thing (tests run faster), but sometimes changes behavior
7952+
in a way that the test doesn't work properly.
7953+
When using: >
7954+
call test_override('starting', 1)
7955+
< The value of "starting" is saved. It is restored by: >
7956+
call test_override('starting', 0)
7957+
79477958
test_settime({expr}) *test_settime()*
79487959
Set the time Vim uses internally. Currently only used for
79497960
timestamps in the history, as they are used in viminfo, and

src/evalfunc.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12398,6 +12398,7 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
1239812398
{
1239912399
char_u *name = (char_u *)"";
1240012400
int val;
12401+
static int save_starting = -1;
1240112402

1240212403
if (argvars[0].v_type != VAR_STRING
1240312404
|| (argvars[1].v_type) != VAR_NUMBER)
@@ -12411,10 +12412,29 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
1241112412
disable_redraw_for_testing = val;
1241212413
else if (STRCMP(name, (char_u *)"char_avail") == 0)
1241312414
disable_char_avail_for_testing = val;
12415+
else if (STRCMP(name, (char_u *)"starting") == 0)
12416+
{
12417+
if (val)
12418+
{
12419+
if (save_starting < 0)
12420+
save_starting = starting;
12421+
starting = 0;
12422+
}
12423+
else
12424+
{
12425+
starting = save_starting;
12426+
save_starting = -1;
12427+
}
12428+
}
1241412429
else if (STRCMP(name, (char_u *)"ALL") == 0)
1241512430
{
1241612431
disable_char_avail_for_testing = FALSE;
1241712432
disable_redraw_for_testing = FALSE;
12433+
if (save_starting >= 0)
12434+
{
12435+
starting = save_starting;
12436+
save_starting = -1;
12437+
}
1241812438
}
1241912439
else
1242012440
EMSG2(_(e_invarg2), name);

src/option.c

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4294,6 +4294,32 @@ set_title_defaults(void)
42944294
}
42954295
#endif
42964296

4297+
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
4298+
static void
4299+
trigger_optionsset_string(
4300+
int opt_idx,
4301+
int opt_flags,
4302+
char_u *oldval,
4303+
char_u *newval)
4304+
{
4305+
if (oldval != NULL && newval != NULL)
4306+
{
4307+
char_u buf_type[7];
4308+
4309+
sprintf((char *)buf_type, "%s",
4310+
(opt_flags & OPT_LOCAL) ? "local" : "global");
4311+
set_vim_var_string(VV_OPTION_OLD, oldval, -1);
4312+
set_vim_var_string(VV_OPTION_NEW, newval, -1);
4313+
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
4314+
apply_autocmds(EVENT_OPTIONSET,
4315+
(char_u *)options[opt_idx].fullname, NULL, FALSE, NULL);
4316+
reset_v_option_vars();
4317+
}
4318+
vim_free(oldval);
4319+
vim_free(newval);
4320+
}
4321+
#endif
4322+
42974323
/*
42984324
* Parse 'arg' for option settings.
42994325
*
@@ -4763,6 +4789,7 @@ do_set(
47634789
char_u *origval = NULL;
47644790
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
47654791
char_u *saved_origval = NULL;
4792+
char_u *saved_newval = NULL;
47664793
#endif
47674794
unsigned newlen;
47684795
int comma;
@@ -5114,14 +5141,21 @@ do_set(
51145141
# ifdef FEAT_CRYPT
51155142
&& options[opt_idx].indir != PV_KEY
51165143
# endif
5117-
&& origval != NULL)
5144+
&& origval != NULL && newval != NULL)
5145+
{
51185146
/* origval may be freed by
51195147
* did_set_string_option(), make a copy. */
51205148
saved_origval = vim_strsave(origval);
5149+
/* newval (and varp) may become invalid if the
5150+
* buffer is closed by autocommands. */
5151+
saved_newval = vim_strsave(newval);
5152+
}
51215153
#endif
51225154

51235155
/* Handle side effects, and set the global value for
5124-
* ":set" on local options. */
5156+
* ":set" on local options. Note: when setting 'syntax'
5157+
* or 'filetype' autocommands may be triggered that can
5158+
* cause havoc. */
51255159
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
51265160
new_value_alloced, oldval, errbuf, opt_flags);
51275161

@@ -5130,28 +5164,14 @@ do_set(
51305164
{
51315165
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
51325166
vim_free(saved_origval);
5167+
vim_free(saved_newval);
51335168
#endif
51345169
goto skip;
51355170
}
51365171
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
5137-
if (saved_origval != NULL)
5138-
{
5139-
char_u buf_type[7];
5140-
5141-
sprintf((char *)buf_type, "%s",
5142-
(opt_flags & OPT_LOCAL) ? "local" : "global");
5143-
set_vim_var_string(VV_OPTION_NEW,
5144-
*(char_u **)varp, -1);
5145-
set_vim_var_string(VV_OPTION_OLD, saved_origval, -1);
5146-
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
5147-
apply_autocmds(EVENT_OPTIONSET,
5148-
(char_u *)options[opt_idx].fullname,
5149-
NULL, FALSE, NULL);
5150-
reset_v_option_vars();
5151-
vim_free(saved_origval);
5152-
}
5172+
trigger_optionsset_string(opt_idx, opt_flags,
5173+
saved_origval, saved_newval);
51535174
#endif
5154-
51555175
}
51565176
else /* key code option */
51575177
{
@@ -5922,6 +5942,7 @@ set_string_option(
59225942
char_u *oldval;
59235943
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
59245944
char_u *saved_oldval = NULL;
5945+
char_u *saved_newval = NULL;
59255946
#endif
59265947
char_u *r = NULL;
59275948

@@ -5945,26 +5966,19 @@ set_string_option(
59455966
&& options[opt_idx].indir != PV_KEY
59465967
# endif
59475968
)
5969+
{
59485970
saved_oldval = vim_strsave(oldval);
5971+
saved_newval = vim_strsave(s);
5972+
}
59495973
#endif
59505974
if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
59515975
opt_flags)) == NULL)
59525976
did_set_option(opt_idx, opt_flags, TRUE);
59535977

5954-
/* call autocommand after handling side effects */
59555978
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
5956-
if (saved_oldval != NULL)
5957-
{
5958-
char_u buf_type[7];
5959-
sprintf((char *)buf_type, "%s",
5960-
(opt_flags & OPT_LOCAL) ? "local" : "global");
5961-
set_vim_var_string(VV_OPTION_NEW, *varp, -1);
5962-
set_vim_var_string(VV_OPTION_OLD, saved_oldval, -1);
5963-
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
5964-
apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname, NULL, FALSE, NULL);
5965-
reset_v_option_vars();
5966-
vim_free(saved_oldval);
5967-
}
5979+
/* call autocommand after handling side effects */
5980+
trigger_optionsset_string(opt_idx, opt_flags,
5981+
saved_oldval, saved_newval);
59685982
#endif
59695983
}
59705984
return r;

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
676,
767769
/**/
768770
675,
769771
/**/

0 commit comments

Comments
 (0)