# HG changeset patch # User Christian Brabandt # Date 1528817406 -7200 # Node ID 47b2db8a57095914787f1805120b6781b16a4a98 # Parent 18c62ba450988e9ce47a3f90a069226badbeec0f patch 8.1.0048: vim_str2nr() does not handle numbers close to the maximum commit https://github.com/vim/vim/commit/07ccf7ce7fb948fd4d080b817e9fbaea9e721dab Author: Bram Moolenaar Date: Tue Jun 12 17:25:36 2018 +0200 patch 8.1.0048: vim_str2nr() does not handle numbers close to the maximum Problem: vim_str2nr() does not handle numbers close to the maximum. Solution: Check for overflow more precisely. (Ken Takata, closes https://github.com/vim/vim/issues/2746) diff --git a/src/charset.c b/src/charset.c --- a/src/charset.c +++ b/src/charset.c @@ -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; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 48, +/**/ 47, /**/ 46,