diff options
author | ZyX <kp-pav@yandex.ru> | 2017-10-15 21:09:08 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2017-10-15 21:09:08 +0300 |
commit | bc386c48829c431fe5b17592c82eb4099621953a (patch) | |
tree | feeac8b37e71251c56f66b9457ff5ccfab188e60 | |
parent | 57bb3346d95f325d4894d41c88d3a1434de2d2df (diff) | |
download | rneovim-bc386c48829c431fe5b17592c82eb4099621953a.tar.gz rneovim-bc386c48829c431fe5b17592c82eb4099621953a.tar.bz2 rneovim-bc386c48829c431fe5b17592c82eb4099621953a.zip |
charset: Fix out-of-bounds array access
It is incorrect to *first* access ptr[2] and *then* check whether maxlen allows
it.
-rw-r--r-- | src/nvim/charset.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 403ef65c4f..1147b78c9a 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1621,6 +1621,7 @@ bool vim_isblankline(char_u *lbuf) 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) + FUNC_ATTR_NONNULL_ARG(1) { const char_u *ptr = start; int pre = 0; // default is decimal @@ -1633,20 +1634,21 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, } // Recognize hex, octal and bin. - if ((ptr[0] == '0') && (ptr[1] != '8') && (ptr[1] != '9') - && (maxlen == 0 || maxlen > 1)) { + if ((what & (STR2NR_HEX|STR2NR_OCT|STR2NR_BIN)) + && (maxlen == 0 || 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')) - && ascii_isxdigit(ptr[2]) - && (maxlen == 0 || maxlen > 2)) { + && ascii_isxdigit(ptr[2])) { // hexadecimal ptr += 2; } else if ((what & STR2NR_BIN) + && (maxlen == 0 || maxlen > 2) && ((pre == 'B') || (pre == 'b')) - && ascii_isbdigit(ptr[2]) - && (maxlen == 0 || maxlen > 2)) { + && ascii_isbdigit(ptr[2])) { // binary ptr += 2; } else { @@ -1675,7 +1677,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, // Do the string-to-numeric conversion "manually" to avoid sscanf quirks. int n = 1; - if ((pre == 'B') || (pre == 'b') || what == STR2NR_BIN + STR2NR_FORCE) { + if (pre == 'B' || pre == 'b' || what == (STR2NR_BIN|STR2NR_FORCE)) { // bin if (pre != 0) { n += 2; // skip over "0b" @@ -1692,7 +1694,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, break; } } - } else if ((pre == '0') || what == STR2NR_OCT + STR2NR_FORCE) { + } else if (pre == '0' || what == (STR2NR_OCT|STR2NR_FORCE)) { // octal while ('0' <= *ptr && *ptr <= '7') { // avoid ubsan error for overflow @@ -1706,8 +1708,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, break; } } - } else if ((pre == 'X') || (pre == 'x') - || what == STR2NR_HEX + STR2NR_FORCE) { + } else if (pre == 'X' || pre == 'x' || what == (STR2NR_HEX|STR2NR_FORCE)) { // hex if (pre != 0) { n += 2; // skip over "0x" |