From 4791fcd82565adcc60b86830e0bb6cd5b6eea0a6 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 23 Feb 2022 12:06:00 +0000 Subject: [PATCH] patch 8.2.4453: :helpgrep may free an option that was not allocated Problem: :helpgrep may free an option that was not allocated. (Yegappan Lakshmanan) Solution: Check if the value was allocated. --- src/option.c | 8 ++++++++ src/proto/option.pro | 1 + src/quickfix.c | 5 ++++- src/testdir/test_quickfix.vim | 27 +++++++++++++++++++++++++++ src/version.c | 2 ++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/option.c b/src/option.c index 91ea4138d..44a0520ad 100644 --- a/src/option.c +++ b/src/option.c @@ -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", "" or "" to a key number. * When "has_lt" is true there is a '<' before "*arg_arg". diff --git a/src/proto/option.pro b/src/proto/option.pro index 11f342c3f..b58e79afe 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -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); diff --git a/src/quickfix.c b/src/quickfix.c index 998ec6ec3..16790b030 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -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) diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 7d2373b82..ccfa340f6 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -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 diff --git a/src/version.c b/src/version.c index 1786ceb4d..57f32cbe4 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4453, /**/ 4452, /**/ -- 2.40.0