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)
Files: src/charset.c, src/eval.c, src/evalfunc.c, src/structs.h,
src/testdir/test_viml.vim
*** ../vim-8.0.0218/src/charset.c 2017-01-10 13:51:05.583236296 +0100
--- src/charset.c 2017-01-22 18:23:56.676226532 +0100
***************
*** 1901,1907 ****
n += 2; /* skip over "0b" */
while ('0' <= *ptr && *ptr <= '1')
{
! un = 2 * un + (unsigned long)(*ptr - '0');
++ptr;
if (n++ == maxlen)
break;
--- 1901,1911 ----
n += 2; /* skip over "0b" */
while ('0' <= *ptr && *ptr <= '1')
{
! /* avoid ubsan error for overflow */
! if (un < UVARNUM_MAX / 2)
! un = 2 * un + (unsigned long)(*ptr - '0');
! else
! un = UVARNUM_MAX;
++ptr;
if (n++ == maxlen)
break;
***************
*** 1912,1918 ****
/* octal */
while ('0' <= *ptr && *ptr <= '7')
{
! un = 8 * un + (uvarnumber_T)(*ptr - '0');
++ptr;
if (n++ == maxlen)
break;
--- 1916,1926 ----
/* octal */
while ('0' <= *ptr && *ptr <= '7')
{
! /* avoid ubsan error for overflow */
! if (un < UVARNUM_MAX / 8)
! un = 8 * un + (uvarnumber_T)(*ptr - '0');
! else
! un = UVARNUM_MAX;
++ptr;
if (n++ == maxlen)
break;
***************
*** 1925,1931 ****
n += 2; /* skip over "0x" */
while (vim_isxdigit(*ptr))
{
! un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
++ptr;
if (n++ == maxlen)
break;
--- 1933,1943 ----
n += 2; /* skip over "0x" */
while (vim_isxdigit(*ptr))
{
! /* avoid ubsan error for overflow */
! if (un < UVARNUM_MAX / 16)
! un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
! else
! un = UVARNUM_MAX;
++ptr;
if (n++ == maxlen)
break;
***************
*** 1936,1942 ****
/* decimal */
while (VIM_ISDIGIT(*ptr))
{
! un = 10 * un + (uvarnumber_T)(*ptr - '0');
++ptr;
if (n++ == maxlen)
break;
--- 1948,1958 ----
/* decimal */
while (VIM_ISDIGIT(*ptr))
{
! /* avoid ubsan error for overflow */
! if (un < UVARNUM_MAX / 10)
! un = 10 * un + (uvarnumber_T)(*ptr - '0');
! else
! un = UVARNUM_MAX;
++ptr;
if (n++ == maxlen)
break;
***************
*** 1950,1958 ****
if (nptr != NULL)
{
if (negative) /* account for leading '-' for decimal numbers */
! *nptr = -(varnumber_T)un;
else
*nptr = (varnumber_T)un;
}
if (unptr != NULL)
*unptr = un;
--- 1966,1984 ----
if (nptr != NULL)
{
if (negative) /* account for leading '-' for decimal numbers */
! {
! /* avoid ubsan error for overflow */
! if (un > VARNUM_MAX)
! *nptr = VARNUM_MIN;
! else
! *nptr = -(varnumber_T)un;
! }
else
+ {
+ if (un > VARNUM_MAX)
+ un = VARNUM_MAX;
*nptr = (varnumber_T)un;
+ }
}
if (unptr != NULL)
*unptr = un;
*** ../vim-8.0.0218/src/eval.c 2017-01-14 20:06:11.123087733 +0100
--- src/eval.c 2017-01-22 18:18:11.942429692 +0100
***************
*** 4109,4129 ****
{
if (n2 == 0) /* give an error message? */
{
- #ifdef FEAT_NUM64
if (n1 == 0)
! n1 = -0x7fffffffffffffffLL - 1; /* similar to NaN */
else if (n1 < 0)
! n1 = -0x7fffffffffffffffLL;
else
! n1 = 0x7fffffffffffffffLL;
! #else
! if (n1 == 0)
! n1 = -0x7fffffffL - 1L; /* similar to NaN */
! else if (n1 < 0)
! n1 = -0x7fffffffL;
! else
! n1 = 0x7fffffffL;
! #endif
}
else
n1 = n1 / n2;
--- 4109,4120 ----
{
if (n2 == 0) /* give an error message? */
{
if (n1 == 0)
! n1 = VARNUM_MIN; /* similar to NaN */
else if (n1 < 0)
! n1 = -VARNUM_MAX;
else
! n1 = VARNUM_MAX;
}
else
n1 = n1 / n2;
*** ../vim-8.0.0218/src/evalfunc.c 2017-01-21 20:04:17.566757789 +0100
--- src/evalfunc.c 2017-01-22 18:18:11.946429667 +0100
***************
*** 3304,3324 ****
if (get_float_arg(argvars, &f) == OK)
{
! # ifdef FEAT_NUM64
! if (f < -0x7fffffffffffffffLL)
! rettv->vval.v_number = -0x7fffffffffffffffLL;
! else if (f > 0x7fffffffffffffffLL)
! rettv->vval.v_number = 0x7fffffffffffffffLL;
else
rettv->vval.v_number = (varnumber_T)f;
- # else
- if (f < -0x7fffffff)
- rettv->vval.v_number = -0x7fffffff;
- else if (f > 0x7fffffff)
- rettv->vval.v_number = 0x7fffffff;
- else
- rettv->vval.v_number = (varnumber_T)f;
- # endif
}
}
--- 3304,3315 ----
if (get_float_arg(argvars, &f) == OK)
{
! if (f < -VARNUM_MAX)
! rettv->vval.v_number = -VARNUM_MAX;
! else if (f > VARNUM_MAX)
! rettv->vval.v_number = VARNUM_MAX;
else
rettv->vval.v_number = (varnumber_T)f;
}
}
*** ../vim-8.0.0218/src/structs.h 2017-01-14 14:28:26.952592354 +0100
--- src/structs.h 2017-01-22 18:18:11.946429667 +0100
***************
*** 1133,1157 ****
--- 1133,1175 ----
# ifdef PROTO
typedef long varnumber_T;
typedef unsigned long uvarnumber_T;
+ #define VARNUM_MIN LONG_MIN
+ #define VARNUM_MAX LONG_MAX
+ #define UVARNUM_MAX ULONG_MAX
# else
typedef __int64 varnumber_T;
typedef unsigned __int64 uvarnumber_T;
+ #define VARNUM_MIN _I64_MIN
+ #define VARNUM_MAX _I64_MAX
+ #define UVARNUM_MAX _UI64_MAX
# endif
# elif defined(HAVE_STDINT_H)
typedef int64_t varnumber_T;
typedef uint64_t uvarnumber_T;
+ #define VARNUM_MIN INT64_MIN
+ #define VARNUM_MAX INT64_MAX
+ #define UVARNUM_MAX UINT64_MAX
# else
typedef long varnumber_T;
typedef unsigned long uvarnumber_T;
+ #define VARNUM_MIN LONG_MIN
+ #define VARNUM_MAX LONG_MAX
+ #define UVARNUM_MAX ULONG_MAX
# endif
#else
/* Use 32-bit Number. */
# if VIM_SIZEOF_INT <= 3 /* use long if int is smaller than 32 bits */
typedef long varnumber_T;
typedef unsigned long uvarnumber_T;
+ #define VARNUM_MIN LONG_MIN
+ #define VARNUM_MAX LONG_MAX
+ #define UVARNUM_MAX ULONG_MAX
# else
typedef int varnumber_T;
typedef unsigned int uvarnumber_T;
+ #define VARNUM_MIN INT_MIN
+ #define VARNUM_MAX INT_MAX
+ #define UVARNUM_MAX UINT_MAX
# endif
#endif
*** ../vim-8.0.0218/src/testdir/test_viml.vim 2017-01-12 22:20:49.461383785
+0100
--- src/testdir/test_viml.vim 2017-01-22 18:18:11.946429667 +0100
***************
*** 1226,1232 ****
call assert_equal( 9223372036854775807, 1 / 0)
call assert_equal(-9223372036854775807, -1 / 0)
! call assert_equal(-9223372036854775808, 0 / 0)
call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
--- 1226,1232 ----
call assert_equal( 9223372036854775807, 1 / 0)
call assert_equal(-9223372036854775807, -1 / 0)
! call assert_equal(-9223372036854775807 - 1, 0 / 0)
call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
*** ../vim-8.0.0218/src/version.c 2017-01-22 16:46:52.253278433 +0100
--- src/version.c 2017-01-22 18:33:21.376620042 +0100
***************
*** 766,767 ****
--- 766,769 ----
{ /* Add new patch number below this line */
+ /**/
+ 219,
/**/
--
Q: Why do ducks have flat feet?
A: To stamp out forest fires.
Q: Why do elephants have flat feet?
A: To stamp out flaming ducks.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.