aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/charset.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/charset.c')
-rw-r--r--src/nvim/charset.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 5a0590d075..403ef65c4f 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -981,10 +981,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
mb_ptr_adv(s);
c = *s;
- if (!((c != NUL)
- && (vim_isbreak(c)
- || (!vim_isbreak(c)
- && ((col2 == col) || !vim_isbreak(*ps)))))) {
+ if (!(c != NUL
+ && (vim_isbreak(c) || col2 == col || !vim_isbreak(*ps)))) {
break;
}
@@ -1621,13 +1619,13 @@ bool vim_isblankline(char_u *lbuf)
/// @param unptr Returns the unsigned result.
/// @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, long *const nptr, unsigned long *const unptr,
- const int maxlen)
+ const int what, varnumber_T *const nptr,
+ uvarnumber_T *const unptr, const int maxlen)
{
const char_u *ptr = start;
int pre = 0; // default is decimal
bool negative = false;
- unsigned long un = 0;
+ uvarnumber_T un = 0;
if (ptr[0] == '-') {
negative = true;
@@ -1683,7 +1681,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
n += 2; // skip over "0b"
}
while ('0' <= *ptr && *ptr <= '1') {
- un = 2 * un + (unsigned long)(*ptr - '0');
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 2) {
+ un = 2 * un + (uvarnumber_T)(*ptr - '0');
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1692,7 +1695,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
} else if ((pre == '0') || what == STR2NR_OCT + STR2NR_FORCE) {
// octal
while ('0' <= *ptr && *ptr <= '7') {
- un = 8 * un + (unsigned long)(*ptr - '0');
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 8) {
+ un = 8 * un + (uvarnumber_T)(*ptr - '0');
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1705,7 +1713,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
n += 2; // skip over "0x"
}
while (ascii_isxdigit(*ptr)) {
- un = 16 * un + (unsigned long)hex2nr(*ptr);
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 16) {
+ un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1714,7 +1727,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
} else {
// decimal
while (ascii_isdigit(*ptr)) {
- un = 10 * un + (unsigned long)(*ptr - '0');
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 10) {
+ un = 10 * un + (uvarnumber_T)(*ptr - '0');
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1731,11 +1749,18 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
}
if (nptr != NULL) {
- if (negative) {
- // account for leading '-' for decimal numbers
- *nptr = -(long)un;
+ if (negative) { // account for leading '-' for decimal numbers
+ // avoid ubsan error for overflow
+ if (un > VARNUMBER_MAX) {
+ *nptr = VARNUMBER_MIN;
+ } else {
+ *nptr = -(varnumber_T)un;
+ }
} else {
- *nptr = (long)un;
+ if (un > VARNUMBER_MAX) {
+ un = VARNUMBER_MAX;
+ }
+ *nptr = (varnumber_T)un;
}
}