From e2bd8600b873d2cd1f9d667c28cba8b1dba18839 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 May 2022 13:11:57 +0100 Subject: [PATCH] patch 8.2.4977: memory access error when substitute expression changes window Problem: Memory access error when substitute expression changes window. Solution: Disallow changing window in substitute expression. --- src/ex_cmds.c | 11 +++++++++++ src/testdir/test_substitute.vim | 13 +++++++++++++ src/version.c | 2 ++ 3 files changed, 26 insertions(+) Backport: Use textlock instead of textwinlock. In this version, textwinlock wasn't yet split out from textlock and it'll get merged back later. --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -5576,12 +5576,17 @@ do_sub(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. */ + ++textlock; #endif /* get length of substitution part */ sublen = vim_regsub_multi(®match, sub_firstlnum - regmatch.startpos[0].lnum, sub, sub_firstline, FALSE, p_magic, TRUE); #ifdef FEAT_EVAL + --textlock; + /* Don't keep flags set by a recursive call. */ subflags = subflags_save; if (subflags.do_count) @@ -5670,9 +5675,15 @@ do_sub(exarg_T *eap) mch_memmove(new_end, sub_firstline + copycol, (size_t)copy_len); new_end += copy_len; +#ifdef FEAT_EVAL + ++textlock; +#endif (void)vim_regsub_multi(®match, sub_firstlnum - regmatch.startpos[0].lnum, sub, new_end, TRUE, p_magic, TRUE); +#ifdef FEAT_EVAL + --textlock; +#endif sub_nsubs++; did_sub = TRUE; --- a/src/testdir/test_substitute.vim +++ b/src/testdir/test_substitute.vim @@ -517,3 +517,16 @@ 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 + --- a/src/version.c +++ b/src/version.c @@ -796,6 +796,8 @@ static int included_patches[] = /**/ 5024, /**/ + 4977, +/**/ 4921, /**/ 4919,