diff options
author | serg@serg.mylan <> | 2004-03-14 17:25:20 +0100 |
---|---|---|
committer | serg@serg.mylan <> | 2004-03-14 17:25:20 +0100 |
commit | ded8fa56ebe1af3eb7b61f16d4da72004682b48b (patch) | |
tree | 8d62b783d18499a58998dcedd618f5eb2b66ee66 /strings/strtod.c | |
parent | 42c19ada564ad6b9f94ea5aefd9371e845b8f18f (diff) | |
download | mariadb-git-ded8fa56ebe1af3eb7b61f16d4da72004682b48b.tar.gz |
my_strtod fixes:
sigsegv protection (exp overflow)
don't return inf!
use errno=EOVERFLOW to signal an overflow (as my_strntod uses errno anyway)
if errno will be too slow, my_strtod can be changed to return overflow status in a parameter (like my_strntod does)
Diffstat (limited to 'strings/strtod.c')
-rw-r--r-- | strings/strtod.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/strings/strtod.c b/strings/strtod.c index a06b74248cb..243322cb945 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 @@ -41,6 +41,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++; @@ -85,7 +86,8 @@ 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) @@ -93,7 +95,7 @@ double my_strtod(const char *str, char **end) if (neg) result= 0.0; else - result= DBL_MAX*10; + overflow=1; goto done; } while (exp >= 100) @@ -113,6 +115,12 @@ done: if (end) *end = (char *)str; + if (overflow || ((overflow=isinf(result)))) + { + result=DBL_MAX; + errno=EOVERFLOW; + } + return negative ? -result : result; } |