aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
authorGavin Howard <yzena.tech@gmail.com>2019-03-16 14:52:19 -0600
committerRob Landley <rob@landley.net>2019-03-16 20:08:32 -0500
commita7cecf3bbf0901cfe34b2f13a763fef27b051dbd (patch)
tree08672e5ef7d1219fc657f7a3f45d45df7be84776 /toys
parent21287daef23e8ca6acd60af8b997ae119095dbc0 (diff)
downloadtoybox-a7cecf3bbf0901cfe34b2f13a763fef27b051dbd.tar.gz
bc: fix an overflow bug in bc_num_ulong()
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/bc.c15
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;