0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 8.2.4253: using freed memory when substitute with function call

Problem:    Using freed memory when substitute uses a recursive function call.
Solution:   Make a copy of the substitute text.
This commit is contained in:
Bram Moolenaar 2022-01-29 14:21:51 +00:00
parent 4dc0dd8699
commit 37f47958b8
3 changed files with 34 additions and 4 deletions

View File

@ -3687,6 +3687,7 @@ ex_substitute(exarg_T *eap)
int save_do_all; // remember user specified 'g' flag int save_do_all; // remember user specified 'g' flag
int save_do_ask; // remember user specified 'c' flag int save_do_ask; // remember user specified 'c' flag
char_u *pat = NULL, *sub = NULL; // init for GCC char_u *pat = NULL, *sub = NULL; // init for GCC
char_u *sub_copy = NULL;
int delimiter; int delimiter;
int sublen; int sublen;
int got_quit = FALSE; int got_quit = FALSE;
@ -3980,11 +3981,20 @@ ex_substitute(exarg_T *eap)
sub_firstline = NULL; sub_firstline = NULL;
/* /*
* ~ in the substitute pattern is replaced with the old pattern. * If the substitute pattern starts with "\=" then it's an expression.
* We do it here once to avoid it to be replaced over and over again. * Make a copy, a recursive function may free it.
* But don't do it when it starts with "\=", then it's an expression. * 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()); sub = regtilde(sub, magic_isset());
/* /*
@ -4790,6 +4800,7 @@ outofmem:
#endif #endif
vim_regfree(regmatch.regprog); vim_regfree(regmatch.regprog);
vim_free(sub_copy);
// Restore the flag values, they can be used for ":&&". // Restore the flag values, they can be used for ":&&".
subflags.do_all = save_do_all; subflags.do_all = save_do_all;

View File

@ -980,4 +980,21 @@ func Test_substitute_gdefault()
bw! bw!
endfunc endfunc
" This was using "old_sub" after it was freed.
func Test_using_old_sub()
set compatible maxfuncdepth=10
new
call setline(1, 'some text.')
func Repl()
~
s/
endfunc
silent! s/\%')/\=Repl()
delfunc Repl
bwipe!
set nocompatible
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4253,
/**/ /**/
4252, 4252,
/**/ /**/