diff options
author | ZyX <kp-pav@yandex.ru> | 2017-10-29 01:40:55 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2017-10-29 01:40:55 +0300 |
commit | 06bdc9ed839eedbead34d58214927d3c0cebff58 (patch) | |
tree | ab3d6b3e81fa69985be9eefb68610bc27a2858d8 | |
parent | c202f17c8d8cb2140aa1b21b2e2d2ab3925a7812 (diff) | |
download | rneovim-06bdc9ed839eedbead34d58214927d3c0cebff58.tar.gz rneovim-06bdc9ed839eedbead34d58214927d3c0cebff58.tar.bz2 rneovim-06bdc9ed839eedbead34d58214927d3c0cebff58.zip |
klee: Update vim_str2nr in mock as well
-rw-r--r-- | test/symbolic/klee/nvim/charset.c | 78 |
1 files changed, 30 insertions, 48 deletions
diff --git a/test/symbolic/klee/nvim/charset.c b/test/symbolic/klee/nvim/charset.c index c584bd72ef..f3a218949f 100644 --- a/test/symbolic/klee/nvim/charset.c +++ b/test/symbolic/klee/nvim/charset.c @@ -60,18 +60,19 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, // decimal or octal, default is decimal pre = 0; - if (what & STR2NR_OCT) { - // Don't interpret "0", "08" or "0129" as octal. - for (int i = 1; !STRING_ENDED(ptr + i) && ascii_isdigit(ptr[i]); i++) { + if (what & STR2NR_OCT + && !STRING_ENDED(ptr + 1) + && ('0' <= ptr[1] && ptr[1] <= '7')) { + // Assume octal now: what we already know is that string starts with + // zero and some octal digit. + pre = '0'; + // Don’t interpret "0", "008" or "0129" as octal. + for (int i = 2; !STRING_ENDED(ptr + i) && ascii_isdigit(ptr[i]); i++) { if (ptr[i] > '7') { - // can't be octal + // Can’t be octal. pre = 0; break; } - if (ptr[i] >= '0') { - // assume octal - pre = '0'; - } } } } @@ -79,51 +80,32 @@ 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. uvarnumber_T un = 0; +#define PARSE_NUMBER(base, cond, conv) \ + do { \ + while (!STRING_ENDED(ptr) && (cond)) { \ + /* avoid ubsan error for overflow */ \ + if (un < UVARNUMBER_MAX / base) { \ + un = base * un + (uvarnumber_T)(conv); \ + } else { \ + un = UVARNUMBER_MAX; \ + } \ + ptr++; \ + } \ + } while (0) if (pre == 'B' || pre == 'b' || what == (STR2NR_BIN|STR2NR_FORCE)) { - // bin - while (!STRING_ENDED(ptr) && '0' <= *ptr && *ptr <= '1') { - // avoid ubsan error for overflow - if (un < UVARNUMBER_MAX / 2) { - un = 2 * un + (uvarnumber_T)(*ptr - '0'); - } else { - un = UVARNUMBER_MAX; - } - ptr++; - } + // Binary number. + PARSE_NUMBER(2, (*ptr == '0' || *ptr == '1'), (*ptr - '0')); } else if (pre == '0' || what == (STR2NR_OCT|STR2NR_FORCE)) { - // octal - while (!STRING_ENDED(ptr) && '0' <= *ptr && *ptr <= '7') { - // avoid ubsan error for overflow - if (un < UVARNUMBER_MAX / 8) { - un = 8 * un + (uvarnumber_T)(*ptr - '0'); - } else { - un = UVARNUMBER_MAX; - } - ptr++; - } + // Octal number. + PARSE_NUMBER(8, ('0' <= *ptr && *ptr <= '7'), (*ptr - '0')); } else if (pre == 'X' || pre == 'x' || what == (STR2NR_HEX|STR2NR_FORCE)) { - // hex - while (!STRING_ENDED(ptr) && ascii_isxdigit(*ptr)) { - // avoid ubsan error for overflow - if (un < UVARNUMBER_MAX / 16) { - un = 16 * un + (uvarnumber_T)hex2nr(*ptr); - } else { - un = UVARNUMBER_MAX; - } - ptr++; - } + // Hexadecimal number. + PARSE_NUMBER(16, (ascii_isxdigit(*ptr)), (hex2nr(*ptr))); } else { - // decimal - while (!STRING_ENDED(ptr) && ascii_isdigit(*ptr)) { - // avoid ubsan error for overflow - if (un < UVARNUMBER_MAX / 10) { - un = 10 * un + (uvarnumber_T)(*ptr - '0'); - } else { - un = UVARNUMBER_MAX; - } - ptr++; - } + // Decimal number. + PARSE_NUMBER(10, (ascii_isdigit(*ptr)), (*ptr - '0')); } +#undef PARSE_NUMBER if (prep != NULL) { *prep = pre; |