diff options
-rw-r--r-- | client/sql_string.cc | 6 | ||||
-rw-r--r-- | include/m_string.h | 9 | ||||
-rw-r--r-- | mysql-test/r/type_float.result | 12 | ||||
-rw-r--r-- | mysql-test/t/type_float.test | 15 | ||||
-rw-r--r-- | sql/sql_string.cc | 6 | ||||
-rw-r--r-- | sql/unireg.h | 1 |
6 files changed, 44 insertions, 5 deletions
diff --git a/client/sql_string.cc b/client/sql_string.cc index 17622fb7d98..c7e235522e0 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -118,7 +118,7 @@ bool String::set(ulonglong num, CHARSET_INFO *cs) bool String::set(double num,uint decimals, CHARSET_INFO *cs) { - char buff[331]; + char buff[FLOATING_POINT_BUFFER]; uint dummy_errors; str_charset=cs; @@ -188,7 +188,9 @@ end: #else #ifdef HAVE_SNPRINTF buff[sizeof(buff)-1]=0; // Safety - snprintf(buff,sizeof(buff)-1, "%.*f",(int) decimals,num); + int num_chars= snprintf(buff, sizeof(buff)-1, "%.*f",(int) decimals, num); + DBUG_ASSERT(num_chars > 0); + DBUG_ASSERT(num_chars < (int) sizeof(buff)); #else sprintf(buff,"%.*f",(int) decimals,num); #endif diff --git a/include/m_string.h b/include/m_string.h index 0e0090f52e6..e1cf7651519 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -179,6 +179,15 @@ extern int is_prefix(const char *, const char *); double my_strtod(const char *str, char **end, int *error); double my_atof(const char *nptr); +#ifndef NOT_FIXED_DEC +#define NOT_FIXED_DEC 31 +#endif + +/* + Max length of a floating point number. + */ +#define FLOATING_POINT_BUFFER (311 + NOT_FIXED_DEC) + extern char *llstr(longlong value,char *buff); extern char *ullstr(longlong value,char *buff); #ifndef HAVE_STRTOUL diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index a3a13bb0435..f88f33b6419 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -407,4 +407,16 @@ SELECT f1 FROM t1; f1 -1.79769313486231e+308 DROP TABLE t1; +# +# Bug#12406055 BUFFER OVERFLOW OF VARIABLE 'BUFF' IN STRING::SET_REAL +# +select format(-1.7976931348623157E+307,256) as foo; +foo +ignore_float_result +select least(-1.1111111111111111111111111, +- group_concat(1.7976931348623157E+308)) as foo; +foo +ignore_float_result +select concat((truncate((-1.7976931348623157E+307),(0x1e))), +(99999999999999999999999999999999999999999999999999999999999999999)) into @a; End of 5.0 tests diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 3b7b30db6f8..95d6b6d802b 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -276,4 +276,19 @@ INSERT INTO t1 VALUES(-1.79769313486231e+308); SELECT f1 FROM t1; DROP TABLE t1; +--echo # +--echo # Bug#12406055 BUFFER OVERFLOW OF VARIABLE 'BUFF' IN STRING::SET_REAL +--echo # + +let $nine_65= +99999999999999999999999999999999999999999999999999999999999999999; + +--replace_column 1 ignore_float_result +select format(-1.7976931348623157E+307,256) as foo; +--replace_column 1 ignore_float_result +select least(-1.1111111111111111111111111, + - group_concat(1.7976931348623157E+308)) as foo; +eval select concat((truncate((-1.7976931348623157E+307),(0x1e))), + ($nine_65)) into @a; + --echo End of 5.0 tests diff --git a/sql/sql_string.cc b/sql/sql_string.cc index f99dbbcea01..ea146c3938c 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -130,7 +130,7 @@ bool String::set_int(longlong num, bool unsigned_flag, CHARSET_INFO *cs) bool String::set_real(double num,uint decimals, CHARSET_INFO *cs) { - char buff[331]; + char buff[FLOATING_POINT_BUFFER]; uint dummy_errors; str_charset=cs; @@ -200,7 +200,9 @@ end: #else #ifdef HAVE_SNPRINTF buff[sizeof(buff)-1]=0; // Safety - snprintf(buff,sizeof(buff)-1, "%.*f",(int) decimals,num); + int num_chars= snprintf(buff, sizeof(buff)-1, "%.*f",(int) decimals, num); + DBUG_ASSERT(num_chars > 0); + DBUG_ASSERT(num_chars < (int) sizeof(buff)); #else sprintf(buff,"%.*f",(int) decimals,num); #endif diff --git a/sql/unireg.h b/sql/unireg.h index d35a7715b68..2f16709e7df 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -210,7 +210,6 @@ */ #define BIN_LOG_HEADER_SIZE 4 -#define FLOATING_POINT_BUFFER 331 #define DEFAULT_KEY_CACHE_NAME "default" |