diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-29 14:21:51 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-29 14:21:51 +0000 |
commit | 37f47958b8a2a44abc60614271d9537e7f14e51a (patch) | |
tree | 93ecab84af2e5191851cef159b559f2267ef233e /src/ex_cmds.c | |
parent | 4dc0dd869972ddafc7d9ee5ea765645b818a6dc9 (diff) |
patch 8.2.4253: using freed memory when substitute with function callv8.2.4253
Problem: Using freed memory when substitute uses a recursive function call.
Solution: Make a copy of the substitute text.
Diffstat (limited to 'src/ex_cmds.c')
-rw-r--r-- | src/ex_cmds.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 099d9cfeed..9d99571f72 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3687,6 +3687,7 @@ ex_substitute(exarg_T *eap) int save_do_all; // remember user specified 'g' flag int save_do_ask; // remember user specified 'c' flag char_u *pat = NULL, *sub = NULL; // init for GCC + char_u *sub_copy = NULL; int delimiter; int sublen; int got_quit = FALSE; @@ -3980,11 +3981,20 @@ ex_substitute(exarg_T *eap) sub_firstline = NULL; /* - * ~ in the substitute pattern is replaced with the old pattern. - * We do it here once to avoid it to be replaced over and over again. - * But don't do it when it starts with "\=", then it's an expression. + * If the substitute pattern starts with "\=" then it's an expression. + * Make a copy, a recursive function may free it. + * Otherwise, '~' in the substitute pattern is replaced with the old + * pattern. We do it here once to avoid it to be replaced over and over + * again. */ - if (!(sub[0] == '\\' && sub[1] == '=')) + if (sub[0] == '\\' && sub[1] == '=') + { + sub = vim_strsave(sub); + if (sub == NULL) + return; + sub_copy = sub; + } + else sub = regtilde(sub, magic_isset()); /* @@ -4790,6 +4800,7 @@ outofmem: #endif vim_regfree(regmatch.regprog); + vim_free(sub_copy); // Restore the flag values, they can be used for ":&&". subflags.do_all = save_do_all; |