vim-patch:8.2.4065: computation overflow with large cound for :yank

Problem:    Computation overflow with large cound for :yank.
Solution:   Avoid an overflow.

3cf21b3051

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
zeertzjq 2024-07-14 05:58:32 +08:00
parent 6276fce11e
commit 5531c95101
3 changed files with 16 additions and 7 deletions

View File

@ -1411,7 +1411,11 @@ void set_cmd_count(exarg_T *eap, linenr_T count, bool validate)
} }
} else { } else {
eap->line1 = eap->line2; eap->line1 = eap->line2;
eap->line2 += count - 1; if (eap->line2 >= INT32_MAX - (count - 1)) {
eap->line2 = INT32_MAX;
} else {
eap->line2 += count - 1;
}
eap->addr_count++; eap->addr_count++;
// Be vi compatible: no error message for out of range. // Be vi compatible: no error message for out of range.
if (validate && eap->line2 > curbuf->b_ml.ml_line_count) { if (validate && eap->line2 > curbuf->b_ml.ml_line_count) {
@ -1429,7 +1433,7 @@ static int parse_count(exarg_T *eap, const char **errormsg, bool validate)
if ((eap->argt & EX_COUNT) && ascii_isdigit(*eap->arg) if ((eap->argt & EX_COUNT) && ascii_isdigit(*eap->arg)
&& (!(eap->argt & EX_BUFNAME) || *(p = skipdigits(eap->arg + 1)) == NUL && (!(eap->argt & EX_BUFNAME) || *(p = skipdigits(eap->arg + 1)) == NUL
|| ascii_iswhite(*p))) { || ascii_iswhite(*p))) {
linenr_T n = getdigits_int32(&eap->arg, false, -1); linenr_T n = getdigits_int32(&eap->arg, false, INT32_MAX);
eap->arg = skipwhite(eap->arg); eap->arg = skipwhite(eap->arg);
if (eap->args != NULL) { if (eap->args != NULL) {

View File

@ -29,13 +29,13 @@ describe('Ex cmds', function()
':tabnext 9999999999999999999999999999999999999999', ':tabnext 9999999999999999999999999999999999999999',
'Vim(tabnext):E475: Invalid argument: 9999999999999999999999999999999999999999' 'Vim(tabnext):E475: Invalid argument: 9999999999999999999999999999999999999999'
) )
check_excmd_err( eq(
':N 9999999999999999999999999999999999999999', 'Vim(Next):E163: There is only one file to edit',
'Vim(Next):E939: Positive count required' pcall_err(command, ':N 9999999999999999999999999999999999999999')
) )
check_excmd_err( check_excmd_err(
':bdelete 9999999999999999999999999999999999999999', ':bdelete 9999999999999999999999999999999999999999',
'Vim(bdelete):E939: Positive count required' 'Vim(bdelete):E516: No buffers were deleted'
) )
eq( eq(
'Vim(menu):E329: No menu "9999999999999999999999999999999999999999"', 'Vim(menu):E329: No menu "9999999999999999999999999999999999999999"',

View File

@ -722,9 +722,14 @@ func Test_address_line_overflow()
throw 'Skipped: only works with 64 bit long ints' throw 'Skipped: only works with 64 bit long ints'
endif endif
new new
call setline(1, 'text') call setline(1, range(100))
call assert_fails('|.44444444444444444444444', 'E1247:') call assert_fails('|.44444444444444444444444', 'E1247:')
call assert_fails('|.9223372036854775806', 'E1247:') call assert_fails('|.9223372036854775806', 'E1247:')
$
yank 77777777777777777777
call assert_equal("99\n", @")
bwipe! bwipe!
endfunc endfunc