# 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-04-09 18:49:00.000000000 +0400 +++ b/sql/sql_base.cc 2011-04-09 18:49:02.000000000 +0400 @@ -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-04-09 18:49:00.000000000 +0400 +++ b/sql/sql_parse.cc 2011-04-09 18:49:02.000000000 +0400 @@ -1112,11 +1112,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. @@ -1129,24 +1136,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. */ @@ -1171,9 +1177,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 2011-04-09 18:48:03.000000000 +0400 +++ b/strings/ctype-utf8.c 2011-04-09 18:49:02.000000000 +0400 @@ -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;