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) include/m_string.h: EOVERFLOW mysql-test/r/insert.result: updated mysql-test/r/mysqldump.result: updated strings/strtod.c: 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, it my_strtod can be changed to return overflow status in a parameter (like my_strntod does)
This commit is contained in:
parent
ad73b5ac5b
commit
22657f672c
@ -218,6 +218,9 @@ extern int is_prefix(const char *, const char *);
|
||||
/* Conversion routines */
|
||||
double my_strtod(const char *str, char **end);
|
||||
double my_atof(const char *nptr);
|
||||
#ifndef EOVERFLOW
|
||||
#define EOVERFLOW 84
|
||||
#endif
|
||||
|
||||
#ifdef USE_MY_ITOA
|
||||
extern char *my_itoa(int val,char *dst,int radix);
|
||||
|
@ -169,7 +169,6 @@ set @value= "1e+1111111111a";
|
||||
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'f_double ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_float ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_double_7_2 ' at row 1
|
||||
@ -177,7 +176,6 @@ Warning 1264 Data truncated, out of range for column 'f_double_7_2 ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_float_4_3 ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float_4_3 ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_double_u ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_double_u ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_float_u ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float_u ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_double_15_1_u ' at row 1
|
||||
@ -199,7 +197,6 @@ set @value= "-1e+1111111111a";
|
||||
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'f_double ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_float ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
|
||||
Warning 1265 Data truncated for column 'f_double_7_2 ' at row 1
|
||||
@ -228,17 +225,15 @@ f_float_3_1_u 0.0
|
||||
set @value= 1e+1111111111;
|
||||
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||
Warnings:
|
||||
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_double_7_2 ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float_4_3 ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_double_u ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float_u ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_double_15_1_u ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float_3_1_u ' at row 1
|
||||
select * from t1 where `number `=last_insert_id();
|
||||
number 6
|
||||
original_value inf
|
||||
original_value 1.7976931348623e+308
|
||||
f_double 1.79769313486232e+308
|
||||
f_float 3.40282e+38
|
||||
f_double_7_2 99999.99
|
||||
@ -250,7 +245,6 @@ f_float_3_1_u 99.9
|
||||
set @value= -1e+1111111111;
|
||||
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||
Warnings:
|
||||
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_double_7_2 ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float_4_3 ' at row 1
|
||||
@ -260,7 +254,7 @@ Warning 1264 Data truncated, out of range for column 'f_double_15_1_u ' at row 1
|
||||
Warning 1264 Data truncated, out of range for column 'f_float_3_1_u ' at row 1
|
||||
select * from t1 where `number `=last_insert_id();
|
||||
number 7
|
||||
original_value -inf
|
||||
original_value -1.7976931348623e+308
|
||||
f_double -1.79769313486232e+308
|
||||
f_float -3.40282e+38
|
||||
f_double_7_2 -99999.99
|
||||
|
@ -46,8 +46,6 @@ UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a double);
|
||||
INSERT INTO t1 VALUES (-9e999999);
|
||||
Warnings:
|
||||
Warning 1264 Data truncated, out of range for column 'a' at row 1
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user