diff options
author | Gavin Howard <yzena.tech@gmail.com> | 2019-03-16 14:52:19 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-03-16 20:08:32 -0500 |
commit | a7cecf3bbf0901cfe34b2f13a763fef27b051dbd (patch) | |
tree | 08672e5ef7d1219fc657f7a3f45d45df7be84776 | |
parent | 21287daef23e8ca6acd60af8b997ae119095dbc0 (diff) | |
download | toybox-a7cecf3bbf0901cfe34b2f13a763fef27b051dbd.tar.gz |
bc: fix an overflow bug in bc_num_ulong()
-rw-r--r-- | toys/pending/bc.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/toys/pending/bc.c b/toys/pending/bc.c index 614cae70..142c0ce2 100644 --- a/toys/pending/bc.c +++ b/toys/pending/bc.c @@ -2120,21 +2120,22 @@ BcStatus bc_num_parse(BcNum *n, char *val, BcStatus bc_num_ulong(BcNum *n, unsigned long *result) { size_t i; - unsigned long pow, r; + unsigned long r; *result = 0; if (n->neg) return bc_vm_err(BC_ERROR_MATH_NEGATIVE); - for (r = 0, pow = 1, i = n->rdx; i < n->len; ++i) { + for (r = 0, i = n->len; i > n->rdx;) { - unsigned long prev = r, powprev = pow; + unsigned long prev = r * 10; - r += ((unsigned long) n->num[i]) * pow; - pow *= 10; + if (prev == SIZE_MAX || prev / 10 != r) + return bc_vm_err(BC_ERROR_MATH_OVERFLOW); - if (r < prev || pow < powprev) - return bc_vm_verr(BC_ERROR_MATH_OVERFLOW, "number cannot fit"); + r = prev + ((uchar) n->num[--i]); + + if (r == SIZE_MAX || r < prev) return bc_vm_err(BC_ERROR_MATH_OVERFLOW); } *result = r; |