Patch 8.2.3659
Problem: Integer overflow with large line number.
Solution: Check for overflow. (closes #9202)
Files: src/errors.h, src/ex_docmd.c, src/testdir/test_excmd.vim
src/normal.c, src/testdir/test_normal.vim
*** ../vim-8.2.3658/src/errors.h 2021-11-22 21:58:37.918668436 +0000
--- src/errors.h 2021-11-24 11:43:29.642462961 +0000
***************
*** 688,690 ****
--- 688,692 ----
INIT(= N_("E1245: Cannot expand <sfile> in a Vim9 function"));
EXTERN char e_cannot_find_variable_to_unlock_str[]
INIT(= N_("E1246: Cannot find variable to (un)lock: %s"));
+ EXTERN char e_line_number_out_of_range[]
+ INIT(= N_("E1247: Line number out of range"));
*** ../vim-8.2.3658/src/ex_docmd.c 2021-11-19 11:59:04.927685669 +0000
--- src/ex_docmd.c 2021-11-24 11:51:30.452132000 +0000
***************
*** 4380,4386 ****
--- 4380,4393 ----
if (!VIM_ISDIGIT(*cmd)) // '+' is '+1', but '+0' is not '+1'
n = 1;
else
+ {
n = getdigits(&cmd);
+ if (n == MAXLNUM)
+ {
+ emsg(_(e_line_number_out_of_range));
+ goto error;
+ }
+ }
if (addr_type == ADDR_TABS_RELATIVE)
{
***************
*** 4398,4410 ****
// Relative line addressing, need to adjust for folded lines
// now, but only do it after the first address.
if (addr_type == ADDR_LINES && (i == '-' || i == '+')
! && address_count >= 2)
(void)hasFolding(lnum, NULL, &lnum);
#endif
if (i == '-')
lnum -= n;
else
lnum += n;
}
}
} while (*cmd == '/' || *cmd == '?');
--- 4405,4424 ----
// Relative line addressing, need to adjust for folded lines
// now, but only do it after the first address.
if (addr_type == ADDR_LINES && (i == '-' || i == '+')
! && address_count >= 2)
(void)hasFolding(lnum, NULL, &lnum);
#endif
if (i == '-')
lnum -= n;
else
+ {
+ if (n >= LONG_MAX - lnum)
+ {
+ emsg(_(e_line_number_out_of_range));
+ goto error;
+ }
lnum += n;
+ }
}
}
} while (*cmd == '/' || *cmd == '?');
*** ../vim-8.2.3658/src/testdir/test_excmd.vim 2021-11-21 11:35:59.456938797 +0000
--- src/testdir/test_excmd.vim 2021-11-24 11:57:22.618921533 +0000
***************
*** 655,658 ****
--- 655,670 ----
call assert_equal('1+1', getreg('=', 1))
endfunc
+ func Test_address_line_overflow()
+ if v:sizeoflong < 8
+ throw 'Skipped: only works with 64 bit long ints'
+ endif
+ new
+ call setline(1, 'text')
+ call assert_fails('|.44444444444444444444444', 'E1247:')
+ call assert_fails('|.9223372036854775806', 'E1247:')
+ bwipe!
+ endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.3658/src/normal.c 2021-11-22 14:16:05.113603052 +0000
--- src/normal.c 2021-11-24 12:11:09.513125835 +0000
***************
*** 630,639 ****
del_from_showcmd(4); // delete the digit and ~@%
#endif
}
else
ca.count0 = ca.count0 * 10 + (c - '0');
! if (ca.count0 < 0) // overflow
! ca.count0 = 999999999L;
#ifdef FEAT_EVAL
// Set v:count here, when called from main() and not a stuffed
// command, so that v:count can be used in an expression mapping
--- 630,643 ----
del_from_showcmd(4); // delete the digit and ~@%
#endif
}
+ else if (ca.count0 >= 999999999L)
+ {
+ ca.count0 = 999999999L;
+ }
else
+ {
ca.count0 = ca.count0 * 10 + (c - '0');
! }
#ifdef FEAT_EVAL
// Set v:count here, when called from main() and not a stuffed
// command, so that v:count can be used in an expression mapping
***************
*** 700,710 ****
* multiplied.
*/
if (ca.count0)
! ca.count0 *= ca.opcount;
else
ca.count0 = ca.opcount;
- if (ca.count0 < 0) // overflow
- ca.count0 = 999999999L;
}
/*
--- 704,717 ----
* multiplied.
*/
if (ca.count0)
! {
! if (ca.opcount >= 999999999L / ca.count0)
! ca.count0 = 999999999L;
! else
! ca.count0 *= ca.opcount;
! }
else
ca.count0 = ca.opcount;
}
/*
*** ../vim-8.2.3658/src/testdir/test_normal.vim 2021-11-22 14:16:05.117603051 +0000
--- src/testdir/test_normal.vim 2021-11-24 12:15:56.468635073 +0000
***************
*** 3519,3522 ****
--- 3519,3543 ----
bw!
endfunc
+ func Test_normal_count_out_of_range()
+ new
+ call setline(1, 'text')
+ normal 44444444444|
+ call assert_equal(999999999, v:count)
+ normal 444444444444|
+ call assert_equal(999999999, v:count)
+ normal 4444444444444|
+ call assert_equal(999999999, v:count)
+ normal 4444444444444444444|
+ call assert_equal(999999999, v:count)
+
+ normal 9y99999999|
+ call assert_equal(899999991, v:count)
+ normal 10y99999999|
+ call assert_equal(999999999, v:count)
+ normal 44444444444y44444444444|
+ call assert_equal(999999999, v:count)
+ bwipe!
+ endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.3658/src/version.c 2021-11-24 11:18:03.742223158 +0000
--- src/version.c 2021-11-24 11:44:26.134427584 +0000
***************
*** 759,760 ****
--- 759,762 ----
{ /* Add new patch number below this line */
+ /**/
+ 3659,
/**/
--
Biting someone with your natural teeth is "simple assault," while biting
someone with your false teeth is "aggravated assault."
[real standing law in Louisana, United States of America]
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///