changeset 29144:dee6b7c32f2c v8.2.5092

patch 8.2.5092: using "'<,'>" in Ex mode may compare unrelated pointers Commit: https://github.com/vim/vim/commit/48ce135e6d45e6c10ed0c0fc4cb8433bf647672a Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jun 14 15:43:18 2022 +0100 patch 8.2.5092: using "'<,'>" in Ex mode may compare unrelated pointers Problem: Using "'<,'>" in Ex mode may compare unrelated pointers. Solution: Set eap->cmd to "+" only later.
author Bram Moolenaar <Bram@vim.org>
date Tue, 14 Jun 2022 16:45:03 +0200
parents 424899ef8669
children 878ee13a9d6c
files src/ex_docmd.c src/version.c
diffstat 2 files changed, 18 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -2786,8 +2786,7 @@ parse_command_modifiers(
 {
     char_u  *orig_cmd = eap->cmd;
     char_u  *cmd_start = NULL;
-    int	    did_plus_cmd = FALSE;
-    char_u  *p;
+    int	    use_plus_cmd = FALSE;
     int	    starts_with_colon = FALSE;
     int	    vim9script = in_vim9script();
     int	    has_visual_range = FALSE;
@@ -2799,7 +2798,9 @@ parse_command_modifiers(
     {
 	// The automatically inserted Visual area range is skipped, so that
 	// typing ":cmdmod cmd" in Visual mode works without having to move the
-	// range to after the modififiers.
+	// range to after the modififiers. The command will be
+	// "'<,'>cmdmod cmd", parse "cmdmod cmd" and then put back "'<,'>"
+	// before "cmd" below.
 	eap->cmd += 5;
 	cmd_start = eap->cmd;
 	has_visual_range = TRUE;
@@ -2808,6 +2809,8 @@ parse_command_modifiers(
     // Repeat until no more command modifiers are found.
     for (;;)
     {
+	char_u  *p;
+
 	while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':')
 	{
 	    if (*eap->cmd == ':')
@@ -2815,16 +2818,16 @@ parse_command_modifiers(
 	    ++eap->cmd;
 	}
 
-	// in ex mode, an empty line works like :+
+	// in ex mode, an empty command (after modifiers) works like :+
 	if (*eap->cmd == NUL && exmode_active
 		   && (getline_equal(eap->getline, eap->cookie, getexmodeline)
 		       || getline_equal(eap->getline, eap->cookie, getexline))
 			&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
 	{
-	    eap->cmd = (char_u *)"+";
-	    did_plus_cmd = TRUE;
+	    use_plus_cmd = TRUE;
 	    if (!skip_only)
 		ex_pressedreturn = TRUE;
+	    break;  // no modifiers following
 	}
 
 	// ignore comment and empty lines
@@ -3108,12 +3111,12 @@ parse_command_modifiers(
 	    // Since the modifiers have been parsed put the colon on top of the
 	    // space: "'<,'>mod cmd" -> "mod:'<,'>cmd
 	    // Put eap->cmd after the colon.
-	    if (did_plus_cmd)
+	    if (use_plus_cmd)
 	    {
 		size_t len = STRLEN(cmd_start);
 
-		// Special case: empty command may have been changed to "+":
-		//  "'<,'>mod" -> "mod'<,'>+
+		// Special case: empty command uses "+":
+		//  "'<,'>mods" -> "mods'<,'>+
 		mch_memmove(orig_cmd, cmd_start, len);
 		STRCPY(orig_cmd + len, "'<,'>+");
 	    }
@@ -3126,12 +3129,14 @@ parse_command_modifiers(
 	}
 	else
 	    // No modifiers, move the pointer back.
-	    // Special case: empty command may have been changed to "+".
-	    if (did_plus_cmd)
+	    // Special case: change empty command to "+".
+	    if (use_plus_cmd)
 		eap->cmd = (char_u *)"'<,'>+";
 	    else
 		eap->cmd = orig_cmd;
     }
+    else if (use_plus_cmd)
+	eap->cmd = (char_u *)"+";
 
     return OK;
 }
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    5092,
+/**/
     5091,
 /**/
     5090,