From 5fb78c3fa5c996c08a65431d698bd2c251eef5c7 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 4 Mar 2023 20:47:39 +0000 Subject: patch 9.0.1380: CTRL-X on 2**64 subtracts two Problem: CTRL-X on 2**64 subtracts two. (James McCoy) Solution: Correct computation for large number. (closes #12103) --- src/charset.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'src/charset.c') 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; } } -- cgit v1.2.3