projects
/
musl
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ldso: move the suid/secure check code closer to env/auxv processing
[musl]
/
src
/
stdlib
/
strtold.c
diff --git
a/src/stdlib/strtold.c
b/src/stdlib/strtold.c
index
54f8046
..
ec464c1
100644
(file)
--- a/
src/stdlib/strtold.c
+++ b/
src/stdlib/strtold.c
@@
-2,15
+2,21
@@
#include <errno.h>
#include <ctype.h>
#include <errno.h>
#include <ctype.h>
+static int valid_exp(const unsigned char *s)
+{
+ return isdigit(*s) || ((s[0]=='+'||s[0]=='-') && isdigit(s[1]));
+}
+
long double strtold(const char *s1, char **p)
{
long double strtold(const char *s1, char **p)
{
- const unsigned char *s = s1;
+ const unsigned char *s =
(void *)
s1;
long double x = 0;
long double frac;
int sign = 0;
int nonzero = 0;
int radix = '.';
long e;
long double x = 0;
long double frac;
int sign = 0;
int nonzero = 0;
int radix = '.';
long e;
+ int saved_errno = errno;
if (!p) p = (char **)&s1;
if (!p) p = (char **)&s1;
@@
-41,26
+47,23
@@
long double strtold(const char *s1, char **p)
/* We have a real hex float */
s += 2;
for (; isxdigit(*s); s++) {
/* We have a real hex float */
s += 2;
for (; isxdigit(*s); s++) {
- x = 16*x + (isdigit(*s)?*s-'0':(*s|32)-'a');
+ x = 16*x + (isdigit(*s)?*s-'0':(*s|32)-'a'
+10
);
if (*s!='0') nonzero=1;
}
if (*s == radix) {
frac = 1.0/16.0;
for (s++; isxdigit(*s); s++) {
if (*s!='0') nonzero=1;
}
if (*s == radix) {
frac = 1.0/16.0;
for (s++; isxdigit(*s); s++) {
- x += frac * (isdigit(*s)?*s-'0':(*s|32)-'a');
+ x += frac * (isdigit(*s)?*s-'0':(*s|32)-'a'
+10
);
frac *= 1.0/16.0;
if (*s!='0') nonzero=1;
}
}
frac *= 1.0/16.0;
if (*s!='0') nonzero=1;
}
}
- if ((*s|32) == 'p') {
- e = strtol(
s+1
, (void *)&s, 10);
+ if ((*s|32) == 'p'
&& valid_exp(s+1)
) {
+ e = strtol(
(void *)(s+1)
, (void *)&s, 10);
for (; e>0; e--) x *= 2.0;
for (; e<0; e++) x *= 0.5;
}
for (; e>0; e--) x *= 2.0;
for (; e<0; e++) x *= 0.5;
}
- if ((nonzero && !x) || !(1.0/x))
- errno = ERANGE;
- *p = (char *)s;
- return sign ? -x : x;
+ goto finish;
}
/* Mantissa must be non-degenerate */
}
/* Mantissa must be non-degenerate */
@@
-81,13
+84,13
@@
long double strtold(const char *s1, char **p)
if (*s!='0') nonzero=1;
}
}
if (*s!='0') nonzero=1;
}
}
- if ((*s|32)=='e') {
- e = strtol(++s, (void *)&s, 10);
+ if ((*s|32)=='e'
&& valid_exp(s+1)
) {
+ e = strtol(
(void *)
++s, (void *)&s, 10);
for (; e>0; e--) x *= 10.0;
for (; e<0; e++) x /= 10.0;
}
for (; e>0; e--) x *= 10.0;
for (; e<0; e++) x /= 10.0;
}
- if ((nonzero && !x) || !(1.0/x))
-
errno = ERANGE
;
+finish:
+
errno = ((nonzero && !x) || !(1.0/x)) ? ERANGE : saved_errno
;
*p = (char*)s;
return sign ? -x : x;
}
*p = (char*)s;
return sign ? -x : x;
}