]> granicus.if.org Git - vim/commitdiff
patch 8.0.0676: crash when closing quickfix window in autocmd v8.0.0676
authorBram Moolenaar <Bram@vim.org>
Sun, 25 Jun 2017 18:57:18 +0000 (20:57 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 25 Jun 2017 18:57:18 +0000 (20:57 +0200)
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.

runtime/doc/eval.txt
src/evalfunc.c
src/option.c
src/version.c

index 6c5155022f5f251c3d95395dba4a4072536544c6..c17512a8a402d65da5690f21a1e760143c8b0a3f 100644 (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
@@ -7942,8 +7942,19 @@ test_override({name}, {val})                             *test_override()*
                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
index ac232a3b3e1be1c8879e86240d3e864cb85b61dc..2d796f7e13726ae7b0659a0a93cab55769cf92dc 100644 (file)
@@ -12398,6 +12398,7 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
 {
     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, typval_T *rettv UNUSED)
            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);
index 154c28b5a8f996347566df2f8536001e2603ba19..8097a7f99bc370de98ed1d445bc05ed75bc3b192 100644 (file)
@@ -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);
-                       }
+                       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);
 
-       /* 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);
-       }
+       /* call autocommand after handling side effects */
+       trigger_optionsset_string(opt_idx, opt_flags,
+                                                  saved_oldval, saved_newval);
 #endif
     }
     return r;
index 8dbd2a7d353a0f8efd3a605bb4165720da68d3ec..ab3185e0b2fd6197c018c68d87adf3717afac31a 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    676,
 /**/
     675,
 /**/