summaryrefslogtreecommitdiffstats
path: root/src/cindent.c
diff options
context:
space:
mode:
authorChristian Brabandt <cb@256bit.org>2023-11-22 22:18:35 +0100
committerChristian Brabandt <cb@256bit.org>2023-11-22 22:18:35 +0100
commit3770574e4a70e810add9929973c51f9070c8c851 (patch)
tree4c07fbe0e332d8f4150c075ce96b5655da9fb625 /src/cindent.c
parent26c11c56888d01e298cd8044caf860f3c26f57bb (diff)
patch 9.0.2122: [security]: prevent overflow in indentingv9.0.2122
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: #13554 closes: #13555 Signed-off-by: Christian Brabandt <cb@256bit.org>
Diffstat (limited to 'src/cindent.c')
-rw-r--r--src/cindent.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/src/cindent.c b/src/cindent.c
index 9b2b6442a6..7ac1f4ba87 100644
--- a/src/cindent.c
+++ b/src/cindent.c
@@ -1730,10 +1730,17 @@ parse_cino(buf_T *buf)
char_u *p;
char_u *l;
char_u *digits;
- int n;
+ long long n;
int divider;
int fraction = 0;
- int sw = (int)get_sw_value(buf);
+ int sw;
+ long long t = get_sw_value(buf);
+
+ // needed for cino-(, it will be multiplied by 2 again
+ if (t > INT_MAX / 2)
+ sw = INT_MAX / 2;
+ else
+ sw = (int)t;
// Set the default values.
@@ -1902,47 +1909,52 @@ parse_cino(buf_T *buf)
if (l[1] == '-')
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; break;
- case 'e': buf->b_ind_open_imag = n; break;
- case 'n': buf->b_ind_no_brace = n; break;
- case 'f': buf->b_ind_first_open = n; break;
- case '{': buf->b_ind_open_extra = n; break;
- case '}': buf->b_ind_close_extra = n; break;
- case '^': buf->b_ind_open_left_imag = n; break;
- case 'L': buf->b_ind_jump_label = n; break;
- case ':': buf->b_ind_case = n; break;
- case '=': buf->b_ind_case_code = n; break;
- case 'b': buf->b_ind_case_break = n; break;
- case 'p': buf->b_ind_param = n; break;
- case 't': buf->b_ind_func_type = n; break;
- case '/': buf->b_ind_comment = n; break;
- case 'c': buf->b_ind_in_comment = n; break;
- case 'C': buf->b_ind_in_comment2 = n; break;
- case 'i': buf->b_ind_cpp_baseclass = n; break;
- case '+': buf->b_ind_continuation = n; break;
- case '(': buf->b_ind_unclosed = n; break;
- case 'u': buf->b_ind_unclosed2 = n; break;
- case 'U': buf->b_ind_unclosed_noignore = n; break;
- case 'W': buf->b_ind_unclosed_wrapped = n; break;
- case 'w': buf->b_ind_unclosed_whiteok = n; break;
- case 'm': buf->b_ind_matching_paren = n; break;
- case 'M': buf->b_ind_paren_prev = n; break;
- case ')': buf->b_ind_maxparen = n; break;
- case '*': buf->b_ind_maxcomment = n; break;
- case 'g': buf->b_ind_scopedecl = n; break;
- case 'h': buf->b_ind_scopedecl_code = n; break;
- case 'j': buf->b_ind_java = n; break;
- case 'J': buf->b_ind_js = n; break;
- case 'l': buf->b_ind_keep_case_label = n; break;
- case '#': buf->b_ind_hash_comment = n; break;
- case 'N': buf->b_ind_cpp_namespace = n; break;
- case 'k': buf->b_ind_if_for_while = n; break;
- case 'E': buf->b_ind_cpp_extern_c = n; break;
- case 'P': buf->b_ind_pragma = n; break;
+ case '>': buf->b_ind_level = (int)n; break;
+ case 'e': buf->b_ind_open_imag = (int)n; break;
+ case 'n': buf->b_ind_no_brace = (int)n; break;
+ case 'f': buf->b_ind_first_open = (int)n; break;
+ case '{': buf->b_ind_open_extra = (int)n; break;
+ case '}': buf->b_ind_close_extra = (int)n; break;
+ case '^': buf->b_ind_open_left_imag = (int)n; break;
+ case 'L': buf->b_ind_jump_label = (int)n; break;
+ case ':': buf->b_ind_case = (int)n; break;
+ case '=': buf->b_ind_case_code = (int)n; break;
+ case 'b': buf->b_ind_case_break = (int)n; break;
+ case 'p': buf->b_ind_param = (int)n; break;
+ case 't': buf->b_ind_func_type = (int)n; break;
+ case '/': buf->b_ind_comment = (int)n; break;
+ case 'c': buf->b_ind_in_comment = (int)n; break;
+ case 'C': buf->b_ind_in_comment2 = (int)n; break;
+ case 'i': buf->b_ind_cpp_baseclass = (int)n; break;
+ case '+': buf->b_ind_continuation = (int)n; break;
+ case '(': buf->b_ind_unclosed = (int)n; break;
+ case 'u': buf->b_ind_unclosed2 = (int)n; break;
+ case 'U': buf->b_ind_unclosed_noignore = (int)n; break;
+ case 'W': buf->b_ind_unclosed_wrapped = (int)n; break;
+ case 'w': buf->b_ind_unclosed_whiteok = (int)n; break;
+ case 'm': buf->b_ind_matching_paren = (int)n; break;
+ case 'M': buf->b_ind_paren_prev = (int)n; break;
+ case ')': buf->b_ind_maxparen = (int)n; break;
+ case '*': buf->b_ind_maxcomment = (int)n; break;
+ case 'g': buf->b_ind_scopedecl = (int)n; break;
+ case 'h': buf->b_ind_scopedecl_code = (int)n; break;
+ case 'j': buf->b_ind_java = (int)n; break;
+ case 'J': buf->b_ind_js = (int)n; break;
+ case 'l': buf->b_ind_keep_case_label = (int)n; break;
+ case '#': buf->b_ind_hash_comment = (int)n; break;
+ case 'N': buf->b_ind_cpp_namespace = (int)n; break;
+ case 'k': buf->b_ind_if_for_while = (int)n; break;
+ case 'E': buf->b_ind_cpp_extern_c = (int)n; break;
+ case 'P': buf->b_ind_pragma = (int)n; break;
}
if (*p == ',')
++p;