comparison src/option.c @ 11587:439835c4b7aa v8.0.0676

patch 8.0.0676: crash when closing quickfix window in autocmd commit https://github.com/vim/vim/commit/182a17b1e80b92826204d967808df0d30eb2ef27 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jun 25 20:57:18 2017 +0200 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.
author Christian Brabandt <cb@256bit.org>
date Sun, 25 Jun 2017 21:00:03 +0200
parents c83dd5fa40d8
children b8299e742f41
comparison
equal deleted inserted replaced
11586:c742c05d083c 11587:439835c4b7aa
4289 #endif 4289 #endif
4290 val = mch_can_restore_icon(); 4290 val = mch_can_restore_icon();
4291 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val; 4291 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
4292 p_icon = val; 4292 p_icon = val;
4293 } 4293 }
4294 }
4295 #endif
4296
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);
4294 } 4320 }
4295 #endif 4321 #endif
4296 4322
4297 /* 4323 /*
4298 * Parse 'arg' for option settings. 4324 * Parse 'arg' for option settings.
4761 char_u *oldval = NULL; /* previous value if *varp */ 4787 char_u *oldval = NULL; /* previous value if *varp */
4762 char_u *newval; 4788 char_u *newval;
4763 char_u *origval = NULL; 4789 char_u *origval = NULL;
4764 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 4790 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
4765 char_u *saved_origval = NULL; 4791 char_u *saved_origval = NULL;
4792 char_u *saved_newval = NULL;
4766 #endif 4793 #endif
4767 unsigned newlen; 4794 unsigned newlen;
4768 int comma; 4795 int comma;
4769 int bs; 4796 int bs;
4770 int new_value_alloced; /* new string option 4797 int new_value_alloced; /* new string option
5112 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 5139 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
5113 if (!starting 5140 if (!starting
5114 # ifdef FEAT_CRYPT 5141 # ifdef FEAT_CRYPT
5115 && options[opt_idx].indir != PV_KEY 5142 && options[opt_idx].indir != PV_KEY
5116 # endif 5143 # endif
5117 && origval != NULL) 5144 && origval != NULL && newval != NULL)
5145 {
5118 /* origval may be freed by 5146 /* origval may be freed by
5119 * did_set_string_option(), make a copy. */ 5147 * did_set_string_option(), make a copy. */
5120 saved_origval = vim_strsave(origval); 5148 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 }
5121 #endif 5153 #endif
5122 5154
5123 /* Handle side effects, and set the global value for 5155 /* 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. */
5125 errmsg = did_set_string_option(opt_idx, (char_u **)varp, 5159 errmsg = did_set_string_option(opt_idx, (char_u **)varp,
5126 new_value_alloced, oldval, errbuf, opt_flags); 5160 new_value_alloced, oldval, errbuf, opt_flags);
5127 5161
5128 /* If error detected, print the error message. */ 5162 /* If error detected, print the error message. */
5129 if (errmsg != NULL) 5163 if (errmsg != NULL)
5130 { 5164 {
5131 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 5165 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
5132 vim_free(saved_origval); 5166 vim_free(saved_origval);
5167 vim_free(saved_newval);
5133 #endif 5168 #endif
5134 goto skip; 5169 goto skip;
5135 } 5170 }
5136 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 5171 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
5137 if (saved_origval != NULL) 5172 trigger_optionsset_string(opt_idx, opt_flags,
5138 { 5173 saved_origval, saved_newval);
5139 char_u buf_type[7]; 5174 #endif
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 }
5153 #endif
5154
5155 } 5175 }
5156 else /* key code option */ 5176 else /* key code option */
5157 { 5177 {
5158 char_u *p; 5178 char_u *p;
5159 5179
5920 char_u *s; 5940 char_u *s;
5921 char_u **varp; 5941 char_u **varp;
5922 char_u *oldval; 5942 char_u *oldval;
5923 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 5943 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
5924 char_u *saved_oldval = NULL; 5944 char_u *saved_oldval = NULL;
5945 char_u *saved_newval = NULL;
5925 #endif 5946 #endif
5926 char_u *r = NULL; 5947 char_u *r = NULL;
5927 5948
5928 if (options[opt_idx].var == NULL) /* don't set hidden option */ 5949 if (options[opt_idx].var == NULL) /* don't set hidden option */
5929 return NULL; 5950 return NULL;
5943 if (!starting 5964 if (!starting
5944 # ifdef FEAT_CRYPT 5965 # ifdef FEAT_CRYPT
5945 && options[opt_idx].indir != PV_KEY 5966 && options[opt_idx].indir != PV_KEY
5946 # endif 5967 # endif
5947 ) 5968 )
5969 {
5948 saved_oldval = vim_strsave(oldval); 5970 saved_oldval = vim_strsave(oldval);
5971 saved_newval = vim_strsave(s);
5972 }
5949 #endif 5973 #endif
5950 if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, 5974 if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
5951 opt_flags)) == NULL) 5975 opt_flags)) == NULL)
5952 did_set_option(opt_idx, opt_flags, TRUE); 5976 did_set_option(opt_idx, opt_flags, TRUE);
5953 5977
5978 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
5954 /* call autocommand after handling side effects */ 5979 /* call autocommand after handling side effects */
5955 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) 5980 trigger_optionsset_string(opt_idx, opt_flags,
5956 if (saved_oldval != NULL) 5981 saved_oldval, saved_newval);
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 }
5968 #endif 5982 #endif
5969 } 5983 }
5970 return r; 5984 return r;
5971 } 5985 }
5972 5986