summaryrefslogtreecommitdiffstats
path: root/src/charset.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-03-04 20:47:39 +0000
committerBram Moolenaar <Bram@vim.org>2023-03-04 20:47:39 +0000
commit5fb78c3fa5c996c08a65431d698bd2c251eef5c7 (patch)
tree859712525dc94a60f02b27c38d23fdf7f3e96590 /src/charset.c
parent5284b23e148063648be0ff46c730ca574e3ca9fa (diff)
patch 9.0.1380: CTRL-X on 2**64 subtracts twov9.0.1380
Problem: CTRL-X on 2**64 subtracts two. (James McCoy) Solution: Correct computation for large number. (closes #12103)
Diffstat (limited to 'src/charset.c')
-rw-r--r--src/charset.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/charset.c b/src/charset.c
index 826a768ae0..6b2790f0ea 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2138,7 +2138,8 @@ vim_str2nr(
varnumber_T *nptr, // return: signed result
uvarnumber_T *unptr, // return: unsigned result
int maxlen, // max length of string to check
- int strict) // check strictly
+ int strict, // check strictly
+ int *overflow) // when not NULL set to TRUE for overflow
{
char_u *ptr = start;
int pre = 0; // default is decimal
@@ -2209,7 +2210,11 @@ vim_str2nr(
if (un <= UVARNUM_MAX / 2)
un = 2 * un + (uvarnumber_T)(*ptr - '0');
else
+ {
un = UVARNUM_MAX;
+ if (overflow != NULL)
+ *overflow = TRUE;
+ }
++ptr;
if (n++ == maxlen)
break;
@@ -2234,7 +2239,11 @@ vim_str2nr(
if (un <= UVARNUM_MAX / 8)
un = 8 * un + (uvarnumber_T)(*ptr - '0');
else
+ {
un = UVARNUM_MAX;
+ if (overflow != NULL)
+ *overflow = TRUE;
+ }
++ptr;
if (n++ == maxlen)
break;
@@ -2258,7 +2267,11 @@ vim_str2nr(
if (un <= UVARNUM_MAX / 16)
un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
else
+ {
un = UVARNUM_MAX;
+ if (overflow != NULL)
+ *overflow = TRUE;
+ }
++ptr;
if (n++ == maxlen)
break;
@@ -2282,7 +2295,11 @@ vim_str2nr(
|| (un == UVARNUM_MAX / 10 && digit <= UVARNUM_MAX % 10))
un = 10 * un + digit;
else
+ {
un = UVARNUM_MAX;
+ if (overflow != NULL)
+ *overflow = TRUE;
+ }
++ptr;
if (n++ == maxlen)
break;
@@ -2310,7 +2327,11 @@ vim_str2nr(
{
// avoid ubsan error for overflow
if (un > VARNUM_MAX)
+ {
*nptr = VARNUM_MIN;
+ if (overflow != NULL)
+ *overflow = TRUE;
+ }
else
*nptr = -(varnumber_T)un;
}
@@ -2318,7 +2339,11 @@ vim_str2nr(
{
// prevent a large unsigned number to become negative
if (un > VARNUM_MAX)
+ {
un = VARNUM_MAX;
+ if (overflow != NULL)
+ *overflow = TRUE;
+ }
*nptr = (varnumber_T)un;
}
}