From f25b8f20d21e15be7ca7eb71f3bbbed539924fc1 Mon Sep 17 00:00:00 2001 From: "ramil/ram@mysql.com/myoffice.izhnet.ru" <> Date: Tue, 29 Aug 2006 14:38:02 +0500 Subject: [PATCH 1/3] Fix for bug #21142: Malformed insert causes a segmentation fault. - possible stack overflow fixed. --- client/mysql.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 09818ae27b3..1a967ed8364 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2615,7 +2615,7 @@ com_connect(String *buffer, char *line) bzero(buff, sizeof(buff)); if (buffer) { - strmov(buff, line); + strmake(buff, line, sizeof(buff) - 1); tmp= get_arg(buff, 0); if (tmp && *tmp) { @@ -2729,7 +2729,7 @@ com_use(String *buffer __attribute__((unused)), char *line) char *tmp, buff[FN_REFLEN + 1]; bzero(buff, sizeof(buff)); - strmov(buff, line); + strmake(buff, line, sizeof(buff) - 1); tmp= get_arg(buff, 0); if (!tmp || !*tmp) { From 13200c3f9616cc10d1d077799f4d9945693350bc Mon Sep 17 00:00:00 2001 From: "tnurnberg@salvation.intern.azundris.com" <> Date: Mon, 4 Sep 2006 09:13:40 +0200 Subject: [PATCH 2/3] Bug#21913: DATE_FORMAT() Crashes mysql server if I use it through mysql-connector-j driver. Variable character_set_results can legally be NULL (for "no conversion.") This could result in a NULL deref that crashed the server. Fixed. (Although ran some additional precursory tests to see whether I could break anything else, but no breakage so far.) --- mysql-test/r/func_time.result | 12 ++++++++++++ mysql-test/t/func_time.test | 18 ++++++++++++++++++ sql/sql_string.cc | 7 ++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index fab0bf01f58..07a46f92469 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -688,3 +688,15 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +SET NAMES latin1; +SET character_set_results = NULL; +SHOW VARIABLES LIKE 'character_set_results'; +Variable_name Value +character_set_results +CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY); +INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd'); +SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868; +fmtddate field2 +Sep-4 12:00AM abcd +DROP TABLE testBug8868; +SET NAMES DEFAULT; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index b232fb14e1e..8a7f8792081 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -358,4 +358,22 @@ create table t1 select now() - now(), curtime() - curtime(), show create table t1; drop table t1; +# +# 21913: DATE_FORMAT() Crashes mysql server if I use it through +# mysql-connector-j driver. +# + +SET NAMES latin1; +SET character_set_results = NULL; +SHOW VARIABLES LIKE 'character_set_results'; + +CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY); +INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd'); + +SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868; + +DROP TABLE testBug8868; + +SET NAMES DEFAULT; + # End of 4.1 tests diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 939ffe8d9d2..aaa85b0d96c 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -248,6 +248,10 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) 0 No conversion needed 1 Either character set conversion or adding leading zeros (e.g. for UCS-2) must be done + + NOTE + to_cs may be NULL for "no conversion" if the system variable + character_set_results is NULL. */ bool String::needs_conversion(uint32 arg_length, @@ -256,7 +260,8 @@ bool String::needs_conversion(uint32 arg_length, uint32 *offset) { *offset= 0; - if ((to_cs == &my_charset_bin) || + if (!to_cs || + (to_cs == &my_charset_bin) || (to_cs == from_cs) || my_charset_same(from_cs, to_cs) || ((from_cs == &my_charset_bin) && From d3f503a0bd4160dc62998777c6d9013cad5e7efe Mon Sep 17 00:00:00 2001 From: "ramil/ram@mysql.com/myoffice.izhnet.ru" <> Date: Thu, 21 Sep 2006 16:05:01 +0500 Subject: [PATCH 3/3] Fix for bug #20204: "order by" changes the results returned Item_substr's results are improperly stored in a temporary table due to wrongly calculated max_length value for multi-byte charsets if two arguments specified. --- mysql-test/r/ctype_utf8.result | 13 +++++++++++++ mysql-test/t/ctype_utf8.test | 12 ++++++++++++ sql/item_strfunc.cc | 3 ++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 941b834a733..22b6de80a35 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1352,3 +1352,16 @@ select database(); database() имя_базы_в_кодировке_утф8_длиной_больше_чем_45 drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use test; +create table t1(a char(10)) default charset utf8; +insert into t1 values ('123'), ('456'); +explain +select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE Y ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where +select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1; +substr(Z.a,-1) a +3 123 +6 456 +drop table t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 7272cb79089..90d7ec1b3a0 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1087,5 +1087,17 @@ create database имя_базы_в_кодировке_утф8_длиной_бо use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; select database(); drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use test; + +# +# Bug #20204: "order by" changes the results returned +# + +create table t1(a char(10)) default charset utf8; +insert into t1 values ('123'), ('456'); +explain + select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1; +select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1; +drop table t1; # End of 4.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1ef11945bd5..98888226e58 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1109,12 +1109,13 @@ void Item_func_substr::fix_length_and_dec() } if (arg_count == 3 && args[2]->const_item()) { - int32 length= (int32) args[2]->val_int() * collation.collation->mbmaxlen; + int32 length= (int32) args[2]->val_int(); if (length <= 0) max_length=0; /* purecov: inspected */ else set_if_smaller(max_length,(uint) length); } + max_length*= collation.collation->mbmaxlen; }