Commit 3a80ab21 authored by sunanda's avatar sunanda

Backport into build-201006221614-5.1.46sp1

> ------------------------------------------------------------
> revno: 3392.1.1
> revision-id: gshchepa@mysql.com-20100521184732-0jvpzinv0uwyvr2d
> parent: sven.sandberg@sun.com-20100520153801-yyhujm1qqa4eyfn0
> committer: Gleb Shchepa <gshchepa@mysql.com>
> branch nick: 53804-5.1
> timestamp: Fri 2010-05-21 22:47:32 +0400
> message:
>   Bug #53804: serious flaws in the alter database .. upgrade
>               data directory name command
>   
>   The check_db_name function has been modified to validate tails of
>   #mysql50#-prefixed database names for compliance with MySQL 5.0
>   database name encoding rules (the check_table_name function call
>   has been reused).
parent 7dd4b172
...@@ -7,6 +7,6 @@ ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and n ...@@ -7,6 +7,6 @@ ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and n
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME; ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME; ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name ERROR 42000: Incorrect database name '#mysql50#'
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME; ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Unknown database '#mysql50#upgrade-me' ERROR 42000: Unknown database '#mysql50#upgrade-me'
...@@ -112,3 +112,31 @@ select * from `a-b-c`.v1; ...@@ -112,3 +112,31 @@ select * from `a-b-c`.v1;
f1 f1
drop database `a-b-c`; drop database `a-b-c`;
use test; use test;
# End of 5.0 tests
#
# Bug #53804: serious flaws in the alter database .. upgrade data
# directory name command
#
ALTER DATABASE `#mysql50#:` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Unknown database '#mysql50#:'
ALTER DATABASE `#mysql50#.` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#.'
ALTER DATABASE `#mysql50#../` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#../'
ALTER DATABASE `#mysql50#../..` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#../..'
ALTER DATABASE `#mysql50#../../` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#../../'
ALTER DATABASE `#mysql50#./blablabla` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#./blablabla'
ALTER DATABASE `#mysql50#../blablabla` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#../blablabla'
ALTER DATABASE `#mysql50#/` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#/'
ALTER DATABASE `#mysql50#/.` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Incorrect database name '#mysql50#/.'
USE `#mysql50#.`;
ERROR 42000: Incorrect database name '#mysql50#.'
USE `#mysql50#../blablabla`;
ERROR 42000: Incorrect database name '#mysql50#../blablabla'
# End of 5.1 tests
...@@ -44,7 +44,7 @@ ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME; ...@@ -44,7 +44,7 @@ ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_USAGE --error ER_WRONG_USAGE
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME; ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_USAGE --error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME; ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
--error ER_BAD_DB_ERROR --error ER_BAD_DB_ERROR
......
...@@ -137,3 +137,37 @@ select * from `a-b-c`.v1; ...@@ -137,3 +137,37 @@ select * from `a-b-c`.v1;
--enable_ps_protocol --enable_ps_protocol
drop database `a-b-c`; drop database `a-b-c`;
use test; use test;
--echo # End of 5.0 tests
--echo #
--echo # Bug #53804: serious flaws in the alter database .. upgrade data
--echo # directory name command
--echo #
--error ER_BAD_DB_ERROR
ALTER DATABASE `#mysql50#:` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#.` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#../` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#../..` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#../../` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#./blablabla` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#../blablabla` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#/` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#/.` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_DB_NAME
USE `#mysql50#.`;
--error ER_WRONG_DB_NAME
USE `#mysql50#../blablabla`;
--echo # End of 5.1 tests
...@@ -2287,6 +2287,7 @@ uint explain_filename(THD* thd, const char *from, char *to, uint to_length, ...@@ -2287,6 +2287,7 @@ uint explain_filename(THD* thd, const char *from, char *to, uint to_length,
uint filename_to_tablename(const char *from, char *to, uint to_length); uint filename_to_tablename(const char *from, char *to, uint to_length);
uint tablename_to_filename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length);
uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length); uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length);
bool check_mysql50_prefix(const char *name);
#endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */ #endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */
#ifdef MYSQL_SERVER #ifdef MYSQL_SERVER
uint build_table_filename(char *buff, size_t bufflen, const char *db, uint build_table_filename(char *buff, size_t bufflen, const char *db,
......
...@@ -391,6 +391,25 @@ uint filename_to_tablename(const char *from, char *to, uint to_length) ...@@ -391,6 +391,25 @@ uint filename_to_tablename(const char *from, char *to, uint to_length)
} }
/**
Check if given string begins with "#mysql50#" prefix
@param name string to check cut
@retval
FALSE no prefix found
@retval
TRUE prefix found
*/
bool check_mysql50_prefix(const char *name)
{
return (name[0] == '#' &&
!strncmp(name, MYSQL50_TABLE_NAME_PREFIX,
MYSQL50_TABLE_NAME_PREFIX_LENGTH));
}
/** /**
Check if given string begins with "#mysql50#" prefix, cut it if so. Check if given string begins with "#mysql50#" prefix, cut it if so.
...@@ -406,9 +425,7 @@ uint filename_to_tablename(const char *from, char *to, uint to_length) ...@@ -406,9 +425,7 @@ uint filename_to_tablename(const char *from, char *to, uint to_length)
uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length) uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length)
{ {
if (from[0] == '#' && if (check_mysql50_prefix(from))
!strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH, return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
to_length - 1) - to); to_length - 1) - to);
return 0; return 0;
......
...@@ -2701,44 +2701,30 @@ bool check_db_name(LEX_STRING *org_name) ...@@ -2701,44 +2701,30 @@ bool check_db_name(LEX_STRING *org_name)
{ {
char *name= org_name->str; char *name= org_name->str;
uint name_length= org_name->length; uint name_length= org_name->length;
bool check_for_path_chars;
if (!name_length || name_length > NAME_LEN) if (!name_length || name_length > NAME_LEN)
return 1; return 1;
if ((check_for_path_chars= check_mysql50_prefix(name)))
{
name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
}
if (lower_case_table_names && name != any_db) if (lower_case_table_names && name != any_db)
my_casedn_str(files_charset_info, name); my_casedn_str(files_charset_info, name);
#if defined(USE_MB) && defined(USE_MB_IDENT) return check_table_name(name, name_length, check_for_path_chars);
if (use_mb(system_charset_info))
{
name_length= 0;
bool last_char_is_space= TRUE;
char *end= name + org_name->length;
while (name < end)
{
int len;
last_char_is_space= my_isspace(system_charset_info, *name);
len= my_ismbchar(system_charset_info, name, end);
if (!len)
len= 1;
name+= len;
name_length++;
}
return (last_char_is_space || name_length > NAME_CHAR_LEN);
}
else
#endif
return ((org_name->str[org_name->length - 1] != ' ') ||
(name_length > NAME_CHAR_LEN)); /* purecov: inspected */
} }
/* /*
Allow anything as a table name, as long as it doesn't contain an Allow anything as a table name, as long as it doesn't contain an
' ' at the end ' ' at the end
returns 1 on error returns 1 on error
*/ */
bool check_table_name(const char *name, uint length, bool check_for_path_chars) bool check_table_name(const char *name, uint length, bool check_for_path_chars)
{ {
uint name_length= 0; // name length in symbols uint name_length= 0; // name length in symbols
...@@ -2766,10 +2752,10 @@ bool check_table_name(const char *name, uint length, bool check_for_path_chars) ...@@ -2766,10 +2752,10 @@ bool check_table_name(const char *name, uint length, bool check_for_path_chars)
continue; continue;
} }
} }
#endif
if (check_for_path_chars && if (check_for_path_chars &&
(*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR)) (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
return 1; return 1;
#endif
name++; name++;
name_length++; name_length++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment