List:Commits« Previous MessageNext Message »
From:bar Date:December 12 2007 1:23pm
Subject:bk commit into 6.0 tree (bar:1.2700) BUG#32394
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of bar. When bar does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-12-12 17:23:22+04:00, bar@stripped +8 -0
  Bug#32394 Character sets: crash if comparison with 0xfffd
  Problem: strnncoll() was called with non-aligned arguments in some cases.
  E.g. UCS2 and UTF16 expect length to be divisible by 2,
  and UTF32 expects length to be divisible by 4.
  This was not true in the case of mixing character strings
  with binary constants, like 0xAA of X'AA'. A binary constant of
  this kind was passed directly to strnncoll() without preliminary
  extending to 0x00AA (for UCS2/UTF16) and 0x000000AA (for UTF32).
  Fix: force binary constant alignment for UCS2/UTF16/UTF32.

  mysql-test/include/ctype_bin_const.inc@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +11 -0
    New BitKeeper file ``mysql-test/include/ctype_bin_const.inc''

  mysql-test/include/ctype_bin_const.inc@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +0 -0

  mysql-test/r/ctype_ucs.result@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +16 -0
    Adding test

  mysql-test/r/ctype_utf16.result@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +16 -0
    Adding test

  mysql-test/r/ctype_utf32.result@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +16 -0
    Adding test

  mysql-test/t/ctype_ucs.test@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +1 -0
    Adding test

  mysql-test/t/ctype_utf16.test@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +1 -0
    Adding test

  mysql-test/t/ctype_utf32.test@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +1 -0
    Adding test

  sql/item.cc@stripped, 2007-12-12 17:23:20+04:00, bar@stripped +26 -2
    Auto-extend binary constants to mbminlen of the effective character set

diff -Nrup a/mysql-test/include/ctype_bin_const.inc b/mysql-test/include/ctype_bin_const.inc
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/include/ctype_bin_const.inc	2007-12-12 17:23:20 +04:00
@@ -0,0 +1,11 @@
+#
+# Bug#32394 Character sets: crash if comparison with 0xfffd
+#
+create table t1 select (' ') as s1;
+delete from t1;
+insert into t1 values (0xFFFD);
+select collation(s1) from t1;
+select hex(s1) from t1;
+select hex(s1) from t1 where s1 = 0xFFFD;
+select case when s1 = 0xfffd then 1 else 0 end from t1;
+drop table t1;
diff -Nrup a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
--- a/mysql-test/r/ctype_ucs.result	2007-11-22 23:45:08 +04:00
+++ b/mysql-test/r/ctype_ucs.result	2007-12-12 17:23:20 +04:00
@@ -982,6 +982,22 @@ NULL
 NULL
 NULL
 drop table t1;
+create table t1 select (' ') as s1;
+delete from t1;
+insert into t1 values (0xFFFD);
+select collation(s1) from t1;
+collation(s1)
+ucs2_general_ci
+select hex(s1) from t1;
+hex(s1)
+FFFD
+select hex(s1) from t1 where s1 = 0xFFFD;
+hex(s1)
+FFFD
+select case when s1 = 0xfffd then 1 else 0 end from t1;
+case when s1 = 0xfffd then 1 else 0 end
+1
+drop table t1;
 set names latin1;
 select hex(char(0x41 using ucs2));
 hex(char(0x41 using ucs2))
diff -Nrup a/mysql-test/r/ctype_utf16.result b/mysql-test/r/ctype_utf16.result
--- a/mysql-test/r/ctype_utf16.result	2007-12-06 11:42:16 +04:00
+++ b/mysql-test/r/ctype_utf16.result	2007-12-12 17:23:20 +04:00
@@ -1084,4 +1084,20 @@ NULL
 NULL
 NULL
 drop table t1;
+create table t1 select (' ') as s1;
+delete from t1;
+insert into t1 values (0xFFFD);
+select collation(s1) from t1;
+collation(s1)
+utf16_general_ci
+select hex(s1) from t1;
+hex(s1)
+FFFD
+select hex(s1) from t1 where s1 = 0xFFFD;
+hex(s1)
+FFFD
+select case when s1 = 0xfffd then 1 else 0 end from t1;
+case when s1 = 0xfffd then 1 else 0 end
+1
+drop table t1;
 set names latin1;
