mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.2112: [security]: overflow in shift_line
Problem: [security]: overflow in shift_line Solution: allow a max indent of INT_MAX [security]: overflow in shift_line When shifting lines in operator pending mode and using a very large value, we may overflow the size of integer. Fix this by using a long variable, testing if the result would be larger than INT_MAX and if so, indent by INT_MAX value. Special case: We cannot use long here, since on 32bit architectures (or on Windows?), it typically cannot take larger values than a plain int, so we have to use long long count, decide whether the resulting multiplication of the shiftwidth value * amount is larger than INT_MAX and if so, we will store INT_MAX as possible larges value in the long long count variable. Then we can safely cast it back to int when calling the functions to set the indent (set_indent() or change_indent()). So this should be safe. Add a test that when using a huge value in operator pending mode for shifting, we will shift by INT_MAX closes: #13535 Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
73b2d3790c
commit
6bf131888a
15
src/ops.c
15
src/ops.c
@ -229,11 +229,11 @@ shift_line(
|
|||||||
int amount,
|
int amount,
|
||||||
int call_changed_bytes) // call changed_bytes()
|
int call_changed_bytes) // call changed_bytes()
|
||||||
{
|
{
|
||||||
int count;
|
long long count;
|
||||||
int i, j;
|
int i, j;
|
||||||
int sw_val = (int)get_sw_value_indent(curbuf);
|
int sw_val = (int)get_sw_value_indent(curbuf);
|
||||||
|
|
||||||
count = get_indent(); // get current indent
|
count = (long long)get_indent(); // get current indent
|
||||||
|
|
||||||
if (round) // round off indent
|
if (round) // round off indent
|
||||||
{
|
{
|
||||||
@ -260,14 +260,19 @@ shift_line(
|
|||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
count += sw_val * amount;
|
{
|
||||||
|
if ((long long)sw_val * (long long)amount > INT_MAX - count)
|
||||||
|
count = INT_MAX;
|
||||||
|
else
|
||||||
|
count += (long long)sw_val * (long long)amount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new indent
|
// Set new indent
|
||||||
if (State & VREPLACE_FLAG)
|
if (State & VREPLACE_FLAG)
|
||||||
change_indent(INDENT_SET, count, FALSE, NUL, call_changed_bytes);
|
change_indent(INDENT_SET, (int)count, FALSE, NUL, call_changed_bytes);
|
||||||
else
|
else
|
||||||
(void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0);
|
(void)set_indent((int)count, call_changed_bytes ? SIN_CHANGED : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -275,4 +275,15 @@ func Test_formatting_keeps_first_line_indent()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for indenting with large amount, causes overflow
|
||||||
|
func Test_indent_overflow_count()
|
||||||
|
new
|
||||||
|
setl sw=8
|
||||||
|
call setline(1, "abc")
|
||||||
|
norm! V2147483647>
|
||||||
|
" indents by INT_MAX
|
||||||
|
call assert_equal(2147483647, indent(1))
|
||||||
|
close!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -704,6 +704,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 */
|
||||||
|
/**/
|
||||||
|
2112,
|
||||||
/**/
|
/**/
|
||||||
2111,
|
2111,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user