patch 8.2.5023: substitute overwrites allocated buffer

Problem:    Substitute overwrites allocated buffer.
Solution:   Disallow undo when in a substitute command.
diff --git a/src/normal.c b/src/normal.c
index bc3e29e..53c50dc 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -184,6 +184,22 @@
 }
 
 /*
+ * If currently editing a cmdline or text is locked: beep and give an error
+ * message, return TRUE.
+ */
+    static int
+check_text_locked(oparg_T *oap)
+{
+    if (text_locked())
+    {
+	clearopbeep(oap);
+	text_locked_msg();
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
  * Handle the count before a normal command and set cap->count0.
  */
     static int
@@ -802,14 +818,9 @@
 	goto normal_end;
     }
 
-    if (text_locked() && (nv_cmds[idx].cmd_flags & NV_NCW))
-    {
-	// This command is not allowed while editing a cmdline: beep.
-	clearopbeep(oap);
-	text_locked_msg();
-	goto normal_end;
-    }
-    if ((nv_cmds[idx].cmd_flags & NV_NCW) && curbuf_locked())
+    if ((nv_cmds[idx].cmd_flags & NV_NCW)
+				&& (check_text_locked(oap) || curbuf_locked()))
+	// this command is not allowed now
 	goto normal_end;
 
     // In Visual/Select mode, a few keys are handled in a special way.
@@ -4049,12 +4060,8 @@
     char_u	*ptr;
     linenr_T	lnum = -1;
 
-    if (text_locked())
-    {
-	clearopbeep(cap->oap);
-	text_locked_msg();
+    if (check_text_locked(cap->oap))
 	return;
-    }
     if (curbuf_locked())
     {
 	clearop(cap->oap);
@@ -6182,14 +6189,7 @@
 
     // "gQ": improved Ex mode
     case 'Q':
-	if (text_locked())
-	{
-	    clearopbeep(cap->oap);
-	    text_locked_msg();
-	    break;
-	}
-
-	if (!checkclearopq(oap))
+	if (!check_text_locked(cap->oap) && !checkclearopq(oap))
 	    do_exmode(TRUE);
 	break;