]> granicus.if.org Git - vim/commitdiff
patch 8.1.0048: vim_str2nr() does not handle numbers close to the maximum v8.1.0048
authorBram Moolenaar <Bram@vim.org>
Tue, 12 Jun 2018 15:25:36 +0000 (17:25 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 12 Jun 2018 15:25:36 +0000 (17:25 +0200)
Problem:    vim_str2nr() does not handle numbers close to the maximum.
Solution:   Check for overflow more precisely. (Ken Takata, closes #2746)

src/charset.c
src/version.c

index e6657ce84c7037c128342f2d1c390e4644bb7216..179fc89db3c7cb4f5dbe174791acab9c701f2e4d 100644 (file)
@@ -1928,8 +1928,8 @@ vim_str2nr(
        while ('0' <= *ptr && *ptr <= '1')
        {
            /* avoid ubsan error for overflow */
-           if (un < UVARNUM_MAX / 2)
-               un = 2 * un + (unsigned long)(*ptr - '0');
+           if (un <= UVARNUM_MAX / 2)
+               un = 2 * un + (uvarnumber_T)(*ptr - '0');
            else
                un = UVARNUM_MAX;
            ++ptr;
@@ -1943,7 +1943,7 @@ vim_str2nr(
        while ('0' <= *ptr && *ptr <= '7')
        {
            /* avoid ubsan error for overflow */
-           if (un < UVARNUM_MAX / 8)
+           if (un <= UVARNUM_MAX / 8)
                un = 8 * un + (uvarnumber_T)(*ptr - '0');
            else
                un = UVARNUM_MAX;
@@ -1960,7 +1960,7 @@ vim_str2nr(
        while (vim_isxdigit(*ptr))
        {
            /* avoid ubsan error for overflow */
-           if (un < UVARNUM_MAX / 16)
+           if (un <= UVARNUM_MAX / 16)
                un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
            else
                un = UVARNUM_MAX;
@@ -1974,9 +1974,12 @@ vim_str2nr(
        /* decimal */
        while (VIM_ISDIGIT(*ptr))
        {
+           uvarnumber_T    digit = (uvarnumber_T)(*ptr - '0');
+
            /* avoid ubsan error for overflow */
-           if (un < UVARNUM_MAX / 10)
-               un = 10 * un + (uvarnumber_T)(*ptr - '0');
+           if (un < UVARNUM_MAX / 10
+                   || (un == UVARNUM_MAX / 10 && digit <= UVARNUM_MAX % 10))
+               un = 10 * un + digit;
            else
                un = UVARNUM_MAX;
            ++ptr;
index d290fda6fd2c88a94abfcc7d039f495ccb8b816e..fc68f8ef2eb76d1a81f325e5eafc0ecca519ba4a 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    48,
 /**/
     47,
 /**/