Commit cfcd49b4 authored by Tor Didriksen's avatar Tor Didriksen

Bug#12406055 BUFFER OVERFLOW OF VARIABLE 'BUFF' IN STRING::SET_REAL

The buffer was simply too small.
In 5.5 and trunk, the size is 311 + 31,
in 5.1 and below, the size is 331


client/sql_string.cc:
  Increase buffer size in String::set(double, ...)
include/m_string.h:
  Increase FLOATING_POINT_BUFFER
mysql-test/r/type_float.result:
  New test cases.
mysql-test/t/type_float.test:
  New test cases.
sql/sql_string.cc:
  Increase buffer size in String::set(double, ...)
sql/unireg.h:
  Move definition of FLOATING_POINT_BUFFER
parent 8e90c619
......@@ -119,7 +119,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 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs)
#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
......
......@@ -216,6 +216,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
......
......@@ -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
......@@ -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
......@@ -117,7 +117,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;
......@@ -186,7 +186,9 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs)
#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
......
......@@ -175,7 +175,6 @@
*/
#define BIN_LOG_HEADER_SIZE 4
#define FLOATING_POINT_BUFFER 331
#define DEFAULT_KEY_CACHE_NAME "default"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment