From ffde32d219d7824257efc98476c310bf3ffac06b Mon Sep 17 00:00:00 2001
From: "ramil/ram@mysql.com/ramil.myoffice.izhnet.ru" <>
Date: Wed, 17 Oct 2007 14:28:00 +0500
Subject: [PATCH] Fix for bug#31615: crash after set names ucs2 collate xxx

Problem: currently, UCS-2 cannot be used as a client character set.

Fix: raise an error if one attempts to set it to USC-2.
---
 mysql-test/r/ctype_ucs.result |  8 ++++++++
 mysql-test/t/ctype_ucs.test   | 12 ++++++++++++
 sql/set_var.cc                | 22 ++++++++++++++++++++++
 sql/set_var.h                 |  1 +
 4 files changed, 43 insertions(+)

diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index bf827209795..befbd04f63d 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -803,4 +803,12 @@ quote(name)
 ????????
 ????????????????
 drop table bug20536;
+set names ucs2;
+ERROR 42000: Variable 'character_set_client' can't be set to the value of 'ucs2'
+set names ucs2 collate ucs2_bin;
+ERROR 42000: Variable 'character_set_client' can't be set to the value of 'ucs2'
+set character_set_client= ucs2;
+ERROR 42000: Variable 'character_set_client' can't be set to the value of 'ucs2'
+set character_set_client= concat('ucs', substr('2', 1));
+ERROR 42000: Variable 'character_set_client' can't be set to the value of 'ucs2'
 End of 4.1 tests
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 10559d33eb3..9e6bd0e95e6 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -535,4 +535,16 @@ select quote(name) from bug20536;
 
 drop table bug20536;
 
+#
+# Bug #31615: crash after set names ucs2 collate xxx
+#
+--error 1231
+set names ucs2;
+--error 1231
+set names ucs2 collate ucs2_bin;
+--error 1231
+set character_set_client= ucs2;
+--error 1231
+set character_set_client= concat('ucs', substr('2', 1));
+
 --echo End of 4.1 tests
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 520ee5c9f70..275252c4960 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1992,6 +1992,21 @@ void sys_var_character_set_client::set_default(THD *thd, enum_var_type type)
 }
 
 
+bool sys_var_character_set_client::check(THD *thd, set_var *var)
+{
+  if (sys_var_character_set::check(thd, var))
+    return 1;
+  /* Currently, UCS-2 cannot be used as a client character set */
+  if (var->save_result.charset->mbminlen > 1)
+  {
+    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, 
+             var->save_result.charset->csname); 
+    return 1;
+  }
+  return 0;
+}
+
+
 CHARSET_INFO **
 sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type)
 {
@@ -2355,6 +2370,13 @@ end:
 
 int set_var_collation_client::check(THD *thd)
 {
+  /* Currently, UCS-2 cannot be used as a client character set */
+  if (character_set_client->mbminlen > 1)
+  {
+    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
+             character_set_client->csname);
+    return 1;
+  }
   return 0;
 }
 
diff --git a/sql/set_var.h b/sql/set_var.h
index 78b34963e9d..f6fd0a082b5 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -578,6 +578,7 @@ public:
     sys_var_character_set(name_arg) {}
   void set_default(THD *thd, enum_var_type type);
   CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
+  bool check(THD *thd, set_var *var);
 };
 
 class sys_var_character_set_results :public sys_var_character_set