Commit 1002a941 authored by bar@mysql.com's avatar bar@mysql.com

ctype_utf8.result, ctype_utf8.test:

  adding test
field.cc:
  bug#10714 Inserting double value into utf8 column crashes server:
  sprintf was executed with too big length, which caused
  crash on some Windows platforms.
parent 342f6d54
...@@ -888,3 +888,6 @@ NULL ...@@ -888,3 +888,6 @@ NULL
select ifnull(NULL, _utf8'string'); select ifnull(NULL, _utf8'string');
ifnull(NULL, _utf8'string') ifnull(NULL, _utf8'string')
string string
create table t1 (a varchar(255)) default character set utf8;
insert into t1 values (1.0);
drop table t1;
...@@ -724,3 +724,10 @@ select ifnull(a,'') from t1; ...@@ -724,3 +724,10 @@ select ifnull(a,'') from t1;
drop table t1; drop table t1;
select repeat(_utf8'+',3) as h union select NULL; select repeat(_utf8'+',3) as h union select NULL;
select ifnull(NULL, _utf8'string'); select ifnull(NULL, _utf8'string');
#
# Bug#10714: Inserting double value into utf8 column crashes server
#
create table t1 (a varchar(255)) default character set utf8;
insert into t1 values (1.0);
drop table t1;
...@@ -4981,31 +4981,32 @@ int Field_str::store(double nr) ...@@ -4981,31 +4981,32 @@ int Field_str::store(double nr)
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
uint length; uint length;
bool use_scientific_notation= TRUE; bool use_scientific_notation= TRUE;
uint char_length= field_length / charset()->mbmaxlen;
/* /*
Check fabs(nr) against longest value that can be stored in field, Check fabs(nr) against longest value that can be stored in field,
which depends on whether the value is < 1 or not, and negative or not which depends on whether the value is < 1 or not, and negative or not
*/ */
double anr= fabs(nr); double anr= fabs(nr);
int neg= (nr < 0.0) ? 1 : 0; int neg= (nr < 0.0) ? 1 : 0;
if (field_length > 4 && field_length < 32 && if (char_length > 4 && char_length < 32 &&
(anr < 1.0 ? anr > 1/(log_10[max(0,field_length-neg-2)]) /* -2 for "0." */ (anr < 1.0 ? anr > 1/(log_10[max(0,char_length-neg-2)]) /* -2 for "0." */
: anr < log_10[field_length-neg]-1)) : anr < log_10[char_length-neg]-1))
use_scientific_notation= FALSE; use_scientific_notation= FALSE;
length= (uint) my_sprintf(buff, (buff, "%-.*g", length= (uint) my_sprintf(buff, (buff, "%-.*g",
(use_scientific_notation ? (use_scientific_notation ?
max(0, (int)field_length-neg-5) : max(0, (int)char_length-neg-5) :
field_length), char_length),
nr)); nr));
/* /*
+1 below is because "precision" in %g above means the +1 below is because "precision" in %g above means the
max. number of significant digits, not the output width. max. number of significant digits, not the output width.
Thus the width can be larger than number of significant digits by 1 Thus the width can be larger than number of significant digits by 1
(for decimal point) (for decimal point)
the test for field_length < 5 is for extreme cases, the test for char_length < 5 is for extreme cases,
like inserting 500.0 in char(1) like inserting 500.0 in char(1)
*/ */
DBUG_ASSERT(field_length < 5 || length <= field_length+1); DBUG_ASSERT(char_length < 5 || length <= char_length+1);
return store((const char *) buff, length, charset()); return store((const char *) buff, length, charset());
} }
......
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