mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 02:34:59 -07:00
vim-patch:9.0.2122: [security]: prevent overflow in indenting
Problem: [security]: prevent overflow in indenting
Solution: use long long and remove cast to (int)
The shiftwidth option values are defined as being long. However, when
calculating the actual amount of indent, we cast down to (int), which
may cause the shiftwidth value to become negative and later it may even
cause Vim to try to allocate a huge amount of memory.
We already use long and long long variable types to calculate the indent
(and detect possible overflows), so the cast to (int) seems superfluous
and can be safely removed. So let's just remove the (int) cast and
calculate the indent using longs.
Additionally, the 'shiftwidth' option value is also used when determining
the actual 'cino' options. There it can again cause another overflow, so
make sure it is safe in parse_cino() as well.
fixes: vim/vim#13554
closes: vim/vim#13555
3770574e4a
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
ac230370f3
commit
7a7ed0c8ac
@ -1689,7 +1689,7 @@ void parse_cino(buf_T *buf)
|
||||
p++;
|
||||
}
|
||||
char *digits_start = p; // remember where the digits start
|
||||
int n = getdigits_int(&p, true, 0);
|
||||
int64_t n = getdigits_int(&p, true, 0);
|
||||
divider = 0;
|
||||
if (*p == '.') { // ".5s" means a fraction.
|
||||
fraction = atoi(++p);
|
||||
@ -1717,119 +1717,125 @@ void parse_cino(buf_T *buf)
|
||||
n = -n;
|
||||
}
|
||||
|
||||
if (n > INT_MAX) {
|
||||
n = INT_MAX;
|
||||
} else if (n < INT_MIN) {
|
||||
n = INT_MIN;
|
||||
}
|
||||
|
||||
// When adding an entry here, also update the default 'cinoptions' in
|
||||
// doc/indent.txt, and add explanation for it!
|
||||
switch (*l) {
|
||||
case '>':
|
||||
buf->b_ind_level = n;
|
||||
buf->b_ind_level = (int)n;
|
||||
break;
|
||||
case 'e':
|
||||
buf->b_ind_open_imag = n;
|
||||
buf->b_ind_open_imag = (int)n;
|
||||
break;
|
||||
case 'n':
|
||||
buf->b_ind_no_brace = n;
|
||||
buf->b_ind_no_brace = (int)n;
|
||||
break;
|
||||
case 'f':
|
||||
buf->b_ind_first_open = n;
|
||||
buf->b_ind_first_open = (int)n;
|
||||
break;
|
||||
case '{':
|
||||
buf->b_ind_open_extra = n;
|
||||
buf->b_ind_open_extra = (int)n;
|
||||
break;
|
||||
case '}':
|
||||
buf->b_ind_close_extra = n;
|
||||
buf->b_ind_close_extra = (int)n;
|
||||
break;
|
||||
case '^':
|
||||
buf->b_ind_open_left_imag = n;
|
||||
buf->b_ind_open_left_imag = (int)n;
|
||||
break;
|
||||
case 'L':
|
||||
buf->b_ind_jump_label = n;
|
||||
buf->b_ind_jump_label = (int)n;
|
||||
break;
|
||||
case ':':
|
||||
buf->b_ind_case = n;
|
||||
buf->b_ind_case = (int)n;
|
||||
break;
|
||||
case '=':
|
||||
buf->b_ind_case_code = n;
|
||||
buf->b_ind_case_code = (int)n;
|
||||
break;
|
||||
case 'b':
|
||||
buf->b_ind_case_break = n;
|
||||
buf->b_ind_case_break = (int)n;
|
||||
break;
|
||||
case 'p':
|
||||
buf->b_ind_param = n;
|
||||
buf->b_ind_param = (int)n;
|
||||
break;
|
||||
case 't':
|
||||
buf->b_ind_func_type = n;
|
||||
buf->b_ind_func_type = (int)n;
|
||||
break;
|
||||
case '/':
|
||||
buf->b_ind_comment = n;
|
||||
buf->b_ind_comment = (int)n;
|
||||
break;
|
||||
case 'c':
|
||||
buf->b_ind_in_comment = n;
|
||||
buf->b_ind_in_comment = (int)n;
|
||||
break;
|
||||
case 'C':
|
||||
buf->b_ind_in_comment2 = n;
|
||||
buf->b_ind_in_comment2 = (int)n;
|
||||
break;
|
||||
case 'i':
|
||||
buf->b_ind_cpp_baseclass = n;
|
||||
buf->b_ind_cpp_baseclass = (int)n;
|
||||
break;
|
||||
case '+':
|
||||
buf->b_ind_continuation = n;
|
||||
buf->b_ind_continuation = (int)n;
|
||||
break;
|
||||
case '(':
|
||||
buf->b_ind_unclosed = n;
|
||||
buf->b_ind_unclosed = (int)n;
|
||||
break;
|
||||
case 'u':
|
||||
buf->b_ind_unclosed2 = n;
|
||||
buf->b_ind_unclosed2 = (int)n;
|
||||
break;
|
||||
case 'U':
|
||||
buf->b_ind_unclosed_noignore = n;
|
||||
buf->b_ind_unclosed_noignore = (int)n;
|
||||
break;
|
||||
case 'W':
|
||||
buf->b_ind_unclosed_wrapped = n;
|
||||
buf->b_ind_unclosed_wrapped = (int)n;
|
||||
break;
|
||||
case 'w':
|
||||
buf->b_ind_unclosed_whiteok = n;
|
||||
buf->b_ind_unclosed_whiteok = (int)n;
|
||||
break;
|
||||
case 'm':
|
||||
buf->b_ind_matching_paren = n;
|
||||
buf->b_ind_matching_paren = (int)n;
|
||||
break;
|
||||
case 'M':
|
||||
buf->b_ind_paren_prev = n;
|
||||
buf->b_ind_paren_prev = (int)n;
|
||||
break;
|
||||
case ')':
|
||||
buf->b_ind_maxparen = n;
|
||||
buf->b_ind_maxparen = (int)n;
|
||||
break;
|
||||
case '*':
|
||||
buf->b_ind_maxcomment = n;
|
||||
buf->b_ind_maxcomment = (int)n;
|
||||
break;
|
||||
case 'g':
|
||||
buf->b_ind_scopedecl = n;
|
||||
buf->b_ind_scopedecl = (int)n;
|
||||
break;
|
||||
case 'h':
|
||||
buf->b_ind_scopedecl_code = n;
|
||||
buf->b_ind_scopedecl_code = (int)n;
|
||||
break;
|
||||
case 'j':
|
||||
buf->b_ind_java = n;
|
||||
buf->b_ind_java = (int)n;
|
||||
break;
|
||||
case 'J':
|
||||
buf->b_ind_js = n;
|
||||
buf->b_ind_js = (int)n;
|
||||
break;
|
||||
case 'l':
|
||||
buf->b_ind_keep_case_label = n;
|
||||
buf->b_ind_keep_case_label = (int)n;
|
||||
break;
|
||||
case '#':
|
||||
buf->b_ind_hash_comment = n;
|
||||
buf->b_ind_hash_comment = (int)n;
|
||||
break;
|
||||
case 'N':
|
||||
buf->b_ind_cpp_namespace = n;
|
||||
buf->b_ind_cpp_namespace = (int)n;
|
||||
break;
|
||||
case 'k':
|
||||
buf->b_ind_if_for_while = n;
|
||||
buf->b_ind_if_for_while = (int)n;
|
||||
break;
|
||||
case 'E':
|
||||
buf->b_ind_cpp_extern_c = n;
|
||||
buf->b_ind_cpp_extern_c = (int)n;
|
||||
break;
|
||||
case 'P':
|
||||
buf->b_ind_pragma = n;
|
||||
buf->b_ind_pragma = (int)n;
|
||||
break;
|
||||
}
|
||||
if (*p == ',') {
|
||||
|
@ -288,4 +288,19 @@ func Test_indent_overflow_count()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
func Test_indent_overflow_count2()
|
||||
throw 'skipped: Nvim does not support 64-bit number options'
|
||||
new
|
||||
" this only works, when long is 64bits
|
||||
try
|
||||
setl sw=0x180000000
|
||||
catch /^Vim\%((\a\+)\)\=:E487:/
|
||||
throw 'Skipped: value negative on this platform'
|
||||
endtry
|
||||
call setline(1, "\tabc")
|
||||
norm! <<
|
||||
call assert_equal(0, indent(1))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
Loading…
Reference in New Issue
Block a user