mirror of
https://github.com/neovim/neovim.git
synced 2025-10-01 07:28:34 +00:00
vim-patch:8.0.0219
Problem: Ubsan reports errors for integer overflow.
Solution: Define macros for minimum and maximum values. Select an
expression based on the value. (Mike Williams)
7a40ea2138
This commit is contained in:
@@ -1683,7 +1683,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
|
|||||||
n += 2; // skip over "0b"
|
n += 2; // skip over "0b"
|
||||||
}
|
}
|
||||||
while ('0' <= *ptr && *ptr <= '1') {
|
while ('0' <= *ptr && *ptr <= '1') {
|
||||||
|
// avoid ubsan error for overflow
|
||||||
|
if (un < UVARNUMBER_MAX / 2) {
|
||||||
un = 2 * un + (uvarnumber_T)(*ptr - '0');
|
un = 2 * un + (uvarnumber_T)(*ptr - '0');
|
||||||
|
} else {
|
||||||
|
un = UVARNUMBER_MAX;
|
||||||
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
if (n++ == maxlen) {
|
if (n++ == maxlen) {
|
||||||
break;
|
break;
|
||||||
@@ -1692,7 +1697,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
|
|||||||
} else if ((pre == '0') || what == STR2NR_OCT + STR2NR_FORCE) {
|
} else if ((pre == '0') || what == STR2NR_OCT + STR2NR_FORCE) {
|
||||||
// octal
|
// octal
|
||||||
while ('0' <= *ptr && *ptr <= '7') {
|
while ('0' <= *ptr && *ptr <= '7') {
|
||||||
|
// avoid ubsan error for overflow
|
||||||
|
if (un < UVARNUMBER_MAX / 8) {
|
||||||
un = 8 * un + (uvarnumber_T)(*ptr - '0');
|
un = 8 * un + (uvarnumber_T)(*ptr - '0');
|
||||||
|
} else {
|
||||||
|
un = UVARNUMBER_MAX;
|
||||||
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
if (n++ == maxlen) {
|
if (n++ == maxlen) {
|
||||||
break;
|
break;
|
||||||
@@ -1705,7 +1715,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
|
|||||||
n += 2; // skip over "0x"
|
n += 2; // skip over "0x"
|
||||||
}
|
}
|
||||||
while (ascii_isxdigit(*ptr)) {
|
while (ascii_isxdigit(*ptr)) {
|
||||||
|
// avoid ubsan error for overflow
|
||||||
|
if (un < UVARNUMBER_MAX / 16) {
|
||||||
un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
|
un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
|
||||||
|
} else {
|
||||||
|
un = UVARNUMBER_MAX;
|
||||||
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
if (n++ == maxlen) {
|
if (n++ == maxlen) {
|
||||||
break;
|
break;
|
||||||
@@ -1714,7 +1729,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
|
|||||||
} else {
|
} else {
|
||||||
// decimal
|
// decimal
|
||||||
while (ascii_isdigit(*ptr)) {
|
while (ascii_isdigit(*ptr)) {
|
||||||
un = 10 * un + (unsigned long)(*ptr - '0');
|
// avoid ubsan error for overflow
|
||||||
|
if (un < UVARNUMBER_MAX / 10) {
|
||||||
|
un = 10 * un + (uvarnumber_T)(*ptr - '0');
|
||||||
|
} else {
|
||||||
|
un = UVARNUMBER_MAX;
|
||||||
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
if (n++ == maxlen) {
|
if (n++ == maxlen) {
|
||||||
break;
|
break;
|
||||||
@@ -1731,10 +1751,17 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nptr != NULL) {
|
if (nptr != NULL) {
|
||||||
if (negative) {
|
if (negative) { // account for leading '-' for decimal numbers
|
||||||
// account for leading '-' for decimal numbers
|
// avoid ubsan error for overflow
|
||||||
*nptr = -(varnumber_T)un;
|
if (un > VARNUMBER_MAX) {
|
||||||
|
*nptr = VARNUMBER_MIN;
|
||||||
} else {
|
} else {
|
||||||
|
*nptr = -(varnumber_T)un;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (un > VARNUMBER_MAX) {
|
||||||
|
un = VARNUMBER_MAX;
|
||||||
|
}
|
||||||
*nptr = (varnumber_T)un;
|
*nptr = (varnumber_T)un;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4032,11 +4032,11 @@ eval6 (
|
|||||||
else if (op == '/') {
|
else if (op == '/') {
|
||||||
if (n2 == 0) { /* give an error message? */
|
if (n2 == 0) { /* give an error message? */
|
||||||
if (n1 == 0)
|
if (n1 == 0)
|
||||||
n1 = -0x7fffffffffffffff - 1; /* similar to NaN */
|
n1 = VARNUMBER_MIN; /* similar to NaN */
|
||||||
else if (n1 < 0)
|
else if (n1 < 0)
|
||||||
n1 = -0x7fffffffffffffff;
|
n1 = -VARNUMBER_MAX;
|
||||||
else
|
else
|
||||||
n1 = 0x7fffffffffffffff;
|
n1 = VARNUMBER_MAX;
|
||||||
} else
|
} else
|
||||||
n1 = n1 / n2;
|
n1 = n1 / n2;
|
||||||
} else {
|
} else {
|
||||||
@@ -8539,8 +8539,8 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
float_T f;
|
float_T f;
|
||||||
|
|
||||||
if (tv_get_float_chk(argvars, &f)) {
|
if (tv_get_float_chk(argvars, &f)) {
|
||||||
if (f < VARNUMBER_MIN) {
|
if (f < -VARNUMBER_MAX) {
|
||||||
rettv->vval.v_number = VARNUMBER_MIN;
|
rettv->vval.v_number = -VARNUMBER_MAX;
|
||||||
} else if (f > VARNUMBER_MAX) {
|
} else if (f > VARNUMBER_MAX) {
|
||||||
rettv->vval.v_number = VARNUMBER_MAX;
|
rettv->vval.v_number = VARNUMBER_MAX;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1078,7 +1078,7 @@ func Test_num64()
|
|||||||
|
|
||||||
call assert_equal( 9223372036854775807, 1 / 0)
|
call assert_equal( 9223372036854775807, 1 / 0)
|
||||||
call assert_equal(-9223372036854775807, -1 / 0)
|
call assert_equal(-9223372036854775807, -1 / 0)
|
||||||
call assert_equal(-9223372036854775808, 0 / 0)
|
call assert_equal(-9223372036854775807 - 1, 0 / 0)
|
||||||
|
|
||||||
call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
|
call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
|
||||||
call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
|
call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
|
||||||
|
Reference in New Issue
Block a user