aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/charset.c60
1 files changed, 21 insertions, 39 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index f824717fcd..7b307b8160 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1620,13 +1620,16 @@ bool vim_isblankline(char_u *lbuf)
/// @param maxlen Max length of string to check.
void vim_str2nr(const char_u *const start, int *const prep, int *const len,
const int what, varnumber_T *const nptr,
- uvarnumber_T *const unptr, const int maxlen)
+ uvarnumber_T *const unptr, int maxlen)
FUNC_ATTR_NONNULL_ARG(1)
{
- const char_u *ptr = start;
+ const char *ptr = (const char *)start;
+ if (maxlen == 0) {
+ maxlen = (int)strlen(ptr);
+ }
+ const char *const e = ptr + maxlen;
int pre = 0; // default is decimal
bool negative = false;
- uvarnumber_T un = 0;
if (ptr[0] == '-') {
negative = true;
@@ -1635,19 +1638,19 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
// Recognize hex, octal and bin.
if ((what & (STR2NR_HEX|STR2NR_OCT|STR2NR_BIN))
- && (maxlen == 0 || maxlen > 1)
- && (ptr[0] == '0') && (ptr[1] != '8') && (ptr[1] != '9')) {
+ && maxlen > 1
+ && ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9') {
pre = ptr[1];
if ((what & STR2NR_HEX)
- && (maxlen == 0 || maxlen > 2)
- && ((pre == 'X') || (pre == 'x'))
+ && maxlen > 2
+ && (pre == 'X' || pre == 'x')
&& ascii_isxdigit(ptr[2])) {
// hexadecimal
ptr += 2;
} else if ((what & STR2NR_BIN)
- && (maxlen == 0 || maxlen > 2)
- && ((pre == 'B') || (pre == 'b'))
+ && maxlen > 2
+ && (pre == 'B' || pre == 'b')
&& ascii_isbdigit(ptr[2])) {
// binary
ptr += 2;
@@ -1657,32 +1660,26 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
if (what & STR2NR_OCT) {
// Don't interpret "0", "08" or "0129" as octal.
- for (int n = 1; ascii_isdigit(ptr[n]); ++n) {
- if (ptr[n] > '7') {
+ for (int i = 1; i < maxlen && ascii_isdigit(ptr[i]); i++) {
+ if (ptr[i] > '7') {
// can't be octal
pre = 0;
break;
}
- if (ptr[n] >= '0') {
+ if (ptr[i] >= '0') {
// assume octal
pre = '0';
}
- if (n == maxlen) {
- break;
- }
}
}
}
}
// Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
- int n = 1;
+ uvarnumber_T un = 0;
if (pre == 'B' || pre == 'b' || what == (STR2NR_BIN|STR2NR_FORCE)) {
// bin
- if (pre != 0) {
- n += 2; // skip over "0b"
- }
- while ('0' <= *ptr && *ptr <= '1') {
+ while (ptr < e && '0' <= *ptr && *ptr <= '1') {
// avoid ubsan error for overflow
if (un < UVARNUMBER_MAX / 2) {
un = 2 * un + (uvarnumber_T)(*ptr - '0');
@@ -1690,13 +1687,10 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
un = UVARNUMBER_MAX;
}
ptr++;
- if (n++ == maxlen) {
- break;
- }
}
} else if (pre == '0' || what == (STR2NR_OCT|STR2NR_FORCE)) {
// octal
- while ('0' <= *ptr && *ptr <= '7') {
+ while (ptr < e && '0' <= *ptr && *ptr <= '7') {
// avoid ubsan error for overflow
if (un < UVARNUMBER_MAX / 8) {
un = 8 * un + (uvarnumber_T)(*ptr - '0');
@@ -1704,16 +1698,10 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
un = UVARNUMBER_MAX;
}
ptr++;
- if (n++ == maxlen) {
- break;
- }
}
} else if (pre == 'X' || pre == 'x' || what == (STR2NR_HEX|STR2NR_FORCE)) {
// hex
- if (pre != 0) {
- n += 2; // skip over "0x"
- }
- while (ascii_isxdigit(*ptr)) {
+ while (ptr < e && ascii_isxdigit(*ptr)) {
// avoid ubsan error for overflow
if (un < UVARNUMBER_MAX / 16) {
un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
@@ -1721,13 +1709,10 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
un = UVARNUMBER_MAX;
}
ptr++;
- if (n++ == maxlen) {
- break;
- }
}
} else {
// decimal
- while (ascii_isdigit(*ptr)) {
+ while (ptr < e && ascii_isdigit(*ptr)) {
// avoid ubsan error for overflow
if (un < UVARNUMBER_MAX / 10) {
un = 10 * un + (uvarnumber_T)(*ptr - '0');
@@ -1735,9 +1720,6 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
un = UVARNUMBER_MAX;
}
ptr++;
- if (n++ == maxlen) {
- break;
- }
}
}
@@ -1746,7 +1728,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
}
if (len != NULL) {
- *len = (int)(ptr - start);
+ *len = (int)(ptr - (const char *)start);
}
if (nptr != NULL) {