mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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:
parent
db13f105d6
commit
6486983117
@ -3627,13 +3627,20 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
|
|||||||
|
|
||||||
sub_firstline = NULL;
|
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);
|
assert(sub != NULL);
|
||||||
|
|
||||||
bool sub_needs_free = false;
|
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;
|
char_u *source = sub;
|
||||||
sub = regtilde(sub, p_magic);
|
sub = regtilde(sub, p_magic);
|
||||||
// When previewing, the new pattern allocated by regtilde() needs to be freed
|
// When previewing, the new pattern allocated by regtilde() needs to be freed
|
||||||
@ -4412,6 +4419,7 @@ skip:
|
|||||||
}
|
}
|
||||||
|
|
||||||
vim_regfree(regmatch.regprog);
|
vim_regfree(regmatch.regprog);
|
||||||
|
xfree(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;
|
||||||
|
@ -819,4 +819,22 @@ func Test_substitute_skipped_range()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
Loading…
Reference in New Issue
Block a user