]> git.saurik.com Git - apple/libc.git/blob - gdtoa/FreeBSD/gdtoa-gethex.c.patch
655851b46bf93810769d55a246f7863405c74d7b
[apple/libc.git] / gdtoa / FreeBSD / gdtoa-gethex.c.patch
1 --- gdtoa-gethex.c.orig 2010-02-24 20:50:10.000000000 -0800
2 +++ gdtoa-gethex.c 2010-02-24 21:26:32.000000000 -0800
3 @@ -29,34 +29,40 @@ THIS SOFTWARE.
4 /* Please send bug reports to David M. Gay (dmg at acm dot org,
5 * with " at " changed at "@" and " dot " changed to "."). */
6
7 +#include "xlocale_private.h"
8 +
9 #include "gdtoaimp.h"
10
11 +#include <sys/types.h>
12 +
13 #ifdef USE_LOCALE
14 #include "locale.h"
15 #endif
16
17 int
18 #ifdef KR_headers
19 -gethex(sp, fpi, exp, bp, sign)
20 - CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign;
21 +gethex(sp, fpi, exp, bp, sign, loc)
22 + CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; locale_t loc;
23 #else
24 -gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
25 +gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t loc)
26 #endif
27 {
28 Bigint *b;
29 CONST unsigned char *decpt, *s0, *s, *s1;
30 + unsigned char *strunc;
31 int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret;
32 ULong L, lostbits, *x;
33 Long e, e1;
34 #ifdef USE_LOCALE
35 int i;
36 + NORMALIZE_LOCALE(loc);
37 #ifdef NO_LOCALE_CACHE
38 - const unsigned char *decimalpoint = (unsigned char*)localeconv()->decimal_point;
39 + const unsigned char *decimalpoint = (unsigned char*)localeconv_l(loc)->decimal_point;
40 #else
41 const unsigned char *decimalpoint;
42 static unsigned char *decimalpoint_cache;
43 if (!(s0 = decimalpoint_cache)) {
44 - s0 = (unsigned char*)localeconv()->decimal_point;
45 + s0 = (unsigned char*)localeconv_l(loc)->decimal_point;
46 if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
47 strcpy(decimalpoint_cache, s0);
48 s0 = decimalpoint_cache;
49 @@ -198,6 +204,57 @@ gethex( CONST char **sp, FPI *fpi, Long
50 *exp = fpi->emin;
51 return STRTOG_Normal | STRTOG_Inexlo;
52 }
53 + /*
54 + * Truncate the hex string if it is longer than the precision needed,
55 + * to avoid denial-of-service issues with very large strings. Use
56 + * additional digits to insure precision. Scan to-be-truncated digits
57 + * and replace with either '1' or '0' to ensure proper rounding.
58 + */
59 + {
60 + int maxdigits = ((fpi->nbits + 3) >> 2) + 2;
61 + size_t nd = s1 - s0;
62 +#ifdef USE_LOCALE
63 + int dplen = strlen((const char *)decimalpoint);
64 +#else
65 + int dplen = 1;
66 +#endif
67 +
68 + if (decpt && s0 < decpt)
69 + nd -= dplen;
70 + if (nd > maxdigits && (strunc = alloca(maxdigits + dplen + 2)) != NULL) {
71 + ssize_t nd0 = decpt ? decpt - s0 - dplen : nd;
72 + unsigned char *tp = strunc + maxdigits;
73 + int found = 0;
74 + if ((nd0 -= maxdigits) >= 0 || s0 >= decpt)
75 + memcpy(strunc, s0, maxdigits);
76 + else {
77 + memcpy(strunc, s0, maxdigits + dplen);
78 + tp += dplen;
79 + }
80 + s0 += maxdigits;
81 + e += (nd - (maxdigits + 1)) << 2;
82 + if (nd0 > 0) {
83 + while(nd0-- > 0)
84 + if (*s0++ != '0') {
85 + found++;
86 + break;
87 + }
88 + s0 += dplen;
89 + }
90 + if (!found && decpt) {
91 + while(s0 < s1)
92 + if(*s0++ != '0') {
93 + found++;
94 + break;
95 + }
96 + }
97 + *tp++ = found ? '1' : '0';
98 + *tp = 0;
99 + s0 = strunc;
100 + s1 = tp;
101 + }
102 + }
103 +
104 n = s1 - s0 - 1;
105 for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
106 k++;