From: Christian Brabandt <cb@256bit.org>
Date: Tue, 5 Sep 2023 20:18:06 +0200
Subject: patch 9.0.1873: [security] heap-buffer-overflow in vim_regsub_both

Problem:  heap-buffer-overflow in vim_regsub_both
Solution: Disallow exchanging windows when textlock is active

Signed-off-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit f6d28fe2c95c678cc3202cc5dc825a3fcc709e93)
---
 src/ex_cmds.c                         |   3 +++
 src/testdir/crash/vim_regsub_both_poc | Bin 0 -> 244 bytes
 src/version.c                         |   2 ++
 src/window.c                          |   5 +++++
 4 files changed, 10 insertions(+)
 create mode 100644 src/testdir/crash/vim_regsub_both_poc

diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 62d7b9c..5f017f4 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4509,6 +4509,9 @@ ex_substitute(exarg_T *eap)
 		{
 		    nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1;
 		    skip_match = TRUE;
+		    // safety check
+		    if (nmatch < 0)
+			goto skip;
 		}
 
 		// Need room for:
diff --git a/src/testdir/crash/vim_regsub_both_poc b/src/testdir/crash/vim_regsub_both_poc
new file mode 100644
index 0000000..19a5711
--- /dev/null
+++ b/src/testdir/crash/vim_regsub_both_poc
@@ -0,0 +1,23 @@
+fu R()
+sil!norm0z=
+endf
+cal R()
+si
+cal R()
+sv ÿ n   
+se
+s/\%')/\=R()ú  
+siznorm
+'zR[sp
+qe sm:d
+l!n0
+sil!
+d
+l!no80
+sil!norm*soqmao\\Zÿÿÿ\\ 
+vim9s*\
+oa
+no0 z=Dx$enormyynore sm:vs0@vvvvvvvvvvse() Vdir(¼Xtest=csd{so88
+vs
+0scrÿh de
+so
diff --git a/src/version.c b/src/version.c
index 49a8d6b..8feb0c4 100644
--- a/src/version.c
+++ b/src/version.c
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1873,
 /**/
     1858,
 /**/
diff --git a/src/window.c b/src/window.c
index a804b4f..e6b1b2c 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1685,6 +1685,11 @@ win_exchange(long Prenum)
 	beep_flush();
 	return;
     }
+    if (text_or_buf_locked())
+    {
+	beep_flush();
+	return;
+    }
 
 #ifdef FEAT_GUI
     need_mouse_correct = TRUE;
