You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.2 KiB
69 lines
2.2 KiB
diff -up vim82/src/ex_cmds.c.cve0413 vim82/src/ex_cmds.c |
|
--- vim82/src/ex_cmds.c.cve0413 2022-02-10 08:09:27.644493218 +0100 |
|
+++ vim82/src/ex_cmds.c 2022-02-10 08:09:27.653493168 +0100 |
|
@@ -3627,6 +3627,7 @@ ex_substitute(exarg_T *eap) |
|
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; |
|
@@ -3928,11 +3929,20 @@ ex_substitute(exarg_T *eap) |
|
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 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] == '=')) |
|
+ if (sub[0] == '\\' && sub[1] == '=') |
|
+ { |
|
+ sub = vim_strsave(sub); |
|
+ if (sub == NULL) |
|
+ return; |
|
+ sub_copy = sub; |
|
+ } |
|
+ else |
|
sub = regtilde(sub, magic_isset()); |
|
|
|
/* |
|
@@ -4737,6 +4747,7 @@ outofmem: |
|
#endif |
|
|
|
vim_regfree(regmatch.regprog); |
|
+ vim_free(sub_copy); |
|
|
|
// Restore the flag values, they can be used for ":&&". |
|
subflags.do_all = save_do_all; |
|
diff -up vim82/src/testdir/test_substitute.vim.cve0413 vim82/src/testdir/test_substitute.vim |
|
--- vim82/src/testdir/test_substitute.vim.cve0413 2022-02-10 08:09:27.654493162 +0100 |
|
+++ vim82/src/testdir/test_substitute.vim 2022-02-10 08:10:14.392230843 +0100 |
|
@@ -926,4 +926,21 @@ func Test_substitute_multiline_submatch( |
|
close! |
|
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
|
|
|