[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] strtod: work around IRIX 6.5 bug
From: |
Eric Blake |
Subject: |
[PATCH] strtod: work around IRIX 6.5 bug |
Date: |
Wed, 1 Sep 2010 21:49:58 -0600 |
IRIX mis-parses "1e 1" as 10.0 and "" instead of 1.0 and "e 1".
Because the original parse may differ from the reparse in terms
of whether the value overflows, we have to do an errno dance.
* lib/strtod.c (strtod): Reparse number on shorter string if
exponent parse was invalid.
Reported by Tom G. Christensen.
Signed-off-by: Eric Blake <address@hidden>
---
>> Building with MIPSpro works but there are testsuite failures:
>> $ ./test-strtod
>> test-strtod.c:377: assertion failed
>> Abort (core dumped)
>
>Phooey - a regression. This is already a known bug ("1E 2" is
>mistakenly treated as 100.0 instead of 1.0 on HP-UX 11.11, IRIX 6.5,
>and OSF/1 4.0, per the comments on that line); so our rewrite to call
>the native strtod under the hood of rpl_strtod is not working around
>this particular bug.
This should do it. I've compile-tested it, but without an actual
platform exhibiting the failure, there may still be a tweak or
two needed.
Hmm - the testsuite lacks any tests for "0x1p 1" not consuming the
"p 1". I wonder if AIX is buggy in that regards; and if so, the
errno dance needs to be extended to 0x handling. I guess I'd better
do a followup that enhances the testsuite, yet again.
ChangeLog | 7 +++++++
lib/strtod.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2955f2f..395191a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-09-01 Eric Blake <address@hidden>
+
+ strtod: work around IRIX 6.5 bug
+ * lib/strtod.c (strtod): Reparse number on shorter string if
+ exponent parse was invalid.
+ Reported by Tom G. Christensen.
+
2010-08-31 Eric Blake <address@hidden>
and Jim Meyering <address@hidden>
diff --git a/lib/strtod.c b/lib/strtod.c
index 64b62ff..944f6cd 100644
--- a/lib/strtod.c
+++ b/lib/strtod.c
@@ -24,6 +24,7 @@
#include <limits.h>
#include <math.h>
#include <stdbool.h>
+#include <string.h>
#include "c-ctype.h"
@@ -202,6 +203,7 @@ strtod (const char *nptr, char **endptr)
const char *s = nptr;
const char *end;
char *endbuf;
+ int saved_errno;
/* Eat whitespace. */
while (locale_isspace (*s))
@@ -212,6 +214,7 @@ strtod (const char *nptr, char **endptr)
if (*s == '-' || *s == '+')
++s;
+ saved_errno = errno;
num = underlying_strtod (s, &endbuf);
end = endbuf;
@@ -239,6 +242,35 @@ strtod (const char *nptr, char **endptr)
end = p;
}
}
+ else
+ {
+ /* If "1e 1" was misparsed as 10.0 instead of 1.0, re-do the
+ underlying strtod on a copy of the original string
+ truncated to avoid the bug. */
+ const char *e = s + 1;
+ while (e < end && c_tolower (*e) != 'e')
+ e++;
+ if (e < end && ! c_isdigit (e[1 + (e[1] == '-' || e[1] == '+')]))
+ {
+ char *dup = strdup (s);
+ errno = saved_errno;
+ if (!dup)
+ {
+ /* Not really our day, is it. Rounding errors are
+ better than outright failure. */
+ num = parse_number (s, 10, 10, 1, 'e', &endbuf);
+ }
+ else
+ {
+ dup[e - s] = '\0';
+ num = underlying_strtod (s, &endbuf);
+ saved_errno = errno;
+ free (dup);
+ errno = saved_errno;
+ }
+ end = e;
+ }
+ }
s = end;
}
--
1.7.2.2
iswblank failure [was: IRIX failures], Eric Blake, 2010/09/01
[PATCH] strtod: work around IRIX 6.5 bug,
Eric Blake <=