Patch 8.2.4253
Problem: Using freed memory when substitute uses a recursive function call.
Solution: Make a copy of the substitute text.
Files: src/ex_cmds.c, src/testdir/test_substitute.vim
*** ../vim-8.2.4252/src/ex_cmds.c 2022-01-28 15:28:00.204927781 +0000
--- src/ex_cmds.c 2022-01-29 14:21:00.925635137 +0000
***************
*** 3687,3692 ****
--- 3687,3693 ----
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,3990 ****
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 (!(sub[0] == '\\' && sub[1] == '='))
sub = regtilde(sub, magic_isset());
/*
--- 3981,4000 ----
sub_firstline = 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);
! if (sub == NULL)
! return;
! sub_copy = sub;
! }
! else
sub = regtilde(sub, magic_isset());
/*
***************
*** 4790,4795 ****
--- 4800,4806 ----
#endif
vim_regfree(regmatch.regprog);
+ vim_free(sub_copy);
// Restore the flag values, they can be used for ":&&".
subflags.do_all = save_do_all;
*** ../vim-8.2.4252/src/testdir/test_substitute.vim 2021-08-14 20:11:47.500966948 +0100
--- src/testdir/test_substitute.vim 2022-01-29 14:03:44.536800703 +0000
***************
*** 980,983 ****
--- 980,1000 ----
bw!
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-8.2.4252/src/version.c 2022-01-29 13:06:19.340028690 +0000
--- src/version.c 2022-01-29 14:11:10.446280792 +0000
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 4253,
/**/
--
BODY: I'm not dead!
CART DRIVER: 'Ere. He says he's not dead.
LARGE MAN: Yes he is.
BODY: I'm not!
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///