Commit 99645e5b authored by Neeraj Bisht's avatar Neeraj Bisht

BUG#14303860 - EXECUTING A SELECT QUERY WITH TOO

MANY WILDCARDS CAUSES A SEGFAULT

Back port from 5.6 and trunk
parent 54c47527
...@@ -132,6 +132,8 @@ enum my_lex_states ...@@ -132,6 +132,8 @@ enum my_lex_states
struct charset_info_st; struct charset_info_st;
extern int (*my_string_stack_guard)(int);
/* See strings/CHARSET_INFO.txt for information about this structure */ /* See strings/CHARSET_INFO.txt for information about this structure */
typedef struct my_collation_handler_st typedef struct my_collation_handler_st
{ {
......
...@@ -28,7 +28,7 @@ typedef struct { ...@@ -28,7 +28,7 @@ typedef struct {
/* === regcomp.c === */ /* === regcomp.c === */
typedef int (*my_regex_stack_check_t)(); typedef int (*my_regex_stack_check_t)(int);
extern int my_regcomp(my_regex_t *, const char *, int, CHARSET_INFO *charset); extern int my_regcomp(my_regex_t *, const char *, int, CHARSET_INFO *charset);
#define REG_BASIC 0000 #define REG_BASIC 0000
#define REG_EXTENDED 0001 #define REG_EXTENDED 0001
......
...@@ -227,7 +227,7 @@ int stop; /* character this ERE should end at */ ...@@ -227,7 +227,7 @@ int stop; /* character this ERE should end at */
while (MORE() && (c = PEEK()) != '|' && c != stop) while (MORE() && (c = PEEK()) != '|' && c != stop)
{ {
if (my_regex_enough_mem_in_stack && if (my_regex_enough_mem_in_stack &&
my_regex_enough_mem_in_stack()) my_regex_enough_mem_in_stack(0))
{ {
SETERROR(REG_ESPACE); SETERROR(REG_ESPACE);
return; return;
......
...@@ -2898,14 +2898,25 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]); ...@@ -2898,14 +2898,25 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
static /**
int This function is used to check for stack overrun for pathological
check_enough_stack_size() cases of regular expressions and 'like' expressions.
The call to current_thd is quite expensive, so we try to avoid it
for the normal cases.
The size of each stack frame for the wildcmp() routines is ~128 bytes,
so checking *every* recursive call is not necessary.
*/
extern "C" int
check_enough_stack_size(int recurse_level)
{ {
uchar stack_top; uchar stack_top;
if (recurse_level % 16 != 0)
return 0;
return check_stack_overrun(current_thd, STACK_MIN_SIZE, THD *my_thd= current_thd;
&stack_top); if (my_thd != NULL)
return check_stack_overrun(my_thd, STACK_MIN_SIZE * 2, &stack_top);
return 0;
} }
#endif #endif
...@@ -3293,6 +3304,7 @@ static int init_common_variables(const char *conf_file_name, int argc, ...@@ -3293,6 +3304,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
#ifdef USE_REGEX #ifdef USE_REGEX
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
my_regex_init(&my_charset_latin1, check_enough_stack_size); my_regex_init(&my_charset_latin1, check_enough_stack_size);
my_string_stack_guard= check_enough_stack_size;
#else #else
my_regex_init(&my_charset_latin1, NULL); my_regex_init(&my_charset_latin1, NULL);
#endif #endif
......
...@@ -323,13 +323,16 @@ void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)), ...@@ -323,13 +323,16 @@ void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
#define INC_PTR(cs,A,B) (A)++ #define INC_PTR(cs,A,B) (A)++
int my_wildcmp_bin(CHARSET_INFO *cs, static
const char *str,const char *str_end, int my_wildcmp_bin_impl(CHARSET_INFO *cs,
const char *wildstr,const char *wildend, const char *str,const char *str_end,
int escape, int w_one, int w_many) const char *wildstr,const char *wildend,
int escape, int w_one, int w_many, int recurse_level)
{ {
int result= -1; /* Not found, using wildcards */ int result= -1; /* Not found, using wildcards */
if (my_string_stack_guard && my_string_stack_guard(recurse_level))
return 1;
while (wildstr != wildend) while (wildstr != wildend)
{ {
while (*wildstr != w_many && *wildstr != w_one) while (*wildstr != w_many && *wildstr != w_one)
...@@ -388,8 +391,8 @@ int my_wildcmp_bin(CHARSET_INFO *cs, ...@@ -388,8 +391,8 @@ int my_wildcmp_bin(CHARSET_INFO *cs,
if (str++ == str_end) if (str++ == str_end)
return(-1); return(-1);
{ {
int tmp=my_wildcmp_bin(cs,str,str_end,wildstr,wildend,escape,w_one, int tmp=my_wildcmp_bin_impl(cs,str,str_end,wildstr,wildend,escape,w_one,
w_many); w_many, recurse_level + 1);
if (tmp <= 0) if (tmp <= 0)
return(tmp); return(tmp);
} }
...@@ -400,6 +403,16 @@ int my_wildcmp_bin(CHARSET_INFO *cs, ...@@ -400,6 +403,16 @@ int my_wildcmp_bin(CHARSET_INFO *cs,
return(str != str_end ? 1 : 0); return(str != str_end ? 1 : 0);
} }
int my_wildcmp_bin(CHARSET_INFO *cs,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many)
{
return my_wildcmp_bin_impl(cs, str, str_end,
wildstr, wildend,
escape, w_one, w_many, 1);
}
static size_t my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), static size_t my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)),
uchar *dest, size_t dstlen, uchar *dest, size_t dstlen,
......
...@@ -148,13 +148,16 @@ int my_strcasecmp_mb(CHARSET_INFO * cs,const char *s, const char *t) ...@@ -148,13 +148,16 @@ int my_strcasecmp_mb(CHARSET_INFO * cs,const char *s, const char *t)
#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)] #define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)]
int my_wildcmp_mb(CHARSET_INFO *cs, static
const char *str,const char *str_end, int my_wildcmp_mb_impl(CHARSET_INFO *cs,
const char *wildstr,const char *wildend, const char *str,const char *str_end,
int escape, int w_one, int w_many) const char *wildstr,const char *wildend,
int escape, int w_one, int w_many, int recurse_level)
{ {
int result= -1; /* Not found, using wildcards */ int result= -1; /* Not found, using wildcards */
if (my_string_stack_guard && my_string_stack_guard(recurse_level))
return 1;
while (wildstr != wildend) while (wildstr != wildend)
{ {
while (*wildstr != w_many && *wildstr != w_one) while (*wildstr != w_many && *wildstr != w_one)
...@@ -243,8 +246,8 @@ int my_wildcmp_mb(CHARSET_INFO *cs, ...@@ -243,8 +246,8 @@ int my_wildcmp_mb(CHARSET_INFO *cs,
INC_PTR(cs,str, str_end); INC_PTR(cs,str, str_end);
} }
{ {
int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one, int tmp=my_wildcmp_mb_impl(cs,str,str_end,wildstr,wildend,escape,w_one,
w_many); w_many, recurse_level + 1);
if (tmp <= 0) if (tmp <= 0)
return (tmp); return (tmp);
} }
...@@ -255,6 +258,16 @@ int my_wildcmp_mb(CHARSET_INFO *cs, ...@@ -255,6 +258,16 @@ int my_wildcmp_mb(CHARSET_INFO *cs,
return (str != str_end ? 1 : 0); return (str != str_end ? 1 : 0);
} }
int my_wildcmp_mb(CHARSET_INFO *cs,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many)
{
return my_wildcmp_mb_impl(cs, str, str_end,
wildstr, wildend,
escape, w_one, w_many, 1);
}
size_t my_numchars_mb(CHARSET_INFO *cs __attribute__((unused)), size_t my_numchars_mb(CHARSET_INFO *cs __attribute__((unused)),
const char *pos, const char *end) const char *pos, const char *end)
...@@ -697,13 +710,15 @@ fill_max_and_min: ...@@ -697,13 +710,15 @@ fill_max_and_min:
} }
static int my_wildcmp_mb_bin(CHARSET_INFO *cs, static int my_wildcmp_mb_bin_impl(CHARSET_INFO *cs,
const char *str,const char *str_end, const char *str,const char *str_end,
const char *wildstr,const char *wildend, const char *wildstr,const char *wildend,
int escape, int w_one, int w_many) int escape, int w_one, int w_many, int recurse_level)
{ {
int result= -1; /* Not found, using wildcards */ int result= -1; /* Not found, using wildcards */
if (my_string_stack_guard && my_string_stack_guard(recurse_level))
return 1;
while (wildstr != wildend) while (wildstr != wildend)
{ {
while (*wildstr != w_many && *wildstr != w_one) while (*wildstr != w_many && *wildstr != w_one)
...@@ -790,7 +805,9 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs, ...@@ -790,7 +805,9 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs,
INC_PTR(cs,str, str_end); INC_PTR(cs,str, str_end);
} }
{ {
int tmp=my_wildcmp_mb_bin(cs,str,str_end,wildstr,wildend,escape,w_one,w_many); int tmp=my_wildcmp_mb_bin_impl(cs,str,str_end,
wildstr,wildend,escape,
w_one,w_many, recurse_level+1);
if (tmp <= 0) if (tmp <= 0)
return (tmp); return (tmp);
} }
...@@ -801,6 +818,17 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs, ...@@ -801,6 +818,17 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs,
return (str != str_end ? 1 : 0); return (str != str_end ? 1 : 0);
} }
int
my_wildcmp_mb_bin(CHARSET_INFO *cs,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many)
{
return my_wildcmp_mb_bin_impl(cs, str, str_end,
wildstr, wildend,
escape, w_one, w_many, 1);
}
/* /*
Data was produced from EastAsianWidth.txt Data was produced from EastAsianWidth.txt
......
...@@ -952,13 +952,16 @@ cnv: ...@@ -952,13 +952,16 @@ cnv:
#define INC_PTR(cs,A,B) (A)++ #define INC_PTR(cs,A,B) (A)++
int my_wildcmp_8bit(CHARSET_INFO *cs, static
const char *str,const char *str_end, int my_wildcmp_8bit_impl(CHARSET_INFO *cs,
const char *wildstr,const char *wildend, const char *str,const char *str_end,
int escape, int w_one, int w_many) const char *wildstr,const char *wildend,
int escape, int w_one, int w_many, int recurse_level)
{ {
int result= -1; /* Not found, using wildcards */ int result= -1; /* Not found, using wildcards */
if (my_string_stack_guard && my_string_stack_guard(recurse_level))
return 1;
while (wildstr != wildend) while (wildstr != wildend)
{ {
while (*wildstr != w_many && *wildstr != w_one) while (*wildstr != w_many && *wildstr != w_one)
...@@ -1018,8 +1021,9 @@ int my_wildcmp_8bit(CHARSET_INFO *cs, ...@@ -1018,8 +1021,9 @@ int my_wildcmp_8bit(CHARSET_INFO *cs,
str++; str++;
if (str++ == str_end) return(-1); if (str++ == str_end) return(-1);
{ {
int tmp=my_wildcmp_8bit(cs,str,str_end,wildstr,wildend,escape,w_one, int tmp=my_wildcmp_8bit_impl(cs,str,str_end,
w_many); wildstr,wildend,escape,w_one,
w_many, recurse_level+1);
if (tmp <= 0) if (tmp <= 0)
return(tmp); return(tmp);
} }
...@@ -1030,6 +1034,16 @@ int my_wildcmp_8bit(CHARSET_INFO *cs, ...@@ -1030,6 +1034,16 @@ int my_wildcmp_8bit(CHARSET_INFO *cs,
return(str != str_end ? 1 : 0); return(str != str_end ? 1 : 0);
} }
int my_wildcmp_8bit(CHARSET_INFO *cs,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many)
{
return my_wildcmp_8bit_impl(cs, str, str_end,
wildstr, wildend,
escape, w_one, w_many, 1);
}
/* /*
** Calculate min_str and max_str that ranges a LIKE string. ** Calculate min_str and max_str that ranges a LIKE string.
......
...@@ -7328,10 +7328,10 @@ static int my_uca_charcmp(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2) ...@@ -7328,10 +7328,10 @@ static int my_uca_charcmp(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2)
*/ */
static static
int my_wildcmp_uca(CHARSET_INFO *cs, int my_wildcmp_uca_impl(CHARSET_INFO *cs,
const char *str,const char *str_end, const char *str,const char *str_end,
const char *wildstr,const char *wildend, const char *wildstr,const char *wildend,
int escape, int w_one, int w_many) int escape, int w_one, int w_many, int recurse_level)
{ {
int result= -1; /* Not found, using wildcards */ int result= -1; /* Not found, using wildcards */
my_wc_t s_wc, w_wc; my_wc_t s_wc, w_wc;
...@@ -7339,7 +7339,9 @@ int my_wildcmp_uca(CHARSET_INFO *cs, ...@@ -7339,7 +7339,9 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
int (*mb_wc)(struct charset_info_st *, my_wc_t *, int (*mb_wc)(struct charset_info_st *, my_wc_t *,
const uchar *, const uchar *); const uchar *, const uchar *);
mb_wc= cs->cset->mb_wc; mb_wc= cs->cset->mb_wc;
if (my_string_stack_guard && my_string_stack_guard(recurse_level))
return 1;
while (wildstr != wildend) while (wildstr != wildend)
{ {
while (1) while (1)
...@@ -7446,8 +7448,8 @@ int my_wildcmp_uca(CHARSET_INFO *cs, ...@@ -7446,8 +7448,8 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
if (str == str_end) if (str == str_end)
return -1; return -1;
result= my_wildcmp_uca(cs, str, str_end, wildstr, wildend, result= my_wildcmp_uca_impl(cs, str, str_end, wildstr, wildend,
escape, w_one, w_many); escape, w_one, w_many, recurse_level+1);
if (result <= 0) if (result <= 0)
return result; return result;
...@@ -7459,6 +7461,16 @@ int my_wildcmp_uca(CHARSET_INFO *cs, ...@@ -7459,6 +7461,16 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
return (str != str_end ? 1 : 0); return (str != str_end ? 1 : 0);
} }
int my_wildcmp_uca(CHARSET_INFO *cs,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many)
{
return my_wildcmp_uca_impl(cs, str, str_end,
wildstr, wildend,
escape, w_one, w_many, 1);
}
/* /*
Collation language is implemented according to Collation language is implemented according to
......
...@@ -1889,11 +1889,12 @@ MY_UNICASE_INFO *my_unicase_turkish[256]= ...@@ -1889,11 +1889,12 @@ MY_UNICASE_INFO *my_unicase_turkish[256]=
** 1 if matched with wildcard ** 1 if matched with wildcard
*/ */
int my_wildcmp_unicode(CHARSET_INFO *cs, static
const char *str,const char *str_end, int my_wildcmp_unicode_impl(CHARSET_INFO *cs,
const char *wildstr,const char *wildend, const char *str,const char *str_end,
int escape, int w_one, int w_many, const char *wildstr,const char *wildend,
MY_UNICASE_INFO **weights) int escape, int w_one, int w_many,
MY_UNICASE_INFO **weights, int recurse_level)
{ {
int result= -1; /* Not found, using wildcards */ int result= -1; /* Not found, using wildcards */
my_wc_t s_wc, w_wc; my_wc_t s_wc, w_wc;
...@@ -1901,7 +1902,9 @@ int my_wildcmp_unicode(CHARSET_INFO *cs, ...@@ -1901,7 +1902,9 @@ int my_wildcmp_unicode(CHARSET_INFO *cs,
int (*mb_wc)(struct charset_info_st *, my_wc_t *, int (*mb_wc)(struct charset_info_st *, my_wc_t *,
const uchar *, const uchar *); const uchar *, const uchar *);
mb_wc= cs->cset->mb_wc; mb_wc= cs->cset->mb_wc;
if (my_string_stack_guard && my_string_stack_guard(recurse_level))
return 1;
while (wildstr != wildend) while (wildstr != wildend)
{ {
while (1) while (1)
...@@ -2027,9 +2030,9 @@ int my_wildcmp_unicode(CHARSET_INFO *cs, ...@@ -2027,9 +2030,9 @@ int my_wildcmp_unicode(CHARSET_INFO *cs,
return -1; return -1;
str+= scan; str+= scan;
result= my_wildcmp_unicode(cs, str, str_end, wildstr, wildend, result= my_wildcmp_unicode_impl(cs, str, str_end, wildstr, wildend,
escape, w_one, w_many, escape, w_one, w_many,
weights); weights, recurse_level+1);
if (result <= 0) if (result <= 0)
return result; return result;
} }
...@@ -2038,6 +2041,18 @@ int my_wildcmp_unicode(CHARSET_INFO *cs, ...@@ -2038,6 +2041,18 @@ int my_wildcmp_unicode(CHARSET_INFO *cs,
return (str != str_end ? 1 : 0); return (str != str_end ? 1 : 0);
} }
int
my_wildcmp_unicode(CHARSET_INFO *cs,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many,
MY_UNICASE_INFO **weights)
{
return my_wildcmp_unicode_impl(cs, str, str_end,
wildstr, wildend,
escape, w_one, w_many, weights, 1);
}
#endif #endif
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
*/ */
int (*my_string_stack_guard)(int)= NULL;
static char *mstr(char *str,const char *src,size_t l1,size_t l2) static char *mstr(char *str,const char *src,size_t l1,size_t l2)
{ {
l1= l1<l2 ? l1 : l2; l1= l1<l2 ? l1 : l2;
......
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