summaryrefslogtreecommitdiffstats
path: root/src/charset.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-01-22 18:34:57 +0100
committerBram Moolenaar <Bram@vim.org>2017-01-22 18:34:57 +0100
commit7a40ea2138102545848ea86a361f1b8dec7552b5 (patch)
tree28c03360f9bb2de0d7454f50ffccc1f33c75fe54 /src/charset.c
parent2b2207ba69c6b009e466a36eef0644ca723e16d3 (diff)
patch 8.0.0219: ubsan reports errors for overflowv8.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)
Diffstat (limited to 'src/charset.c')
-rw-r--r--src/charset.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/charset.c b/src/charset.c
index c3b62590bc..c047afec7f 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1901,7 +1901,11 @@ vim_str2nr(
n += 2; /* skip over "0b" */
while ('0' <= *ptr && *ptr <= '1')
{
- un = 2 * un + (unsigned long)(*ptr - '0');
+ /* 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,7 +1916,11 @@ vim_str2nr(
/* octal */
while ('0' <= *ptr && *ptr <= '7')
{
- un = 8 * un + (uvarnumber_T)(*ptr - '0');
+ /* 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,7 +1933,11 @@ vim_str2nr(
n += 2; /* skip over "0x" */
while (vim_isxdigit(*ptr))
{
- un = 16 * un + (uvarnumber_T)hex2nr(*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,7 +1948,11 @@ vim_str2nr(
/* decimal */
while (VIM_ISDIGIT(*ptr))
{
- un = 10 * un + (uvarnumber_T)(*ptr - '0');
+ /* 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,9 +1966,19 @@ vim_str2nr(
if (nptr != NULL)
{
if (negative) /* account for leading '-' for decimal numbers */
- *nptr = -(varnumber_T)un;
+ {
+ /* 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;