~percona-dev/percona-server/release-5.5.11-20.2-fix-bug-764138

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# name       : bug580324.patch
# introduced : 11 or before
# maintainer : Oleg
#
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc	2011-01-11 21:35:26.000000000 +0300
+++ b/sql/sql_base.cc	2011-01-11 21:42:02.000000000 +0300
@@ -251,8 +251,12 @@
                           const TABLE_LIST *table_list,
                           bool tmp_table)
 {
-  uint key_length= (uint) (strmov(strmov(key, table_list->db)+1,
-                                  table_list->table_name)-key)+1;
+  char *db_end= strnmov(key, table_list->db, MAX_DBKEY_LENGTH - 2);
+  *db_end++= '\0';
+  char *table_end= strnmov(db_end, table_list->table_name,
+                           key + MAX_DBKEY_LENGTH - 1 - db_end);
+  *table_end++= '\0';
+  uint key_length= (uint) (table_end-key);
   if (tmp_table)
   {
     int4store(key + key_length, thd->server_id);
diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc	2011-01-11 21:35:26.000000000 +0300
+++ b/sql/sql_parse.cc	2011-01-11 21:48:50.000000000 +0300
@@ -1113,11 +1113,18 @@
     break;
 #else
   {
-    char *fields, *packet_end= packet + packet_length, *arg_end;
+    char *fields;
+    char *packet_end= packet + packet_length;
+    char *wildcard;
     /* Locked closure of all tables */
     TABLE_LIST table_list;
+    char table_name_buff[NAME_LEN+1];
     LEX_STRING table_name;
+    uint dummy_errors;
     LEX_STRING db;
+
+    table_name.str= table_name_buff;
+    table_name.length= 0;
     /*
       SHOW statements should not add the used tables to the list of tables
       used in a transaction.
@@ -1130,24 +1137,23 @@
     /*
       We have name + wildcard in packet, separated by endzero
     */
-    arg_end= strend(packet);
-    uint arg_length= arg_end - packet;
-
-    /* Check given table name length. */
-    if (arg_length >= packet_length || arg_length > NAME_LEN)
+    wildcard= strend(packet);
+    table_name.length= wildcard - packet;
+    wildcard++;
+    uint query_length= (uint) (packet_end - wildcard); // Don't count end \0
+    if (table_name.length > NAME_LEN || query_length > NAME_LEN)
     {
       my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
       break;
     }
-    thd->convert_string(&table_name, system_charset_info,
-			packet, arg_length, thd->charset());
-    if (check_table_name(table_name.str, table_name.length, FALSE))
-    {
-      /* this is OK due to convert_string() null-terminating the string */
-      my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
+    table_name.length= copy_and_convert(table_name.str,
+                                        sizeof(table_name_buff)-1,
+                                        system_charset_info,
+                                        packet, table_name.length,
+                                        thd->charset(), &dummy_errors);
+    table_name.str[table_name.length]= '\0';
+    if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
       break;
-    }
-    packet= arg_end + 1;
     mysql_reset_thd_for_next_command(thd);
     lex_start(thd);
     /* Must be before we init the table list. */
@@ -1172,9 +1178,6 @@
         table_list.schema_table= schema_table;
     }
 
-    uint query_length= (uint) (packet_end - packet); // Don't count end \0
-    if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
-      break;
     thd->set_query(fields, query_length);
     general_log_print(thd, command, "%s %s", table_list.table_name, fields);
 
diff -ruN a/strings/ctype-utf8.c b/strings/ctype-utf8.c
--- a/strings/ctype-utf8.c	2010-12-03 20:58:26.000000000 +0300
+++ b/strings/ctype-utf8.c	2011-01-11 21:42:02.000000000 +0300
@@ -4212,6 +4212,10 @@
 {
   int code;
   char hex[]= "0123456789abcdef";
+
+  if (s >= e)
+    return MY_CS_TOOSMALL;
+
   if (wc < 128 && filename_safe_char[wc])
   {
     *s= (uchar) wc;