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
[count] lines, starting with the last line in [range].
When [range] is omitted start in the current line.
*E939*
[count] must be a positive number. Also see
|cmdline-ranges|.
*E939* *E1510*
[count] must be a positive number (max 2147483647)
Also see |cmdline-ranges|.
See |:s_flags| for [flags].
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
as it is given in the first column of a :history listing.
This number remains fixed even if other entries are deleted.
(see |E1510|)
A negative number means the relative position of an entry,
counted from the newest entry (which has index -1) backwards.

View File

@ -30,8 +30,6 @@
# include "cmdhist.c.generated.h"
#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 int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; ///< lastused 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
cmd = skipwhite(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) {
emsg(_(e_zerocount));
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->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 == '-') {
lnum -= n;
} else {
if (n >= INT32_MAX - lnum) {
if (lnum >= 0 && n >= INT32_MAX - lnum) {
*errormsg = _(e_line_number_out_of_range);
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 char e_stray_closing_curly_str[]
EXTERN const char e_stray_closing_curly_str[]
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"));
EXTERN const char e_val_too_large[] 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"));

View File

@ -180,6 +180,9 @@ int get_number(int colon, int *mouse_used)
ui_cursor_goto(msg_row, msg_col);
int c = safe_vgetc();
if (ascii_isdigit(c)) {
if (n > INT_MAX / 10) {
return 0;
}
n = n * 10 + c - '0';
msg_putchar(c);
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) {
n /= 10;
} else if (ascii_isdigit(nchar)) {
if (n > INT_MAX / 10) {
clearopbeep(cap->oap);
break;
}
n = n * 10 + (nchar - '0');
} else if (nchar == CAR) {
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 *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 (reg_prev_sub != NULL) {
// length = len(newsub) - 1 + len(prev_sub) + 1
prevlen = (int)strlen(reg_prev_sub);
tmpsub = xmalloc(strlen(newsub) + (size_t)prevlen);
// Avoid making the text longer than MAXCOL, it will cause
// 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
len = (int)(p - newsub); // not including ~
memmove(tmpsub, newsub, (size_t)len);
size_t prefixlen = (size_t)(p - newsub); // not including ~
memmove(tmpsub, newsub, prefixlen);
// interpret tilde
memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen);
memmove(tmpsub + prefixlen, reg_prev_sub, prevsublen);
// copy postfix
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);
}
newsub = tmpsub;
p = newsub + len + prevlen;
p = newsub + prefixlen + prevsublen;
} else if (magic) {
STRMOVE(p, p + 1); // remove '~'
STRMOVE(p, p + 1); // remove '~'
} else {
STRMOVE(p, p + 2); // remove '\~'
STRMOVE(p, p + 2); // remove '\~'
}
p--;
} else {
if (*p == '\\' && p[1]) { // skip escaped characters
if (*p == '\\' && p[1]) { // skip escaped characters
p++;
}
p += utfc_ptr2len(p) - 1;

View File

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

View File

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

View File

@ -1081,6 +1081,15 @@ func Test_spell_compatible()
call StopVimInTerminal(buf)
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 = [
\"SET ISO8859-1",
\"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'],
\ getline(1, '$'))
call assert_fails('s/./b/2147483647', 'E1510:')
bwipe!
endfunc
@ -1415,6 +1416,21 @@ func Test_substitute_short_cmd()
bw!
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
" called to evaluate an expression but it is not used in a second call.
func Test_z_substitute_expr_leak()