1 diff -Nrup a/stdlib/Makefile b/stdlib/Makefile
2 --- a/stdlib/Makefile 2010-05-04 05:27:23.000000000 -0600
3 +++ b/stdlib/Makefile 2012-08-15 09:25:37.812443006 -0600
4 @@ -71,7 +71,7 @@ tests := tst-strtol tst-strtod testmb t
5 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
6 tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \
7 tst-makecontext2 tst-strtod6 tst-unsetenv1 \
9 + tst-makecontext3 tst-strtod-overflow
13 diff -Nrup a/stdlib/strtod_l.c b/stdlib/strtod_l.c
14 --- a/stdlib/strtod_l.c 2010-05-04 05:27:23.000000000 -0600
15 +++ b/stdlib/strtod_l.c 2012-08-15 09:34:29.550281346 -0600
16 @@ -62,6 +62,7 @@ extern unsigned long long int ____strtou
22 /* The gmp headers need some configuration frobs. */
24 @@ -176,19 +177,19 @@ extern const mp_limb_t _tens_in_limb[MAX
25 /* Return a floating point number of the needed type according to the given
26 multi-precision number after possible rounding. */
28 -round_and_return (mp_limb_t *retval, int exponent, int negative,
29 +round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
30 mp_limb_t round_limb, mp_size_t round_bit, int more_bits)
32 if (exponent < MIN_EXP - 1)
34 - mp_size_t shift = MIN_EXP - 1 - exponent;
36 - if (shift > MANT_DIG)
37 + if (exponent < MIN_EXP - 1 - MANT_DIG)
43 + mp_size_t shift = MIN_EXP - 1 - exponent;
45 more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0;
46 if (shift == MANT_DIG)
47 /* This is a special case to handle the very seldom case where
48 @@ -235,6 +236,9 @@ round_and_return (mp_limb_t *retval, int
52 + if (exponent > MAX_EXP)
55 if ((round_limb & (((mp_limb_t) 1) << round_bit)) != 0
56 && (more_bits || (retval[0] & 1) != 0
57 || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0))
58 @@ -260,6 +264,7 @@ round_and_return (mp_limb_t *retval, int
61 if (exponent > MAX_EXP)
63 return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
65 return MPN2FLOAT (retval, exponent, negative);
66 @@ -273,7 +278,7 @@ round_and_return (mp_limb_t *retval, int
67 factor for the resulting number (see code) multiply by it. */
68 static const STRING_TYPE *
69 str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
73 , const char *decimal, size_t decimal_len, const char *thousands
75 @@ -337,7 +342,7 @@ str_to_mpn (const STRING_TYPE *str, int
79 - if (*exponent > 0 && cnt + *exponent <= MAX_DIG_PER_LIMB)
80 + if (*exponent > 0 && *exponent <= MAX_DIG_PER_LIMB - cnt)
82 low *= _tens_in_limb[*exponent];
83 start = _tens_in_limb[cnt + *exponent];
84 @@ -415,7 +420,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
86 int negative; /* The sign of the number. */
87 MPN_VAR (num); /* MP representation of the number. */
88 - int exponent; /* Exponent of the number. */
89 + intmax_t exponent; /* Exponent of the number. */
91 /* Numbers starting `0X' or `0x' have to be processed with base 16. */
93 @@ -437,7 +442,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
94 /* Points at the character following the integer and fractional digits. */
95 const STRING_TYPE *expp;
96 /* Total number of digit and number of digits in integer part. */
97 - int dig_no, int_no, lead_zero;
98 + size_t dig_no, int_no, lead_zero;
99 /* Contains the last character read. */
102 @@ -769,7 +774,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
103 are all or any is really a fractional digit will be decided
106 - lead_zero = int_no == 0 ? -1 : 0;
107 + lead_zero = int_no == 0 ? (size_t) -1 : 0;
109 /* Read the fractional digits. A special case are the 'american
110 style' numbers like `16.' i.e. with decimal point but without
111 @@ -791,12 +796,13 @@ ____STRTOF_INTERNAL (nptr, endptr, group
112 (base == 16 && ({ CHAR_TYPE lo = TOLOWER (c);
113 lo >= L_('a') && lo <= L_('f'); })))
115 - if (c != L_('0') && lead_zero == -1)
116 + if (c != L_('0') && lead_zero == (size_t) -1)
117 lead_zero = dig_no - int_no;
122 + assert (dig_no <= (uintmax_t) INTMAX_MAX);
124 /* Remember start of exponent (if any). */
126 @@ -819,24 +825,80 @@ ____STRTOF_INTERNAL (nptr, endptr, group
128 if (c >= L_('0') && c <= L_('9'))
131 + intmax_t exp_limit;
133 /* Get the exponent limit. */
135 - exp_limit = (exp_negative ?
136 - -MIN_EXP + MANT_DIG + 4 * int_no :
137 - MAX_EXP - 4 * int_no + 4 * lead_zero + 3);
141 + assert (int_no <= (uintmax_t) (INTMAX_MAX
142 + + MIN_EXP - MANT_DIG) / 4);
143 + exp_limit = -MIN_EXP + MANT_DIG + 4 * (intmax_t) int_no;
149 + assert (lead_zero == 0
150 + && int_no <= (uintmax_t) INTMAX_MAX / 4);
151 + exp_limit = MAX_EXP - 4 * (intmax_t) int_no + 3;
153 + else if (lead_zero == (size_t) -1)
155 + /* The number is zero and this limit is
157 + exp_limit = MAX_EXP + 3;
162 + <= (uintmax_t) (INTMAX_MAX - MAX_EXP - 3) / 4);
163 + exp_limit = (MAX_EXP
164 + + 4 * (intmax_t) lead_zero
170 - exp_limit = (exp_negative ?
171 - -MIN_10_EXP + MANT_DIG + int_no :
172 - MAX_10_EXP - int_no + lead_zero + 1);
177 + <= (uintmax_t) (INTMAX_MAX + MIN_10_EXP - MANT_DIG));
178 + exp_limit = -MIN_10_EXP + MANT_DIG + (intmax_t) int_no;
184 + assert (lead_zero == 0
185 + && int_no <= (uintmax_t) INTMAX_MAX);
186 + exp_limit = MAX_10_EXP - (intmax_t) int_no + 1;
188 + else if (lead_zero == (size_t) -1)
190 + /* The number is zero and this limit is
192 + exp_limit = MAX_10_EXP + 1;
197 + <= (uintmax_t) (INTMAX_MAX - MAX_10_EXP - 1));
198 + exp_limit = MAX_10_EXP + (intmax_t) lead_zero + 1;
209 - exponent += c - L_('0');
211 - if (__builtin_expect (exponent > exp_limit, 0))
212 + if (__builtin_expect ((exponent > exp_limit / 10
213 + || (exponent == exp_limit / 10
214 + && c - L_('0') > exp_limit % 10)), 0))
215 /* The exponent is too large/small to represent a valid
218 @@ -845,7 +907,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
219 /* We have to take care for special situation: a joker
220 might have written "0.0e100000" which is in fact
222 - if (lead_zero == -1)
223 + if (lead_zero == (size_t) -1)
224 result = negative ? -0.0 : 0.0;
227 @@ -864,6 +926,9 @@ ____STRTOF_INTERNAL (nptr, endptr, group
232 + exponent += c - L_('0');
236 while (c >= L_('0') && c <= L_('9'));
237 @@ -932,7 +997,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group
240 startp += lead_zero + decimal_len;
241 - exponent -= base == 16 ? 4 * lead_zero : lead_zero;
242 + assert (lead_zero <= (base == 16
243 + ? (uintmax_t) INTMAX_MAX / 4
244 + : (uintmax_t) INTMAX_MAX));
245 + assert (lead_zero <= (base == 16
246 + ? ((uintmax_t) exponent
247 + - (uintmax_t) INTMAX_MIN) / 4
248 + : ((uintmax_t) exponent - (uintmax_t) INTMAX_MIN)));
249 + exponent -= base == 16 ? 4 * (intmax_t) lead_zero : (intmax_t) lead_zero;
253 @@ -974,7 +1046,10 @@ ____STRTOF_INTERNAL (nptr, endptr, group
256 /* Adjust the exponent for the bits we are shifting in. */
257 - exponent += bits - 1 + (int_no - 1) * 4;
258 + assert (int_no <= (uintmax_t) (exponent < 0
259 + ? (INTMAX_MAX - bits + 1) / 4
260 + : (INTMAX_MAX - exponent - bits + 1) / 4));
261 + exponent += bits - 1 + ((intmax_t) int_no - 1) * 4;
263 while (--dig_no > 0 && idx >= 0)
265 @@ -1014,13 +1089,15 @@ ____STRTOF_INTERNAL (nptr, endptr, group
266 really integer digits or belong to the fractional part; i.e. we normalize
269 - register int incr = (exponent < 0 ? MAX (-int_no, exponent)
270 - : MIN (dig_no - int_no, exponent));
271 + register intmax_t incr = (exponent < 0
272 + ? MAX (-(intmax_t) int_no, exponent)
273 + : MIN ((intmax_t) dig_no - (intmax_t) int_no,
279 - if (__builtin_expect (int_no + exponent > MAX_10_EXP + 1, 0))
280 + if (__builtin_expect (exponent > MAX_10_EXP + 1 - (intmax_t) int_no, 0))
282 __set_errno (ERANGE);
283 return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
284 @@ -1205,7 +1282,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
285 digits we should have enough bits for the result. The remaining
286 decimal digits give us the information that more bits are following.
287 This can be used while rounding. (Two added as a safety margin.) */
288 - if (dig_no - int_no > (MANT_DIG - bits + 2) / 3 + 2)
289 + if ((intmax_t) dig_no > (intmax_t) int_no + (MANT_DIG - bits + 2) / 3 + 2)
291 dig_no = int_no + (MANT_DIG - bits + 2) / 3 + 2;
293 @@ -1213,7 +1290,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
297 - neg_exp = dig_no - int_no - exponent;
298 + neg_exp = (intmax_t) dig_no - (intmax_t) int_no - exponent;
300 /* Construct the denominator. */
302 @@ -1491,7 +1568,9 @@ ____STRTOF_INTERNAL (nptr, endptr, group
304 (void) __mpn_lshift (&retval[used
306 - retval, RETURN_LIMB_SIZE,
309 + - used / BITS_PER_MP_LIMB),
310 used % BITS_PER_MP_LIMB);
311 for (i = used / BITS_PER_MP_LIMB - 1; i >= 0; --i)
313 diff -Nrup a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
314 --- a/stdlib/tst-strtod-overflow.c 1969-12-31 17:00:00.000000000 -0700
315 +++ b/stdlib/tst-strtod-overflow.c 2012-08-15 09:25:01.098592764 -0600
317 +/* Test for integer/buffer overflow in strtod.
318 + Copyright (C) 2012 Free Software Foundation, Inc.
319 + This file is part of the GNU C Library.
321 + The GNU C Library is free software; you can redistribute it and/or
322 + modify it under the terms of the GNU Lesser General Public
323 + License as published by the Free Software Foundation; either
324 + version 2.1 of the License, or (at your option) any later version.
326 + The GNU C Library is distributed in the hope that it will be useful,
327 + but WITHOUT ANY WARRANTY; without even the implied warranty of
328 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
329 + Lesser General Public License for more details.
331 + You should have received a copy of the GNU Lesser General Public
332 + License along with the GNU C Library; if not, see
333 + <http://www.gnu.org/licenses/>. */
339 +#define EXPONENT "e-2147483649"
340 +#define SIZE 214748364
345 + char *p = malloc (1 + SIZE + sizeof (EXPONENT));
348 + puts ("malloc failed, cannot test for overflow");
352 + memset (p + 1, '0', SIZE);
353 + memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT));
354 + double d = strtod (p, NULL);
357 + printf ("strtod returned wrong value: %a\n", d);
363 +#define TEST_FUNCTION do_test ()
364 +#include "../test-skeleton.c"