diff -Nrup a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result
--- a/mysql-test/r/ctype_utf32.result	2007-12-06 11:42:16 +04:00
+++ b/mysql-test/r/ctype_utf32.result	2007-12-12 17:23:20 +04:00
@@ -1048,4 +1048,20 @@ NULL
 NULL
 NULL
 drop table t1;
+create table t1 select (' ') as s1;
+delete from t1;
+insert into t1 values (0xFFFD);
+select collation(s1) from t1;
+collation(s1)
+utf32_general_ci
+select hex(s1) from t1;
+hex(s1)
+0000FFFD
+select hex(s1) from t1 where s1 = 0xFFFD;
+hex(s1)
+0000FFFD
+select case when s1 = 0xfffd then 1 else 0 end from t1;
+case when s1 = 0xfffd then 1 else 0 end
+1
+drop table t1;
 set names latin1;
diff -Nrup a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
--- a/mysql-test/t/ctype_ucs.test	2007-11-22 23:45:12 +04:00
+++ b/mysql-test/t/ctype_ucs.test	2007-12-12 17:23:20 +04:00
@@ -619,6 +619,7 @@ drop table t1;
 
 set collation_connection=ucs2_general_ci;
 --source include/ctype_regex.inc
+--source include/ctype_bin_const.inc
 set names latin1;
 #
 # Bug#30981 CHAR(0x41 USING ucs2) doesn't add leading zero
diff -Nrup a/mysql-test/t/ctype_utf16.test b/mysql-test/t/ctype_utf16.test
--- a/mysql-test/t/ctype_utf16.test	2007-12-06 11:42:16 +04:00
+++ b/mysql-test/t/ctype_utf16.test	2007-12-12 17:23:20 +04:00
@@ -682,6 +682,7 @@ drop table t1;
 #
 set collation_connection=utf16_general_ci;
 --source include/ctype_regex.inc
+--source include/ctype_bin_const.inc
 set names latin1;
 
 #
diff -Nrup a/mysql-test/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test
--- a/mysql-test/t/ctype_utf32.test	2007-12-06 11:42:16 +04:00
+++ b/mysql-test/t/ctype_utf32.test	2007-12-12 17:23:20 +04:00
@@ -715,6 +715,7 @@ drop table t1;
 #
 set collation_connection=utf32_general_ci;
 --source include/ctype_regex.inc
+--source include/ctype_bin_const.inc
 set names latin1;
 
 # TODO: add tests for all engines
diff -Nrup a/sql/item.cc b/sql/item.cc
--- a/sql/item.cc	2007-11-14 17:53:12 +04:00
+++ b/sql/item.cc	2007-12-12 17:23:20 +04:00
@@ -1656,8 +1656,32 @@ bool agg_item_charsets(DTCollation &coll
   for (i= 0, arg= args; i < nargs; i++, arg+= item_sep)
   {
     Item* conv;
-    uint32 dummy_offset;
-    if (!String::needs_conversion(0, (*arg)->collation.collation,
+    uint32 dummy_offset, arg_length;
+    /*
+      If mbminlen for the result character set is greater than 1,
+      and if character set of the current argument is "binary",
+      and if the current argument is a constant,
+      we need to calculate its length and pass it into needs_conversion()
+      to detect cases when we'll need to left-pad the binary argument
+      with zeros.
+      
+      For example, in
+      
+        SELECT _utf32 0x0000fffd collate utf32_general_ci = 0xfffd;
+      
+      the right argument must be extended to 0x0000fffd before
+      it can be passed to strnncoll().
+    */
+    if (coll.collation->mbminlen > 1 &&
+        (*arg)->collation.collation == &my_charset_bin &&
+        (*arg)->const_item())
+    {
+      String tmp, *ptmp= (*arg)->val_str(&tmp);
+      arg_length= ptmp ? ptmp->length() : 0;
+    }
+    else
+      arg_length= 0;
+    if (!String::needs_conversion(arg_length, (*arg)->collation.collation,
                                   coll.collation,
                                   &dummy_offset))
       continue;
Thread
bk commit into 6.0 tree (bar:1.2700) BUG#32394bar12 Dec