mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
BUG#58246: INSTALL PLUGIN not secure & crashable
When installing plugins, there is a missing check for slash (/) in the path on Windows. Note that on Windows, both / and \ can be used to separate directories. This patch fixes the issue by: - Adding a FN_DIRSEP symbol for all platforms consisting of a string of legal directory separators. - Adding a charset-aware version of strcspn(). - Adding a check_valid_path() function that uses my_strcspn() to check if any FN_DIRSEP character is in the supplied string. - Using the check_valid_path() function in sql_plugin.cc and sql_udf.cc (which means replacing the existing test there).
This commit is contained in:
@@ -13,6 +13,45 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
#include "m_ctype.h"
|
||||
|
||||
#define NEQ(A, B) ((A) != (B))
|
||||
#define EQU(A, B) ((A) == (B))
|
||||
|
||||
/**
|
||||
Macro for the body of the string scanning.
|
||||
|
||||
@param CS The character set of the string
|
||||
@param STR Pointer to beginning of string
|
||||
@param END Pointer to one-after-end of string
|
||||
@param ACC Pointer to beginning of accept (or reject) string
|
||||
@param LEN Length of accept (or reject) string
|
||||
@param CMP is a function-like for doing the comparison of two characters.
|
||||
*/
|
||||
|
||||
#define SCAN_STRING(CS, STR, END, ACC, LEN, CMP) \
|
||||
do { \
|
||||
uint mbl; \
|
||||
const char *ptr_str, *ptr_acc; \
|
||||
const char *acc_end= (ACC) + (LEN); \
|
||||
for (ptr_str= (STR) ; ptr_str < (END) ; ptr_str+= mbl) \
|
||||
{ \
|
||||
mbl= my_mbcharlen((CS), *(uchar*)ptr_str); \
|
||||
if (mbl < 2) \
|
||||
{ \
|
||||
DBUG_ASSERT(mbl == 1); \
|
||||
for (ptr_acc= (ACC) ; ptr_acc < acc_end ; ++ptr_acc) \
|
||||
if (CMP(*ptr_acc, *ptr_str)) \
|
||||
goto end; \
|
||||
} \
|
||||
} \
|
||||
end: \
|
||||
return (size_t) (ptr_str - (STR)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
my_strchr(cs, str, end, c) returns a pointer to the first place in
|
||||
str where c (1-byte character) occurs, or NULL if c does not occur
|
||||
@@ -21,11 +60,6 @@
|
||||
frequently.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include "m_string.h"
|
||||
#include "m_ctype.h"
|
||||
|
||||
|
||||
char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end,
|
||||
pchar c)
|
||||
{
|
||||
@@ -45,3 +79,26 @@ char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end,
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the length of the initial segment of 'str' which consists
|
||||
entirely of characters not in 'reject'.
|
||||
|
||||
@note The reject string points to single-byte characters so it is
|
||||
only possible to find the first occurrence of a single-byte
|
||||
character. Multi-byte characters in 'str' are treated as not
|
||||
matching any character in the reject string.
|
||||
|
||||
@todo should be moved to CHARSET_INFO if it's going to be called
|
||||
frequently.
|
||||
|
||||
@internal The implementation builds on the assumption that 'str' is long,
|
||||
while 'reject' is short. So it compares each character in string
|
||||
with the characters in 'reject' in a tight loop over the characters
|
||||
in 'reject'.
|
||||
*/
|
||||
|
||||
size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *str_end,
|
||||
const char *reject)
|
||||
{
|
||||
SCAN_STRING(cs, str, str_end, reject, strlen(reject), EQU);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user