From 07ccf7ce7fb948fd4d080b817e9fbaea9e721dab Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 12 Jun 2018 17:25:36 +0200 Subject: [PATCH] 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 #2746) --- src/charset.c | 15 +++++++++------ src/version.c | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/charset.c b/src/charset.c index e6657ce84..179fc89db 100644 --- 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 index d290fda6f..fc68f8ef2 100644 --- a/src/version.c +++ b/src/version.c @@ -761,6 +761,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 48, /**/ 47, /**/ -- 2.40.0