From 48ce135e6d45e6c10ed0c0fc4cb8433bf647672a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 14 Jun 2022 15:43:18 +0100 Subject: 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. --- src/ex_docmd.c | 27 ++++++++++++++++----------- src/version.c | 2 ++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index a6f5952c1..23867d8ac 100644 --- 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; } diff --git a/src/version.c b/src/version.c index f00f8057a..f21efe157 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 5092, /**/ 5091, /**/ -- cgit v1.2.1