summaryrefslogtreecommitdiff
path: root/src/charset.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-06-12 17:25:36 +0200
committerBram Moolenaar <Bram@vim.org>2018-06-12 17:25:36 +0200
commit07ccf7ce7fb948fd4d080b817e9fbaea9e721dab (patch)
tree6cef28b8d62f60eb0c3b3b04e5925d6f60eea250 /src/charset.c
parent19834010889fc5bfa0f88b3ba83133dae6c0a35d (diff)
downloadvim-git-07ccf7ce7fb948fd4d080b817e9fbaea9e721dab.tar.gz
patch 8.1.0048: vim_str2nr() does not handle numbers close to the maximumv8.1.0048
Problem: vim_str2nr() does not handle numbers close to the maximum. Solution: Check for overflow more precisely. (Ken Takata, closes #2746)
Diffstat (limited to 'src/charset.c')
-rw-r--r--src/charset.c15
1 files changed, 9 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;