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 */
|
/* Conversion routines */
|
||||||
double my_strtod(const char *str, char **end);
|
double my_strtod(const char *str, char **end);
|
||||||
double my_atof(const char *nptr);
|
double my_atof(const char *nptr);
|
||||||
|
#ifndef EOVERFLOW
|
||||||
|
#define EOVERFLOW 84
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MY_ITOA
|
#ifdef USE_MY_ITOA
|
||||||
extern char *my_itoa(int val,char *dst,int radix);
|
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);
|
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1265 Data truncated for column 'f_double ' at row 1
|
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 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 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
|
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 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 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 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 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 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
|
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);
|
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1265 Data truncated for column 'f_double ' at row 1
|
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 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 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
|
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;
|
set @value= 1e+1111111111;
|
||||||
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||||
Warnings:
|
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_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_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_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_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_double_15_1_u ' at row 1
|
||||||
Warning 1264 Data truncated, out of range for column 'f_float_3_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();
|
select * from t1 where `number `=last_insert_id();
|
||||||
number 6
|
number 6
|
||||||
original_value inf
|
original_value 1.7976931348623e+308
|
||||||
f_double 1.79769313486232e+308
|
f_double 1.79769313486232e+308
|
||||||
f_float 3.40282e+38
|
f_float 3.40282e+38
|
||||||
f_double_7_2 99999.99
|
f_double_7_2 99999.99
|
||||||
@ -250,7 +245,6 @@ f_float_3_1_u 99.9
|
|||||||
set @value= -1e+1111111111;
|
set @value= -1e+1111111111;
|
||||||
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
|
||||||
Warnings:
|
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_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_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_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
|
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();
|
select * from t1 where `number `=last_insert_id();
|
||||||
number 7
|
number 7
|
||||||
original_value -inf
|
original_value -1.7976931348623e+308
|
||||||
f_double -1.79769313486232e+308
|
f_double -1.79769313486232e+308
|
||||||
f_float -3.40282e+38
|
f_float -3.40282e+38
|
||||||
f_double_7_2 -99999.99
|
f_double_7_2 -99999.99
|
||||||
|
@ -46,8 +46,6 @@ UNLOCK TABLES;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a double);
|
CREATE TABLE t1 (a double);
|
||||||
INSERT INTO t1 VALUES (-9e999999);
|
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 */;
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */;
|
||||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
An alternative implementation of "strtod()" that is both
|
An alternative implementation of "strtod()" that is both
|
||||||
simplier, and thread-safe.
|
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
|
SQL:2003 specifies a number as
|
||||||
|
|
||||||
@ -41,6 +41,7 @@ double my_strtod(const char *str, char **end)
|
|||||||
double result= 0.0;
|
double result= 0.0;
|
||||||
int negative, ndigits;
|
int negative, ndigits;
|
||||||
const char *old_str;
|
const char *old_str;
|
||||||
|
my_bool overflow=0;
|
||||||
|
|
||||||
while (my_isspace(&my_charset_latin1, *str))
|
while (my_isspace(&my_charset_latin1, *str))
|
||||||
str++;
|
str++;
|
||||||
@ -85,7 +86,8 @@ double my_strtod(const char *str, char **end)
|
|||||||
double scaler= 1.0;
|
double scaler= 1.0;
|
||||||
while (my_isdigit (&my_charset_latin1, *str))
|
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++;
|
str++;
|
||||||
}
|
}
|
||||||
if (exp >= 1000)
|
if (exp >= 1000)
|
||||||
@ -93,7 +95,7 @@ double my_strtod(const char *str, char **end)
|
|||||||
if (neg)
|
if (neg)
|
||||||
result= 0.0;
|
result= 0.0;
|
||||||
else
|
else
|
||||||
result= DBL_MAX*10;
|
overflow=1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
while (exp >= 100)
|
while (exp >= 100)
|
||||||
@ -113,6 +115,12 @@ done:
|
|||||||
if (end)
|
if (end)
|
||||||
*end = (char *)str;
|
*end = (char *)str;
|
||||||
|
|
||||||
|
if (overflow || ((overflow=isinf(result))))
|
||||||
|
{
|
||||||
|
result=DBL_MAX;
|
||||||
|
errno=EOVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
return negative ? -result : result;
|
return negative ? -result : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user