Merge pull request #26081 from zeertzjq/vim-9.0.2108

vim-patch:9.0.{1532,1534,1535,2108,2109,2110,2111}
This commit is contained in:
zeertzjq 2023-11-17 07:47:22 +08:00 committed by GitHub
commit 133a592d19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 78 additions and 26 deletions

View File

@ -619,9 +619,9 @@ original user.
current line only. When [count] is given, replace in current line only. When [count] is given, replace in
[count] lines, starting with the last line in [range]. [count] lines, starting with the last line in [range].
When [range] is omitted start in the current line. When [range] is omitted start in the current line.
*E939* *E939* *E1510*
[count] must be a positive number. Also see [count] must be a positive number (max 2147483647)
|cmdline-ranges|. Also see |cmdline-ranges|.
See |:s_flags| for [flags]. See |:s_flags| for [flags].
The delimiter doesn't need to be /, see The delimiter doesn't need to be /, see

View File

@ -339,6 +339,7 @@ terminals)
A positive number represents the absolute index of an entry A positive number represents the absolute index of an entry
as it is given in the first column of a :history listing. as it is given in the first column of a :history listing.
This number remains fixed even if other entries are deleted. This number remains fixed even if other entries are deleted.
(see |E1510|)
A negative number means the relative position of an entry, A negative number means the relative position of an entry,
counted from the newest entry (which has index -1) backwards. counted from the newest entry (which has index -1) backwards.

View File

@ -30,8 +30,6 @@
# include "cmdhist.c.generated.h" # include "cmdhist.c.generated.h"
#endif #endif
static const char e_val_too_large[] = N_("E1510: Value too large: %s");
static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL }; static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL };
static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; ///< lastused entry static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; ///< lastused entry
/// identifying (unique) number of newest history entry /// identifying (unique) number of newest history entry

View File

