From 52b70ceff707657a91787a6b67ce79ca015dcabf Mon Sep 17 00:00:00 2001
From: unknown <bar@mysql.com>
Date: Fri, 3 Jun 2005 09:37:53 +0500
Subject: [PATCH] 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.

sql/field.cc:
  bug#10714 Inserting double value into utf8 column crashes server
  sprintf was executed with too long length, which cau
  crashe on Windows.
mysql-test/t/ctype_utf8.test:
  adding test
mysql-test/r/ctype_utf8.result:
  adding test
---
 mysql-test/r/ctype_utf8.result |  3 +++
 mysql-test/t/ctype_utf8.test   |  7 +++++++
 sql/field.cc                   | 15 ++++++++-------
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index ffdb7cb0f3..b7aa7c68b6 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -888,3 +888,6 @@ NULL
 select ifnull(NULL, _utf8'string');
 ifnull(NULL, _utf8'string')
 string
+create table t1 (a varchar(255)) default character set utf8;
+insert into t1 values (1.0);
+drop table t1;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 02024adb34..bac6e60c30 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -724,3 +724,10 @@ select ifnull(a,'') from t1;
 drop table t1;
 select repeat(_utf8'+',3) as h union select NULL;
 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;
diff --git a/sql/field.cc b/sql/field.cc
index 60287d4003..21c3fe12bb 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4981,31 +4981,32 @@ int Field_str::store(double nr)
   char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
   uint length;
   bool use_scientific_notation= TRUE;
+  uint char_length= field_length / charset()->mbmaxlen;
   /*
     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
   */
   double anr= fabs(nr);
   int neg= (nr < 0.0) ? 1 : 0;
-  if (field_length > 4 && field_length < 32 &&
-      (anr < 1.0 ? anr > 1/(log_10[max(0,field_length-neg-2)]) /* -2 for "0." */
-                 : anr < log_10[field_length-neg]-1))
+  if (char_length > 4 && char_length < 32 &&
+      (anr < 1.0 ? anr > 1/(log_10[max(0,char_length-neg-2)]) /* -2 for "0." */
+                 : anr < log_10[char_length-neg]-1))
     use_scientific_notation= FALSE;
 
   length= (uint) my_sprintf(buff, (buff, "%-.*g",
                                    (use_scientific_notation ?
-                                    max(0, (int)field_length-neg-5) :
-                                    field_length),
+                                    max(0, (int)char_length-neg-5) :
+                                    char_length),
                                    nr));
   /*
     +1 below is because "precision" in %g above means the
     max. number of significant digits, not the output width.
     Thus the width can be larger than number of significant digits by 1
     (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)
   */
-  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());
 }
 
-- 
2.30.9