Skip to content

Commit cedafc3

Browse files
author
bar@mysql.com
committed
Merge abarkov@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into mysql.com:/usr/home/bar/mysql-5.1-new.b17870v1
2 parents a3a4ba9 + e8e0d5c commit cedafc3

File tree

6 files changed

+142
-7
lines changed

6 files changed

+142
-7
lines changed

include/my_sys.h

+1
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
608608
#define my_access access
609609
#endif
610610
extern int check_if_legal_filename(const char *path);
611+
extern int check_if_legal_tablename(const char *path);
611612

612613
#ifndef TERMINATE
613614
extern void TERMINATE(FILE *file);

mysql-test/r/ctype_filename.result

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
drop table if exists con, aux, nul, lpt1, com1, `clock$`;
2+
create table con (a int);
3+
drop table con;
4+
create table aux (a int);
5+
drop table aux;
6+
create table nul (a int);
7+
drop table nul;
8+
create table lpt1 (a int);
9+
drop table lpt1;
10+
create table com1 (a int);
11+
drop table com1;
12+
create table `clock$` (a int);
13+
drop table `clock$`;

mysql-test/t/ctype_filename.test

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--disable_warnings
2+
drop table if exists con, aux, nul, lpt1, com1, `clock$`;
3+
--enable_warnings
4+
5+
create table con (a int);
6+
drop table con;
7+
8+
create table aux (a int);
9+
drop table aux;
10+
11+
create table nul (a int);
12+
drop table nul;
13+
14+
create table lpt1 (a int);
15+
drop table lpt1;
16+
17+
create table com1 (a int);
18+
drop table com1;
19+
20+
create table `clock$` (a int);
21+
drop table `clock$`;

mysys/my_access.c

+92-4
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,106 @@ int my_access(const char *path, int amode)
6060
List of file names that causes problem on windows
6161
6262
NOTE that one can also not have file names of type CON.TXT
63+
64+
NOTE: it is important to keep "CLOCK$" on the first place,
65+
we skip it in check_if_legal_tablename.
6366
*/
64-
6567
static const char *reserved_names[]=
6668
{
67-
"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6",
68-
"COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6",
69-
"LPT7", "LPT8", "LPT9", "CLOCK$",
69+
"CLOCK$",
70+
"CON", "PRN", "AUX", "NUL",
71+
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
72+
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
7073
NullS
7174
};
7275

7376
#define MAX_RESERVED_NAME_LENGTH 6
7477

78+
79+
/*
80+
Looks up a null-terminated string in a list,
81+
case insensitively.
82+
83+
SYNOPSIS
84+
str_list_find()
85+
list list of items
86+
str item to find
87+
88+
RETURN
89+
0 ok
90+
1 reserved file name
91+
*/
92+
static int str_list_find(const char **list, const char *str)
93+
{
94+
const char **name;
95+
for (name= list; *name; name++)
96+
{
97+
if (!my_strcasecmp(&my_charset_latin1, *name, str))
98+
return 1;
99+
}
100+
return 0;
101+
}
102+
103+
104+
/*
105+
A map for faster reserved_names lookup,
106+
helps to avoid loops in many cases.
107+
1 - can be the first letter
108+
2 - can be the second letter
109+
4 - can be the third letter
110+
*/
111+
static char reserved_map[256]=
112+
{
113+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
114+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
115+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* !"#$%&'()*+,-./ */
116+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0123456789:;<=>? */
117+
0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* @ABCDEFGHIJKLMNO */
118+
3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* PQRSTUVWXYZ[\]^_ */
119+
0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* bcdefghijklmno */
120+
3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* pqrstuvwxyz{|}~. */
121+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
122+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
123+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
124+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
125+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
126+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
127+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
128+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ................ */
129+
};
130+
131+
132+
/*
133+
Check if a table name may cause problems
134+
135+
SYNOPSIS
136+
check_if_legal_tablename
137+
name Table name (without any extensions)
138+
139+
DESCRIPTION
140+
We don't check 'CLOCK$' because dollar sign is encoded as @0024,
141+
making table file name 'CLOCK@0024', which is safe.
142+
This is why we start lookup from the second element
143+
(i.e. &reserver_name[1])
144+
145+
RETURN
146+
0 ok
147+
1 reserved file name
148+
*/
149+
150+
int check_if_legal_tablename(const char *name)
151+
{
152+
DBUG_ENTER("check_if_legal_tablename");
153+
DBUG_RETURN((reserved_map[(uchar) name[0]] & 1) &&
154+
(reserved_map[(uchar) name[1]] & 2) &&
155+
(reserved_map[(uchar) name[2]] & 4) &&
156+
str_list_find(&reserved_names[1], name));
157+
}
158+
159+
160+
#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
161+
162+
75163
/*
76164
Check if a path will access a reserverd file name that may cause problems
77165

sql/sql_table.cc

+10-3
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,19 @@ uint filename_to_tablename(const char *from, char *to, uint to_length)
7272

7373
uint tablename_to_filename(const char *from, char *to, uint to_length)
7474
{
75-
uint errors;
75+
uint errors, length;
7676
if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
7777
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
7878
return my_snprintf(to, to_length, "%s", from + 9);
79-
return strconvert(system_charset_info, from,
80-
&my_charset_filename, to, to_length, &errors);
79+
length= strconvert(system_charset_info, from,
80+
&my_charset_filename, to, to_length, &errors);
81+
if (check_if_legal_tablename(to) &&
82+
length + 4 < to_length)
83+
{
84+
memcpy(to + length, "@@@", 4);
85+
length+= 3;
86+
}
87+
return length;
8188
}
8289

8390

strings/ctype-utf8.c

+5
Original file line numberDiff line numberDiff line change
@@ -3943,6 +3943,11 @@ my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)),
39433943
*pwc= touni[code];
39443944
return 3;
39453945
}
3946+
if (byte1 == '@' && byte2 == '@')
3947+
{
3948+
*pwc= 0;
3949+
return 3;
3950+
}
39463951
}
39473952

39483953
if (s + 4 > e)

0 commit comments

Comments
 (0)