summaryrefslogtreecommitdiff
path: root/mysys/my_access.c
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-07-21 16:39:19 +0200
committerSergei Golubchik <sergii@pisem.net>2013-07-21 16:39:19 +0200
commitb7b5f6f1ab49948b0e15b762266d4640b3d6b7fb (patch)
tree7c302c2025184dbd053aa6135f0ff28c8ce6f359 /mysys/my_access.c
parent5f6380adde2dac3f32b40339b9b702c0135eb7d6 (diff)
parentc1d6a2d7e194225ccc19a68ea5d0f368632620d0 (diff)
downloadmariadb-git-b7b5f6f1ab49948b0e15b762266d4640b3d6b7fb.tar.gz
10.0-monty merge
includes: * remove some remnants of "Bug#14521864: MYSQL 5.1 TO 5.5 BUGS PARTITIONING" * introduce LOCK_share, now LOCK_ha_data is strictly for engines * rea_create_table() always creates .par file (even in "frm-only" mode) * fix a 5.6 bug, temp file leak on dummy ALTER TABLE
Diffstat (limited to 'mysys/my_access.c')
-rw-r--r--mysys/my_access.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/mysys/my_access.c b/mysys/my_access.c
index b96e11d9809..1b63b827592 100644
--- a/mysys/my_access.c
+++ b/mysys/my_access.c
@@ -150,6 +150,66 @@ int check_if_legal_tablename(const char *name)
}
+#ifdef __WIN__
+/**
+ Checks if the drive letter supplied is valid or not. Valid drive
+ letters are A to Z, both lower case and upper case.
+
+ @param drive_letter : The drive letter to validate.
+
+ @return TRUE if the drive exists, FALSE otherwise.
+*/
+static my_bool does_drive_exists(char drive_letter)
+{
+ DWORD drive_mask= GetLogicalDrives();
+ drive_letter= toupper(drive_letter);
+
+ return (drive_letter >= 'A' && drive_letter <= 'Z') &&
+ (drive_mask & (0x1 << (drive_letter - 'A')));
+}
+
+/**
+ Verifies if the file name supplied is allowed or not. On Windows
+ file names with a colon (:) are not allowed because such file names
+ store data in Alternate Data Streams which can be used to hide
+ the data.
+
+ @param name contains the file name with or without path
+ @param length contains the length of file name
+ @param allow_current_dir TRUE if paths like C:foobar are allowed,
+ FALSE otherwise
+
+ @return TRUE if the file name is allowed, FALSE otherwise.
+*/
+my_bool is_filename_allowed(const char *name __attribute__((unused)),
+ size_t length __attribute__((unused)),
+ my_bool allow_current_dir __attribute__((unused)))
+{
+ /*
+ For Windows, check if the file name contains : character.
+ Start from end of path and search if the file name contains :
+ */
+ const char* ch = NULL;
+ for (ch= name + length - 1; ch >= name; --ch)
+ {
+ if (FN_LIBCHAR == *ch || '/' == *ch)
+ break;
+ else if (':' == *ch)
+ {
+ /*
+ File names like C:foobar.txt are allowed since the syntax means
+ file foobar.txt in current directory of C drive. However file
+ names likes CC:foobar are not allowed since this syntax means ADS
+ foobar in file CC.
+ */
+ return (allow_current_dir && (ch - name == 1) &&
+ does_drive_exists(*name));
+ }
+ }
+ return TRUE;
+} /* is_filename_allowed */
+#endif /* __WIN__ */
+
#if defined(__WIN__) || defined(__EMX__)
@@ -171,6 +231,9 @@ int check_if_legal_filename(const char *path)
const char **reserved_name;
DBUG_ENTER("check_if_legal_filename");
+ if (!is_filename_allowed(path, strlen(path), TRUE))
+ DBUG_RETURN(1);
+
path+= dirname_length(path); /* To start of filename */
if (!(end= strchr(path, FN_EXTCHAR)))
end= strend(path);