diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-01-02 12:45:29 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-01-02 20:28:27 +0900 |
| commit | c1f05a7fb3e15acbe8bce0789af505a2b6a5876a (patch) | |
| tree | 8d271b7b7c11e1b9aa831f207a824629cd8e840f /src/string.c | |
| parent | 4ac73307fdf7996484378fdd6e09c02e5e7efbdc (diff) | |
| download | mruby-c1f05a7fb3e15acbe8bce0789af505a2b6a5876a.tar.gz mruby-c1f05a7fb3e15acbe8bce0789af505a2b6a5876a.zip | |
Avoid `uint64_t` in string-to-integer conversion; ref #5201
Diffstat (limited to 'src/string.c')
| -rw-r--r-- | src/string.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/src/string.c b/src/string.c index 4e8bd7835..749d32698 100644 --- a/src/string.c +++ b/src/string.c @@ -2216,7 +2216,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, mrb_int base, i const char *pend = str + len; char sign = 1; int c; - uint64_t n = 0; + mrb_int n = 0; mrb_int val; #define conv_digit(c) \ @@ -2343,15 +2343,17 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, mrb_int base, i if (c < 0 || c >= base) { break; } - n *= base; - n += c; - if (n > (uint64_t)MRB_INT_MAX) { - if (sign == 0 && n == (uint64_t)MRB_INT_MIN) { + if (mrb_int_mul_overflow(n, base, &n)) goto overflow; + if (MRB_INT_MAX - c < n) { + if (sign == 0 && MRB_INT_MAX - n == c - 1) { + n = MRB_INT_MIN; sign = 1; break; } + overflow: mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str); } + n += c; } val = (mrb_int)n; if (badcheck) { |
