]> granicus.if.org Git - vim/commitdiff
patch 8.2.4453: :helpgrep may free an option that was not allocated v8.2.4453
authorBram Moolenaar <Bram@vim.org>
Wed, 23 Feb 2022 12:06:00 +0000 (12:06 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 23 Feb 2022 12:06:00 +0000 (12:06 +0000)
Problem:    :helpgrep may free an option that was not allocated. (Yegappan
            Lakshmanan)
Solution:   Check if the value was allocated.

src/option.c
src/proto/option.pro
src/quickfix.c
src/testdir/test_quickfix.vim
src/version.c

index 91ea4138d39717df8a4ab42cc0fa9cc6095518ad..44a0520ad02aee1b00bdfc458afaf790ca27aa0d 100644 (file)
@@ -4479,6 +4479,14 @@ get_encoding_default(void)
     return (char_u *)NULL;
 }
 
+    int
+is_option_allocated(char *name)
+{
+    int idx = findoption((char_u *)name);
+
+    return idx >= 0 && (options[idx].flags & P_ALLOCED);
+}
+
 /*
  * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
  * When "has_lt" is true there is a '<' before "*arg_arg".
index 11f342c3f5a9316576e1797f6460c8727e91639b..b58e79afefbdbb4db10d3a8b05b57453ee830288 100644 (file)
@@ -41,6 +41,7 @@ char *set_option_value(char_u *name, long number, char_u *string, int opt_flags)
 char_u *get_term_code(char_u *tname);
 char_u *get_highlight_default(void);
 char_u *get_encoding_default(void);
+int is_option_allocated(char *name);
 int makeset(FILE *fd, int opt_flags, int local_only);
 int makefoldset(FILE *fd);
 void clear_termoptions(void);
index 998ec6ec3d1c0e16b36a52047d3aa9d178aa3713..16790b03040ec7bfd5330c18957e44df357c92f0 100644 (file)
@@ -8235,6 +8235,7 @@ ex_helpgrep(exarg_T *eap)
 {
     regmatch_T regmatch;
     char_u     *save_cpo;
+    int                save_cpo_allocated;
     qf_info_T  *qi = &ql_info;
     int                new_qi = FALSE;
     char_u     *au_name =  NULL;
@@ -8265,6 +8266,7 @@ ex_helpgrep(exarg_T *eap)
 
     // Make 'cpoptions' empty, the 'l' flag should not be used here.
     save_cpo = p_cpo;
+    save_cpo_allocated = is_option_allocated("cpo");
     p_cpo = empty_option;
 
     incr_quickfix_busy();
@@ -8302,7 +8304,8 @@ ex_helpgrep(exarg_T *eap)
        // changed and restored, need to restore in the complicated way.
        if (*p_cpo == NUL)
            set_option_value((char_u *)"cpo", 0L, save_cpo, 0);
-       free_string_option(save_cpo);
+       if (save_cpo_allocated)
+           free_string_option(save_cpo);
     }
 
     if (updated)
index 7d2373b828cf905688dc9dad3b7db17fb652909c..ccfa340f6cfd5f1a7abf403163fd4ce7ac4f748c 100644 (file)
@@ -745,6 +745,33 @@ def Test_helpgrep_vim9_restore_cpo()
   helpclose
 enddef
 
+func Test_helpgrep_restore_cpo_aucmd()
+  let save_cpo = &cpo
+  augroup QF_Test
+    au!
+    autocmd BufNew * set cpo=acd
+  augroup END
+
+  helpgrep quickfix
+  call assert_equal('acd', &cpo)
+  %bw!
+
+  set cpo&vim
+  augroup QF_Test
+    au!
+    autocmd BufReadPost * set cpo=
+  augroup END
+
+  helpgrep buffer
+  call assert_equal('', &cpo)
+
+  augroup QF_Test
+    au!
+  augroup END
+  %bw!
+  let &cpo = save_cpo
+endfunc
+
 def Test_vim9_cexpr()
   var text = 'somefile:95:error'
   cexpr text
index 1786ceb4ddc1f6331bf60dd490712ed66ae4a65e..57f32cbe4a990e6f2c2ce8e8595657d2cb88884d 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4453,
 /**/
     4452,
 /**/