diff options
author | Darren Tucker <dtucker@zip.com.au> | 2017-03-29 16:34:44 +1100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2017-03-29 16:34:44 +1100 |
commit | 282cad2240c4fbc104c2f2df86d688192cbbe4bb (patch) | |
tree | a2e61d6dc484e0dcaa477919984bce71afbd20fd | |
parent | c73a229e4edf98920f395e19fd310684fc6bb951 (diff) |
Import fmt_scaled.c rev 1.16 from OpenBSD.
Fix overly-conservative overflow checks on mulitplications and add checks
on additions. This allows scan_scaled to work up to +/-LLONG_MAX (LLONG_MIN
will still be flagged as a range error). ok millert@
-rw-r--r-- | openbsd-compat/fmt_scaled.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c index 8af866016..7c5193e26 100644 --- a/openbsd-compat/fmt_scaled.c +++ b/openbsd-compat/fmt_scaled.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: fmt_scaled.c,v 1.15 2017/03/15 05:25:56 dtucker Exp $ */ | 1 | /* $OpenBSD: fmt_scaled.c,v 1.16 2017/03/16 02:40:46 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved. | 4 | * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved. |
@@ -125,22 +125,30 @@ scan_scaled(char *scaled, long long *result) | |||
125 | /* ignore extra fractional digits */ | 125 | /* ignore extra fractional digits */ |
126 | continue; | 126 | continue; |
127 | fract_digits++; /* for later scaling */ | 127 | fract_digits++; /* for later scaling */ |
128 | if (fpart >= LLONG_MAX / 10) { | 128 | if (fpart > LLONG_MAX / 10) { |
129 | errno = ERANGE; | 129 | errno = ERANGE; |
130 | return -1; | 130 | return -1; |
131 | } | 131 | } |
132 | fpart *= 10; | 132 | fpart *= 10; |
133 | if (i > LLONG_MAX - fpart) { | ||
134 | errno = ERANGE; | ||
135 | return -1; | ||
136 | } | ||
133 | fpart += i; | 137 | fpart += i; |
134 | } else { /* normal digit */ | 138 | } else { /* normal digit */ |
135 | if (++ndigits >= MAX_DIGITS) { | 139 | if (++ndigits >= MAX_DIGITS) { |
136 | errno = ERANGE; | 140 | errno = ERANGE; |
137 | return -1; | 141 | return -1; |
138 | } | 142 | } |
139 | if (whole >= LLONG_MAX / 10) { | 143 | if (whole > LLONG_MAX / 10) { |
140 | errno = ERANGE; | 144 | errno = ERANGE; |
141 | return -1; | 145 | return -1; |
142 | } | 146 | } |
143 | whole *= 10; | 147 | whole *= 10; |
148 | if (i > LLONG_MAX - whole) { | ||
149 | errno = ERANGE; | ||
150 | return -1; | ||
151 | } | ||
144 | whole += i; | 152 | whole += i; |
145 | } | 153 | } |
146 | } | 154 | } |