1 /* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2018 Free Software
2    Foundation, Inc.
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16 
17 #include <config.h>
18 
19 #include <stdlib.h>
20 
21 #include <ctype.h>
22 #include <errno.h>
23 #include <float.h>
24 #include <limits.h>
25 #include <math.h>
26 #include <stdbool.h>
27 #include <string.h>
28 
29 #include "c-ctype.h"
30 
31 #ifndef HAVE_LDEXP_IN_LIBC
32 #define HAVE_LDEXP_IN_LIBC 0
33 #endif
34 
35 /* Return true if C is a space in the current locale, avoiding
36    problems with signed char and isspace.  */
37 static bool
locale_isspace(char c)38 locale_isspace (char c)
39 {
40   unsigned char uc = c;
41   return isspace (uc) != 0;
42 }
43 
44 #if !HAVE_LDEXP_IN_LIBC
45  #define ldexp dummy_ldexp
46  /* A dummy definition that will never be invoked.  */
ldexp(double x _GL_UNUSED,int exponent _GL_UNUSED)47  static double ldexp (double x _GL_UNUSED, int exponent _GL_UNUSED)
48  {
49    abort ();
50    return 0.0;
51  }
52 #endif
53 
54 /* Return X * BASE**EXPONENT.  Return an extreme value and set errno
55    to ERANGE if underflow or overflow occurs.  */
56 static double
scale_radix_exp(double x,int radix,long int exponent)57 scale_radix_exp (double x, int radix, long int exponent)
58 {
59   /* If RADIX == 10, this code is neither precise nor fast; it is
60      merely a straightforward and relatively portable approximation.
61      If N == 2, this code is precise on a radix-2 implementation,
62      albeit perhaps not fast if ldexp is not in libc.  */
63 
64   long int e = exponent;
65 
66   if (HAVE_LDEXP_IN_LIBC && radix == 2)
67     return ldexp (x, e < INT_MIN ? INT_MIN : INT_MAX < e ? INT_MAX : e);
68   else
69     {
70       double r = x;
71 
72       if (r != 0)
73         {
74           if (e < 0)
75             {
76               while (e++ != 0)
77                 {
78                   r /= radix;
79                   if (r == 0 && x != 0)
80                     {
81                       errno = ERANGE;
82                       break;
83                     }
84                 }
85             }
86           else
87             {
88               while (e-- != 0)
89                 {
90                   if (r < -DBL_MAX / radix)
91                     {
92                       errno = ERANGE;
93                       return -HUGE_VAL;
94                     }
95                   else if (DBL_MAX / radix < r)
96                     {
97                       errno = ERANGE;
98                       return HUGE_VAL;
99                     }
100                   else
101                     r *= radix;
102                 }
103             }
104         }
105 
106       return r;
107     }
108 }
109 
110 /* Parse a number at NPTR; this is a bit like strtol (NPTR, ENDPTR)
111    except there are no leading spaces or signs or "0x", and ENDPTR is
112    nonnull.  The number uses a base BASE (either 10 or 16) fraction, a
113    radix RADIX (either 10 or 2) exponent, and exponent character
114    EXPCHAR.  To convert from a number of digits to a radix exponent,
115    multiply by RADIX_MULTIPLIER (either 1 or 4).  */
116 static double
parse_number(const char * nptr,int base,int radix,int radix_multiplier,char expchar,char ** endptr)117 parse_number (const char *nptr,
118               int base, int radix, int radix_multiplier, char expchar,
119               char **endptr)
120 {
121   const char *s = nptr;
122   bool got_dot = false;
123   long int exponent = 0;
124   double num = 0;
125 
126   for (;; ++s)
127     {
128       int digit;
129       if (c_isdigit (*s))
130         digit = *s - '0';
131       else if (base == 16 && c_isxdigit (*s))
132         digit = c_tolower (*s) - ('a' - 10);
133       else if (! got_dot && *s == '.')
134         {
135           /* Record that we have found the decimal point.  */
136           got_dot = true;
137           continue;
138         }
139       else
140         /* Any other character terminates the number.  */
141         break;
142 
143       /* Make sure that multiplication by base will not overflow.  */
144       if (num <= DBL_MAX / base)
145         num = num * base + digit;
146       else
147         {
148           /* The value of the digit doesn't matter, since we have already
149              gotten as many digits as can be represented in a 'double'.
150              This doesn't necessarily mean the result will overflow.
151              The exponent may reduce it to within range.
152 
153              We just need to record that there was another
154              digit so that we can multiply by 10 later.  */
155           exponent += radix_multiplier;
156         }
157 
158       /* Keep track of the number of digits after the decimal point.
159          If we just divided by base here, we might lose precision.  */
160       if (got_dot)
161         exponent -= radix_multiplier;
162     }
163 
164   if (c_tolower (*s) == expchar && ! locale_isspace (s[1]))
165     {
166       /* Add any given exponent to the implicit one.  */
167       int save = errno;
168       char *end;
169       long int value = strtol (s + 1, &end, 10);
170       errno = save;
171 
172       if (s + 1 != end)
173         {
174           /* Skip past the exponent, and add in the implicit exponent,
175              resulting in an extreme value on overflow.  */
176           s = end;
177           exponent =
178             (exponent < 0
179              ? (value < LONG_MIN - exponent ? LONG_MIN : exponent + value)
180              : (LONG_MAX - exponent < value ? LONG_MAX : exponent + value));
181         }
182     }
183 
184   *endptr = (char *) s;
185   return scale_radix_exp (num, radix, exponent);
186 }
187 
188 static double underlying_strtod (const char *, char **);
189 
190 /* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
191    ICC 10.0 has a bug when optimizing the expression -zero.
192    The expression -DBL_MIN * DBL_MIN does not work when cross-compiling
193    to PowerPC on Mac OS X 10.5.  */
194 #if defined __hpux || defined __sgi || defined __ICC
195 static double
compute_minus_zero(void)196 compute_minus_zero (void)
197 {
198   return -DBL_MIN * DBL_MIN;
199 }
200 # define minus_zero compute_minus_zero ()
201 #else
202 double minus_zero = -0.0;
203 #endif
204 
205 /* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
206    character after the last one used in the number is put in *ENDPTR.  */
207 double
strtod(const char * nptr,char ** endptr)208 strtod (const char *nptr, char **endptr)
209 {
210   bool negative = false;
211 
212   /* The number so far.  */
213   double num;
214 
215   const char *s = nptr;
216   const char *end;
217   char *endbuf;
218   int saved_errno = errno;
219 
220   /* Eat whitespace.  */
221   while (locale_isspace (*s))
222     ++s;
223 
224   /* Get the sign.  */
225   negative = *s == '-';
226   if (*s == '-' || *s == '+')
227     ++s;
228 
229   num = underlying_strtod (s, &endbuf);
230   end = endbuf;
231 
232   if (c_isdigit (s[*s == '.']))
233     {
234       /* If a hex float was converted incorrectly, do it ourselves.
235          If the string starts with "0x" but does not contain digits,
236          consume the "0" ourselves.  If a hex float is followed by a
237          'p' but no exponent, then adjust the end pointer.  */
238       if (*s == '0' && c_tolower (s[1]) == 'x')
239         {
240           if (! c_isxdigit (s[2 + (s[2] == '.')]))
241             {
242               end = s + 1;
243 
244               /* strtod() on z/OS returns ERANGE for "0x".  */
245               errno = saved_errno;
246             }
247           else if (end <= s + 2)
248             {
249               num = parse_number (s + 2, 16, 2, 4, 'p', &endbuf);
250               end = endbuf;
251             }
252           else
253             {
254               const char *p = s + 2;
255               while (p < end && c_tolower (*p) != 'p')
256                 p++;
257               if (p < end && ! c_isdigit (p[1 + (p[1] == '-' || p[1] == '+')]))
258                 end = p;
259             }
260         }
261       else
262         {
263           /* If "1e 1" was misparsed as 10.0 instead of 1.0, re-do the
264              underlying strtod on a copy of the original string
265              truncated to avoid the bug.  */
266           const char *e = s + 1;
267           while (e < end && c_tolower (*e) != 'e')
268             e++;
269           if (e < end && ! c_isdigit (e[1 + (e[1] == '-' || e[1] == '+')]))
270             {
271               char *dup = strdup (s);
272               errno = saved_errno;
273               if (!dup)
274                 {
275                   /* Not really our day, is it.  Rounding errors are
276                      better than outright failure.  */
277                   num = parse_number (s, 10, 10, 1, 'e', &endbuf);
278                 }
279               else
280                 {
281                   dup[e - s] = '\0';
282                   num = underlying_strtod (dup, &endbuf);
283                   saved_errno = errno;
284                   free (dup);
285                   errno = saved_errno;
286                 }
287               end = e;
288             }
289         }
290 
291       s = end;
292     }
293 
294   /* Check for infinities and NaNs.  */
295   else if (c_tolower (*s) == 'i'
296            && c_tolower (s[1]) == 'n'
297            && c_tolower (s[2]) == 'f')
298     {
299       s += 3;
300       if (c_tolower (*s) == 'i'
301           && c_tolower (s[1]) == 'n'
302           && c_tolower (s[2]) == 'i'
303           && c_tolower (s[3]) == 't'
304           && c_tolower (s[4]) == 'y')
305         s += 5;
306       num = HUGE_VAL;
307       errno = saved_errno;
308     }
309   else if (c_tolower (*s) == 'n'
310            && c_tolower (s[1]) == 'a'
311            && c_tolower (s[2]) == 'n')
312     {
313       s += 3;
314       if (*s == '(')
315         {
316           const char *p = s + 1;
317           while (c_isalnum (*p))
318             p++;
319           if (*p == ')')
320             s = p + 1;
321         }
322 
323       /* If the underlying implementation misparsed the NaN, assume
324          its result is incorrect, and return a NaN.  Normally it's
325          better to use the underlying implementation's result, since a
326          nice implementation populates the bits of the NaN according
327          to interpreting n-char-sequence as a hexadecimal number.  */
328       if (s != end || num == num)
329         num = NAN;
330       errno = saved_errno;
331     }
332   else
333     {
334       /* No conversion could be performed.  */
335       errno = EINVAL;
336       s = nptr;
337     }
338 
339   if (endptr != NULL)
340     *endptr = (char *) s;
341   /* Special case -0.0, since at least ICC miscompiles negation.  We
342      can't use copysign(), as that drags in -lm on some platforms.  */
343   if (!num && negative)
344     return minus_zero;
345   return negative ? -num : num;
346 }
347 
348 /* The underlying strtod implementation.  This must be defined
349    after strtod because it #undefs strtod.  */
350 static double
underlying_strtod(const char * nptr,char ** endptr)351 underlying_strtod (const char *nptr, char **endptr)
352 {
353 #undef strtod
354   return strtod (nptr, endptr);
355 }
356