fix(substitute): don't crash with very large count (#39272)

(cherry picked from commit ac8459a09c)
This commit is contained in:
zeertzjq
2026-04-21 19:38:15 +08:00
committed by github-actions[bot]
parent 187a34d59b
commit ffb0ebb752
5 changed files with 10 additions and 8 deletions
+1
View File
@@ -18,6 +18,7 @@ local dup_allowed = {
E116 = 2,
E121 = 2,
E1502 = 4,
E1510 = 2,
E151 = 2,
E155 = 3,
E158 = 2,
+1
View File
@@ -210,6 +210,7 @@ EXTERN const char e_not_allowed_to_change_window_layout_in_this_autocmd[]
INIT(= N_("E1312: Not allowed to change the window layout in this autocmd"));
EXTERN const char e_val_too_large[] INIT(= N_("E1510: Value too large: %s"));
EXTERN const char e_val_too_large_len[] INIT(= N_("E1510: Value too large: %.*s"));
EXTERN const char e_undobang_cannot_redo_or_move_branch[]
INIT(= N_("E5767: Cannot use :undo! to redo or move to a different undo branch"));
+3 -4
View File
@@ -3678,15 +3678,14 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
// check for a trailing count
cmd = skipwhite(cmd);
if (ascii_isdigit(*cmd)) {
i = getdigits_int(&cmd, true, INT_MAX);
const char *const count_arg = cmd;
i = getdigits_int(&cmd, false, INT_MAX);
if (i <= 0 && !eap->skip && subflags.do_error) {
emsg(_(e_zerocount));
xfree(sub);
return 0;
} else if (i >= INT_MAX) {
char buf[20];
vim_snprintf(buf, sizeof(buf), "%d", i);
semsg(_(e_val_too_large), buf);
semsg(_(e_val_too_large_len), (int)(cmd - count_arg), count_arg);
xfree(sub);
return 0;
}
+1 -4
View File
@@ -1053,10 +1053,7 @@ static void format_overflow_error(const char *pstart)
p++;
}
size_t arglen = (size_t)(p - pstart);
char *argcopy = xstrnsave(pstart, arglen);
semsg(_(e_val_too_large), argcopy);
xfree(argcopy);
semsg(_(e_val_too_large_len), (int)(p - pstart), pstart);
}
enum { MAX_ALLOWED_STRING_WIDTH = 1048576, }; // 1MiB
+4
View File
@@ -41,6 +41,10 @@ describe('Ex cmds', function()
'Vim(menu):E329: No menu "9999999999999999999999999999999999999999"',
pcall_err(command, ':menu 9999999999999999999999999999999999999999')
)
eq(
'Vim(substitute):E1510: Value too large: 9999999999999999999999999999999999999999',
pcall_err(command, ':%s/./b/9999999999999999999999999999999999999999')
)
assert_alive()
end)