summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
Diffstat (limited to 'strings')
-rw-r--r--strings/strtod.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/strings/strtod.c b/strings/strtod.c
index 4c3f31bc00c..92a4700cfc4 100644
--- a/strings/strtod.c
+++ b/strings/strtod.c
@@ -2,7 +2,7 @@
An alternative implementation of "strtod()" that is both
simplier, and thread-safe.
- From mit-threads as bundled with MySQL 3.22
+ From mit-threads as bundled with MySQL 3.23
SQL:2003 specifies a number as
@@ -46,6 +46,7 @@ double my_strtod(const char *str, char **end)
double result= 0.0;
int negative, ndigits;
const char *old_str;
+ my_bool overflow=0;
while (my_isspace(&my_charset_latin1, *str))
str++;
@@ -90,12 +91,16 @@ double my_strtod(const char *str, char **end)
double scaler= 1.0;
while (my_isdigit (&my_charset_latin1, *str))
{
- exp= exp*10 + *str - '0';
+ if (exp < 9999) /* protection against exp overflow */
+ exp= exp*10 + *str - '0';
str++;
}
if (exp >= 1000)
{
- result= neg ? 0.0 : HUGE_VAL;
+ if (neg)
+ result= 0.0;
+ else
+ overflow= 1;
goto done;
}
while (exp >= 100)
@@ -115,6 +120,12 @@ done:
if (end)
*end = (char *)str;
+ if (overflow || isinf(result))
+ {
+ result= DBL_MAX;
+ errno= EOVERFLOW;
+ }
+
return negative ? -result : result;
}