diff options
author | bar@mysql.com <> | 2006-04-19 11:42:41 +0500 |
---|---|---|
committer | bar@mysql.com <> | 2006-04-19 11:42:41 +0500 |
commit | a26f115a13b5e246ac437d4293906ea3f0119dd0 (patch) | |
tree | 84ddc5396637268113363233ac1344bc9536663d | |
parent | 9686848d646b80a05a818e8ca57ba8ec67b315e7 (diff) | |
parent | cedafc30e8aef787333334e3a373f6ae04c19545 (diff) | |
download | mariadb-git-a26f115a13b5e246ac437d4293906ea3f0119dd0.tar.gz |
Merge abarkov@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into mysql.com:/usr/home/bar/mysql-5.1-new.b17870v1
-rw-r--r-- | include/my_sys.h | 1 | ||||
-rw-r--r-- | mysql-test/r/ctype_filename.result | 13 | ||||
-rw-r--r-- | mysql-test/t/ctype_filename.test | 21 | ||||
-rw-r--r-- | mysys/my_access.c | 96 | ||||
-rw-r--r-- | sql/sql_table.cc | 13 | ||||
-rw-r--r-- | strings/ctype-utf8.c | 5 |
6 files changed, 142 insertions, 7 deletions
diff --git a/include/my_sys.h b/include/my_sys.h index 26bf31ae10d..51883e8d6f9 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -608,6 +608,7 @@ extern File my_sopen(const char *path, int oflag, int shflag, int pmode); #define my_access access #endif extern int check_if_legal_filename(const char *path); +extern int check_if_legal_tablename(const char *path); #ifndef TERMINATE extern void TERMINATE(FILE *file); diff --git a/mysql-test/r/ctype_filename.result b/mysql-test/r/ctype_filename.result new file mode 100644 index 00000000000..acc32c7dedf --- /dev/null +++ b/mysql-test/r/ctype_filename.result @@ -0,0 +1,13 @@ +drop table if exists con, aux, nul, lpt1, com1, `clock$`; +create table con (a int); +drop table con; +create table aux (a int); +drop table aux; +create table nul (a int); +drop table nul; +create table lpt1 (a int); +drop table lpt1; +create table com1 (a int); +drop table com1; +create table `clock$` (a int); +drop table `clock$`; diff --git a/mysql-test/t/ctype_filename.test b/mysql-test/t/ctype_filename.test new file mode 100644 index 00000000000..436ccfc4f2e --- /dev/null +++ b/mysql-test/t/ctype_filename.test @@ -0,0 +1,21 @@ +--disable_warnings +drop table if exists con, aux, nul, lpt1, com1, `clock$`; +--enable_warnings + +create table con (a int); +drop table con; + +create table aux (a int); +drop table aux; + +create table nul (a int); +drop table nul; + +create table lpt1 (a int); +drop table lpt1; + +create table com1 (a int); +drop table com1; + +create table `clock$` (a int); +drop table `clock$`; diff --git a/mysys/my_access.c b/mysys/my_access.c index 805dc1ee5d1..ddf3fc6622a 100644 --- a/mysys/my_access.c +++ b/mysys/my_access.c @@ -60,18 +60,106 @@ int my_access(const char *path, int amode) List of file names that causes problem on windows NOTE that one can also not have file names of type CON.TXT + + NOTE: it is important to keep "CLOCK$" on the first place, + we skip it in check_if_legal_tablename. */ - static const char *reserved_names[]= { - "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", - "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", - "LPT7", "LPT8", "LPT9", "CLOCK$", + "CLOCK$", + "CON", "PRN", "AUX", "NUL", + "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", + "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", NullS }; #define MAX_RESERVED_NAME_LENGTH 6 + +/* + Looks up a null-terminated string in a list, + case insensitively. + + SYNOPSIS + str_list_find() + list list of items + str item to find + + RETURN + 0 ok + 1 reserved file name +*/ +static int str_list_find(const char **list, const char *str) +{ + const char **name; + for (name= list; *name; name++) + { + if (!my_strcasecmp(&my_charset_latin1, *name, str)) + return 1; + } + return 0; +} + + +/* + A map for faster reserved_names lookup, + helps to avoid loops in many cases. + 1 - can be the first letter + 2 - can be the second letter + 4 - can be the third letter +*/ +static char reserved_map[256]= +{ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* !"#$%&'()*+,-./ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0123456789:;<=>? */ + 0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* @ABCDEFGHIJKLMNO */ + 3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* PQRSTUVWXYZ[\]^_ */ + 0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* bcdefghijklmno */ + 3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* pqrstuvwxyz{|}~. */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ................ */ +}; + + +/* + Check if a table name may cause problems + + SYNOPSIS + check_if_legal_tablename + name Table name (without any extensions) + + DESCRIPTION + We don't check 'CLOCK$' because dollar sign is encoded as @0024, + making table file name 'CLOCK@0024', which is safe. + This is why we start lookup from the second element + (i.e. &reserver_name[1]) + + RETURN + 0 ok + 1 reserved file name +*/ + +int check_if_legal_tablename(const char *name) +{ + DBUG_ENTER("check_if_legal_tablename"); + DBUG_RETURN((reserved_map[(uchar) name[0]] & 1) && + (reserved_map[(uchar) name[1]] & 2) && + (reserved_map[(uchar) name[2]] & 4) && + str_list_find(&reserved_names[1], name)); +} + + +#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) + + /* Check if a path will access a reserverd file name that may cause problems diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1d84c4b0f4a..6cc2ad266e5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -72,12 +72,19 @@ 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 errors; + uint errors, length; if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX, MYSQL50_TABLE_NAME_PREFIX_LENGTH)) return my_snprintf(to, to_length, "%s", from + 9); - return strconvert(system_charset_info, from, - &my_charset_filename, to, to_length, &errors); + length= strconvert(system_charset_info, from, + &my_charset_filename, to, to_length, &errors); + if (check_if_legal_tablename(to) && + length + 4 < to_length) + { + memcpy(to + length, "@@@", 4); + length+= 3; + } + return length; } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index e3bba3ee1e3..1a952a07042 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -3943,6 +3943,11 @@ my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)), *pwc= touni[code]; return 3; } + if (byte1 == '@' && byte2 == '@') + { + *pwc= 0; + return 3; + } } if (s + 4 > e) |