@ -3411,10 +3411,15 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
// check for a trailing count // check for a trailing count
cmd = skipwhite(cmd); cmd = skipwhite(cmd);
if (ascii_isdigit(*cmd)) { if (ascii_isdigit(*cmd)) {
i = getdigits_int(&cmd, true, 0); i = getdigits_int(&cmd, true, INT_MAX);
if (i <= 0 && !eap->skip && subflags.do_error) { if (i <= 0 && !eap->skip && subflags.do_error) {
emsg(_(e_zerocount)); emsg(_(e_zerocount));
return 0; return 0;
} else if (i >= INT_MAX) {
char buf[20];
vim_snprintf(buf, sizeof(buf), "%d", i);
semsg(_(e_val_too_large), buf);
return 0;
} }
eap->line1 = eap->line2; eap->line1 = eap->line2;
eap->line2 += (linenr_T)i - 1; eap->line2 += (linenr_T)i - 1;

View File

@ -3552,7 +3552,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
if (i == '-') { if (i == '-') {
lnum -= n; lnum -= n;
} else { } else {
if (n >= INT32_MAX - lnum) { if (lnum >= 0 && n >= INT32_MAX - lnum) {
*errormsg = _(e_line_number_out_of_range); *errormsg = _(e_line_number_out_of_range);
goto error; goto error;
} }

View File

@ -1026,11 +1026,13 @@ EXTERN const char e_highlight_group_name_too_long[] INIT(= N_("E1249: Highlight
EXTERN const char e_invalid_line_number_nr[] INIT(= N_("E966: Invalid line number: %ld")); EXTERN const char e_invalid_line_number_nr[] INIT(= N_("E966: Invalid line number: %ld"));
EXTERN char e_stray_closing_curly_str[] EXTERN const char e_stray_closing_curly_str[]
INIT(= N_("E1278: Stray '}' without a matching '{': %s")); INIT(= N_("E1278: Stray '}' without a matching '{': %s"));
EXTERN char e_missing_close_curly_str[] EXTERN const char e_missing_close_curly_str[]
INIT(= N_("E1279: Missing '}': %s")); INIT(= N_("E1279: Missing '}': %s"));
EXTERN const char e_val_too_large[] INIT(= N_("E1510: Value too large: %s"));
EXTERN const char e_undobang_cannot_redo_or_move_branch[] 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")); INIT(= N_("E5767: Cannot use :undo! to redo or move to a different undo branch"));

View File

@ -180,6 +180,9 @@ int get_number(int colon, int *mouse_used)
ui_cursor_goto(msg_row, msg_col); ui_cursor_goto(msg_row, msg_col);
int c = safe_vgetc(); int c = safe_vgetc();
if (ascii_isdigit(c)) { if (ascii_isdigit(c)) {
if (n > INT_MAX / 10) {
return 0;
}
n = n * 10 + c - '0'; n = n * 10 + c - '0';
msg_putchar(c); msg_putchar(c);
typed++; typed++;

View File

@ -2695,6 +2695,10 @@ static bool nv_z_get_count(cmdarg_T *cap, int *nchar_arg)
if (nchar == K_DEL || nchar == K_KDEL) { if (nchar == K_DEL || nchar == K_KDEL) {
n /= 10; n /= 10;
} else if (ascii_isdigit(nchar)) { } else if (ascii_isdigit(nchar)) {
if (n > INT_MAX / 10) {
clearopbeep(cap->oap);
break;
}
n = n * 10 + (nchar - '0'); n = n * 10 + (nchar - '0');
} else if (nchar == CAR) { } else if (nchar == CAR) {
win_setheight(n); win_setheight(n);

View File

@ -1642,41 +1642,46 @@ static void do_lower(int *d, int c)
char *regtilde(char *source, int magic, bool preview) char *regtilde(char *source, int magic, bool preview)
{ {
char *newsub = source; char *newsub = source;
char *tmpsub;
char *p;
int len;
int prevlen;
for (p = newsub; *p; p++) { for (char *p = newsub; *p; p++) {
if ((*p == '~' && magic) || (*p == '\\' && *(p + 1) == '~' && !magic)) { if ((*p == '~' && magic) || (*p == '\\' && *(p + 1) == '~' && !magic)) {
if (reg_prev_sub != NULL) { if (reg_prev_sub != NULL) {
// length = len(newsub) - 1 + len(prev_sub) + 1 // length = len(newsub) - 1 + len(prev_sub) + 1
prevlen = (int)strlen(reg_prev_sub); // Avoid making the text longer than MAXCOL, it will cause
tmpsub = xmalloc(strlen(newsub) + (size_t)prevlen); // trouble at some point.
size_t prevsublen = strlen(reg_prev_sub);
size_t newsublen = strlen(newsub);
if (prevsublen > MAXCOL || newsublen > MAXCOL
|| newsublen + prevsublen > MAXCOL) {
emsg(_(e_resulting_text_too_long));
break;
}
char *tmpsub = xmalloc(newsublen + prevsublen);
// copy prefix // copy prefix
len = (int)(p - newsub); // not including ~ size_t prefixlen = (size_t)(p - newsub); // not including ~
memmove(tmpsub, newsub, (size_t)len); memmove(tmpsub, newsub, prefixlen);
// interpret tilde // interpret tilde
memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen); memmove(tmpsub + prefixlen, reg_prev_sub, prevsublen);
// copy postfix // copy postfix
if (!magic) { if (!magic) {
p++; // back off backslash p++; // back off backslash
} }
STRCPY(tmpsub + len + prevlen, p + 1); STRCPY(tmpsub + prefixlen + prevsublen, p + 1);
if (newsub != source) { // already allocated newsub if (newsub != source) { // allocated newsub before
xfree(newsub); xfree(newsub);
} }
newsub = tmpsub; newsub = tmpsub;
p = newsub + len + prevlen; p = newsub + prefixlen + prevsublen;
} else if (magic) { } else if (magic) {
STRMOVE(p, p + 1); // remove '~' STRMOVE(p, p + 1); // remove '~'
} else { } else {
STRMOVE(p, p + 2); // remove '\~' STRMOVE(p, p + 2); // remove '\~'
} }
p--; p--;
} else { } else {
if (*p == '\\' && p[1]) { // skip escaped characters if (*p == '\\' && p[1]) { // skip escaped characters
p++; p++;
} }
p += utfc_ptr2len(p) - 1; p += utfc_ptr2len(p) - 1;

View File

@ -745,5 +745,9 @@ func Test_write_after_rename()
bwipe! bwipe!
endfunc endfunc
" catch address lines overflow
func Test_ex_address_range_overflow()
call assert_fails(':--+foobar', 'E492:')
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -4164,4 +4164,9 @@ func Test_normal33_g_cmd_nonblank()
bw! bw!
endfunc endfunc
func Test_normal34_zet_large()
" shouldn't cause overflow
norm! z9765405999999999999
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -1081,6 +1081,15 @@ func Test_spell_compatible()
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
endfunc endfunc
func Test_z_equal_with_large_count()
split
set spell
call setline(1, "ff")
norm 0z=337203685477580
set nospell
bwipe!
endfunc
let g:test_data_aff1 = [ let g:test_data_aff1 = [
\"SET ISO8859-1", \"SET ISO8859-1",
\"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ", \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",

View File

@ -206,6 +206,7 @@ func Test_substitute_count()
call assert_equal(['foo foo', 'foo foo', 'foo foo', 'bar foo', 'bar foo'], call assert_equal(['foo foo', 'foo foo', 'foo foo', 'bar foo', 'bar foo'],
\ getline(1, '$')) \ getline(1, '$'))
call assert_fails('s/./b/2147483647', 'E1510:')
bwipe! bwipe!
endfunc endfunc
@ -1415,6 +1416,21 @@ func Test_substitute_short_cmd()
bw! bw!
endfunc endfunc
" Check handling expanding "~" resulting in extremely long text.
" FIXME: disabled, it takes too long to run on CI
"func Test_substitute_tilde_too_long()
" enew!
"
" s/.*/ixxx
" s//~~~~~~~~~AAAAAAA@(
"
" " Either fails with "out of memory" or "text too long".
" " This can take a long time.
" call assert_fails('sil! norm &&&&&&&&&', ['E1240:\|E342:'])
"
" bwipe!
"endfunc
" This should be done last to reveal a memory leak when vim_regsub_both() is " This should be done last to reveal a memory leak when vim_regsub_both() is
" called to evaluate an expression but it is not used in a second call. " called to evaluate an expression but it is not used in a second call.
func Test_z_substitute_expr_leak() func Test_z_substitute_expr_leak()