forked from aniani/vim
patch 8.2.3659: integer overflow with large line number
Problem: Integer overflow with large line number. Solution: Check for overflow. (closes #9202)
This commit is contained in:
@@ -688,3 +688,5 @@ EXTERN char e_cannot_expand_sfile_in_vim9_function[]
|
|||||||
INIT(= N_("E1245: Cannot expand <sfile> in a Vim9 function"));
|
INIT(= N_("E1245: Cannot expand <sfile> in a Vim9 function"));
|
||||||
EXTERN char e_cannot_find_variable_to_unlock_str[]
|
EXTERN char e_cannot_find_variable_to_unlock_str[]
|
||||||
INIT(= N_("E1246: Cannot find variable to (un)lock: %s"));
|
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"));
|
||||||
|
@@ -4380,7 +4380,14 @@ get_address(
|
|||||||
if (!VIM_ISDIGIT(*cmd)) // '+' is '+1', but '+0' is not '+1'
|
if (!VIM_ISDIGIT(*cmd)) // '+' is '+1', but '+0' is not '+1'
|
||||||
n = 1;
|
n = 1;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
n = getdigits(&cmd);
|
n = getdigits(&cmd);
|
||||||
|
if (n == MAXLNUM)
|
||||||
|
{
|
||||||
|
emsg(_(e_line_number_out_of_range));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (addr_type == ADDR_TABS_RELATIVE)
|
if (addr_type == ADDR_TABS_RELATIVE)
|
||||||
{
|
{
|
||||||
@@ -4404,9 +4411,16 @@ get_address(
|
|||||||
if (i == '-')
|
if (i == '-')
|
||||||
lnum -= n;
|
lnum -= n;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (n >= LONG_MAX - lnum)
|
||||||
|
{
|
||||||
|
emsg(_(e_line_number_out_of_range));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
lnum += n;
|
lnum += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} while (*cmd == '/' || *cmd == '?');
|
} while (*cmd == '/' || *cmd == '?');
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
17
src/normal.c
17
src/normal.c
@@ -630,10 +630,14 @@ getcount:
|
|||||||
del_from_showcmd(4); // delete the digit and ~@%
|
del_from_showcmd(4); // delete the digit and ~@%
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else if (ca.count0 >= 999999999L)
|
||||||
ca.count0 = ca.count0 * 10 + (c - '0');
|
{
|
||||||
if (ca.count0 < 0) // overflow
|
|
||||||
ca.count0 = 999999999L;
|
ca.count0 = 999999999L;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ca.count0 = ca.count0 * 10 + (c - '0');
|
||||||
|
}
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
// Set v:count here, when called from main() and not a stuffed
|
// Set v:count here, when called from main() and not a stuffed
|
||||||
// command, so that v:count can be used in an expression mapping
|
// command, so that v:count can be used in an expression mapping
|
||||||
@@ -700,11 +704,14 @@ getcount:
|
|||||||
* multiplied.
|
* multiplied.
|
||||||
*/
|
*/
|
||||||
if (ca.count0)
|
if (ca.count0)
|
||||||
|
{
|
||||||
|
if (ca.opcount >= 999999999L / ca.count0)
|
||||||
|
ca.count0 = 999999999L;
|
||||||
|
else
|
||||||
ca.count0 *= ca.opcount;
|
ca.count0 *= ca.opcount;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ca.count0 = ca.opcount;
|
ca.count0 = ca.opcount;
|
||||||
if (ca.count0 < 0) // overflow
|
|
||||||
ca.count0 = 999999999L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -655,4 +655,16 @@ func Test_not_break_expression_register()
|
|||||||
call assert_equal('1+1', getreg('=', 1))
|
call assert_equal('1+1', getreg('=', 1))
|
||||||
endfunc
|
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: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -3519,4 +3519,25 @@ func Test_normal_gj_on_extra_wide_char()
|
|||||||
bw!
|
bw!
|
||||||
endfunc
|
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: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -757,6 +757,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3659,
|
||||||
/**/
|
/**/
|
||||||
3658,
|
3658,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user