vim-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.
37f47958b8

'compatible' doesn't seem needed for the test.
This commit is contained in:
zeertzjq 2022-04-04 11:15:31 +08:00
parent db13f105d6
commit 6486983117
2 changed files with 30 additions and 4 deletions

View File

@ -3627,13 +3627,20 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
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.
assert(sub != NULL);
bool sub_needs_free = false;
if (!(sub[0] == '\\' && sub[1] == '=')) {
char_u *sub_copy = NULL;
// 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] == '=') {
sub = vim_strsave(sub);
sub_copy = sub;
} else {
char_u *source = sub;
sub = regtilde(sub, p_magic);
// When previewing, the new pattern allocated by regtilde() needs to be freed
@ -4412,6 +4419,7 @@ skip:
}
vim_regfree(regmatch.regprog);
xfree(sub_copy);
// Restore the flag values, they can be used for ":&&".
subflags.do_all = save_do_all;

View File

@ -819,4 +819,22 @@ func Test_substitute_skipped_range()
bwipe!
endfunc
" This was using "old_sub" after it was freed.
func Test_using_old_sub()
" set compatible maxfuncdepth=10
set 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