|
|
13ea7f |
diff -up vim82/src/ex_cmds.c.cve0413 vim82/src/ex_cmds.c
|
|
|
13ea7f |
--- vim82/src/ex_cmds.c.cve0413 2022-02-10 08:09:27.644493218 +0100
|
|
|
13ea7f |
+++ vim82/src/ex_cmds.c 2022-02-10 08:09:27.653493168 +0100
|
|
|
13ea7f |
@@ -3627,6 +3627,7 @@ ex_substitute(exarg_T *eap)
|
|
|
13ea7f |
int save_do_all; // remember user specified 'g' flag
|
|
|
13ea7f |
int save_do_ask; // remember user specified 'c' flag
|
|
|
13ea7f |
char_u *pat = NULL, *sub = NULL; // init for GCC
|
|
|
13ea7f |
+ char_u *sub_copy = NULL;
|
|
|
13ea7f |
int delimiter;
|
|
|
13ea7f |
int sublen;
|
|
|
13ea7f |
int got_quit = FALSE;
|
|
|
13ea7f |
@@ -3928,11 +3929,20 @@ ex_substitute(exarg_T *eap)
|
|
|
13ea7f |
sub_firstline = NULL;
|
|
|
13ea7f |
|
|
|
13ea7f |
/*
|
|
|
13ea7f |
- * ~ in the substitute pattern is replaced with the old pattern.
|
|
|
13ea7f |
- * We do it here once to avoid it to be replaced over and over again.
|
|
|
13ea7f |
- * But don't do it when it starts with "\=", then it's an expression.
|
|
|
13ea7f |
+ * If the substitute pattern starts with "\=" then it's an expression.
|
|
|
13ea7f |
+ * Make a copy, a recursive function may free it.
|
|
|
13ea7f |
+ * Otherwise, '~' in the substitute pattern is replaced with the old
|
|
|
13ea7f |
+ * pattern. We do it here once to avoid it to be replaced over and over
|
|
|
13ea7f |
+ * again.
|
|
|
13ea7f |
*/
|
|
|
13ea7f |
- if (!(sub[0] == '\\' && sub[1] == '='))
|
|
|
13ea7f |
+ if (sub[0] == '\\' && sub[1] == '=')
|
|
|
13ea7f |
+ {
|
|
|
13ea7f |
+ sub = vim_strsave(sub);
|
|
|
13ea7f |
+ if (sub == NULL)
|
|
|
13ea7f |
+ return;
|
|
|
13ea7f |
+ sub_copy = sub;
|
|
|
13ea7f |
+ }
|
|
|
13ea7f |
+ else
|
|
|
13ea7f |
sub = regtilde(sub, magic_isset());
|
|
|
13ea7f |
|
|
|
13ea7f |
/*
|
|
|
13ea7f |
@@ -4737,6 +4747,7 @@ outofmem:
|
|
|
13ea7f |
#endif
|
|
|
13ea7f |
|
|
|
13ea7f |
vim_regfree(regmatch.regprog);
|
|
|
13ea7f |
+ vim_free(sub_copy);
|
|
|
13ea7f |
|
|
|
13ea7f |
// Restore the flag values, they can be used for ":&&".
|
|
|
13ea7f |
subflags.do_all = save_do_all;
|
|
|
13ea7f |
diff -up vim82/src/testdir/test_substitute.vim.cve0413 vim82/src/testdir/test_substitute.vim
|
|
|
13ea7f |
--- vim82/src/testdir/test_substitute.vim.cve0413 2022-02-10 08:09:27.654493162 +0100
|
|
|
13ea7f |
+++ vim82/src/testdir/test_substitute.vim 2022-02-10 08:10:14.392230843 +0100
|
|
|
13ea7f |
@@ -926,4 +926,21 @@ func Test_substitute_multiline_submatch(
|
|
|
13ea7f |
close!
|
|
|
13ea7f |
endfunc
|
|
|
13ea7f |
|
|
|
13ea7f |
+" This was using "old_sub" after it was freed.
|
|
|
13ea7f |
+func Test_using_old_sub()
|
|
|
13ea7f |
+ set compatible maxfuncdepth=10
|
|
|
13ea7f |
+ new
|
|
|
13ea7f |
+ call setline(1, 'some text.')
|
|
|
13ea7f |
+ func Repl()
|
|
|
13ea7f |
+ ~
|
|
|
13ea7f |
+ s/
|
|
|
13ea7f |
+ endfunc
|
|
|
13ea7f |
+ silent! s/\%')/\=Repl()
|
|
|
13ea7f |
+
|
|
|
13ea7f |
+ delfunc Repl
|
|
|
13ea7f |
+ bwipe!
|
|
|
13ea7f |
+ set nocompatible
|
|
|
13ea7f |
+endfunc
|
|
|
13ea7f |
+
|
|
|
13ea7f |
+
|
|
|
13ea7f |
" vim: shiftwidth=2 sts=2 expandtab
|