Mercurial > vim
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 |