]> granicus.if.org Git - vim/commitdiff
patch 8.2.4977: memory access error when substitute expression changes window v8.2.4977
authorBram Moolenaar <Bram@vim.org>
Wed, 18 May 2022 12:11:57 +0000 (13:11 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 18 May 2022 12:11:57 +0000 (13:11 +0100)
Problem:    Memory access error when substitute expression changes window.
Solution:   Disallow changing window in substitute expression.

src/ex_cmds.c
src/testdir/test_substitute.vim
src/version.c

index 7e730becb48feef68071008ff29672e742a3cb91..210e21fe7a5b9fb7c340829cc5e7c7ac91b182b9 100644 (file)
@@ -4412,12 +4412,17 @@ ex_substitute(exarg_T *eap)
                // Save flags for recursion.  They can change for e.g.
                // :s/^/\=execute("s#^##gn")
                subflags_save = subflags;
+
+               // Disallow changing text or switching window in an expression.
+               ++textwinlock;
 #endif
                // get length of substitution part
                sublen = vim_regsub_multi(&regmatch,
                                    sub_firstlnum - regmatch.startpos[0].lnum,
                               sub, sub_firstline, FALSE, magic_isset(), TRUE);
 #ifdef FEAT_EVAL
+               --textwinlock;
+
                // If getting the substitute string caused an error, don't do
                // the replacement.
                // Don't keep flags set by a recursive call.
@@ -4518,9 +4523,15 @@ ex_substitute(exarg_T *eap)
                mch_memmove(new_end, sub_firstline + copycol, (size_t)copy_len);
                new_end += copy_len;
 
+#ifdef FEAT_EVAL
+               ++textwinlock;
+#endif
                (void)vim_regsub_multi(&regmatch,
                                    sub_firstlnum - regmatch.startpos[0].lnum,
                                      sub, new_end, TRUE, magic_isset(), TRUE);
+#ifdef FEAT_EVAL
+               --textwinlock;
+#endif
                sub_nsubs++;
                did_sub = TRUE;
 
index f3fd7ab1ce7779019df30cd93ac73dea0618c933..a1c324ed8d208bccec9cf7182a30a50ebf36285f 100644 (file)
@@ -1000,6 +1000,19 @@ func Test_using_old_sub()
   set nocompatible
 endfunc
 
+" This was switching windows in between computing the length and using it.
+func Test_sub_change_window()
+  silent! lfile
+  sil! norm o0000000000000000000000000000000000000000000000000000
+  func Repl()
+    lopen
+  endfunc
+  silent!  s/\%')/\=Repl()
+  bwipe!
+  bwipe!
+  delfunc Repl
+endfunc
+
 " Test for the 2-letter and 3-letter :substitute commands
 func Test_substitute_short_cmd()
   new
index 4c63ea0771ad01c0d7c481c37f9ea2c260f66d65..782642b5d5a1ce13c49729164c00512fccc2b827 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4977,
 /**/
     4976,
 /**/