vim-patch:8.2.4763: using invalid pointer with "V:" in Ex mode

Problem:    Using invalid pointer with "V:" in Ex mode.
Solution:   Correctly handle the command being changed to "+".

f50808ed13

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
Jan Edmund Lazo
2025-12-13 00:33:59 -05:00
parent 0fa678c02f
commit cd543d618d
2 changed files with 34 additions and 5 deletions

View File

@@ -2511,7 +2511,9 @@ static char *ex_range_without_command(exarg_T *eap)
/// @return FAIL when the command is not to be executed. /// @return FAIL when the command is not to be executed.
int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod, bool skip_only) int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod, bool skip_only)
{ {
char *orig_cmd = eap->cmd;
char *cmd_start = NULL; char *cmd_start = NULL;
bool did_plus_cmd = false;
bool has_visual_range = false; bool has_visual_range = false;
CLEAR_POINTER(cmod); CLEAR_POINTER(cmod);
@@ -2537,6 +2539,7 @@ int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod,
&& getline_equal(eap->ea_getline, eap->cookie, getexline) && getline_equal(eap->ea_getline, eap->cookie, getexline)
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
eap->cmd = exmode_plus; eap->cmd = exmode_plus;
did_plus_cmd = true;
if (!skip_only) { if (!skip_only) {
ex_pressedreturn = true; ex_pressedreturn = true;
} }
@@ -2767,12 +2770,26 @@ int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod,
// Since the modifiers have been parsed put the colon on top of the // Since the modifiers have been parsed put the colon on top of the
// space: "'<,'>mod cmd" -> "mod:'<,'>cmd // space: "'<,'>mod cmd" -> "mod:'<,'>cmd
// Put eap->cmd after the colon. // Put eap->cmd after the colon.
memmove(cmd_start - 5, cmd_start, (size_t)(eap->cmd - cmd_start)); if (did_plus_cmd) {
eap->cmd -= 5; size_t len = strlen(cmd_start);
memmove(eap->cmd - 1, ":'<,'>", 6);
// Special case: empty command may have been changed to "+":
// "'<,'>mod" -> "mod'<,'>+
memmove(orig_cmd, cmd_start, len);
strcpy(orig_cmd + len, "'<,'>+");
} else {
memmove(cmd_start - 5, cmd_start, (size_t)(eap->cmd - cmd_start));
eap->cmd -= 5;
memmove(eap->cmd - 1, ":'<,'>", 6);
}
} else { } else {
// no modifiers, move the pointer back // No modifiers, move the pointer back.
eap->cmd -= 5; // Special case: empty command may have been changed to "+".
if (did_plus_cmd) {
eap->cmd = "'<,'>+";
} else {
eap->cmd = orig_cmd;
}
} }
} }

View File

@@ -287,6 +287,18 @@ func Test_ex_mode_large_indent()
bwipe! bwipe!
endfunc endfunc
" This was accessing illegal memory when using "+" for eap->cmd.
func Test_empty_command_visual_mode()
let lines =<< trim END
r<sfile>
0norm0V:
:qall!
END
call writefile(lines, 'Xexmodescript')
call assert_equal(1, RunVim([], [], '-u NONE -e -s -S Xexmodescript'))
call delete('Xexmodescript')
endfunc
" Testing implicit print command " Testing implicit print command
func Test_implicit_print() func Test_implicit_print()