Merge from mysql-5.1 for bug#58026.
This commit is contained in:
commit
d284940f8b
@ -3,6 +3,10 @@ SHOW VARIABLES like 'slave_skip_errors';
|
|||||||
Variable_name Value
|
Variable_name Value
|
||||||
slave_skip_errors OFF
|
slave_skip_errors OFF
|
||||||
#
|
#
|
||||||
|
# Bug#58026: massive recursion and crash in regular expression handling
|
||||||
|
#
|
||||||
|
SELECT '1' RLIKE RPAD('1', 10000, '(');
|
||||||
|
#
|
||||||
# WL#4284: Transactional DDL locking
|
# WL#4284: Transactional DDL locking
|
||||||
#
|
#
|
||||||
# FLUSH PRIVILEGES should not implicitly unlock locked tables.
|
# FLUSH PRIVILEGES should not implicitly unlock locked tables.
|
||||||
|
@ -14,6 +14,16 @@ call mtr.add_suppression("Can't open and lock privilege tables: Table 'host' was
|
|||||||
|
|
||||||
SHOW VARIABLES like 'slave_skip_errors';
|
SHOW VARIABLES like 'slave_skip_errors';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#58026: massive recursion and crash in regular expression handling
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--disable_result_log
|
||||||
|
--error ER_STACK_OVERRUN_NEED_MORE
|
||||||
|
SELECT '1' RLIKE RPAD('1', 10000, '(');
|
||||||
|
--enable_result_log
|
||||||
|
|
||||||
|
|
||||||
# End of 5.1 tests
|
# End of 5.1 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -28,6 +28,7 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
/* === regcomp.c === */
|
/* === regcomp.c === */
|
||||||
|
typedef int (*my_regex_stack_check_t)();
|
||||||
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
|
||||||
@ -76,7 +77,8 @@ extern void my_regfree(my_regex_t *);
|
|||||||
|
|
||||||
/* === reginit.c === */
|
/* === reginit.c === */
|
||||||
|
|
||||||
extern void my_regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */
|
/* Should be called for multithread progs */
|
||||||
|
extern void my_regex_init(CHARSET_INFO *cs, my_regex_stack_check_t func);
|
||||||
extern void my_regex_end(void); /* If one wants a clean end */
|
extern void my_regex_end(void); /* If one wants a clean end */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -31,6 +31,9 @@ struct parse {
|
|||||||
CHARSET_INFO *charset; /* for ctype things */
|
CHARSET_INFO *charset; /* for ctype things */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Check if there is enough stack space for recursion. */
|
||||||
|
my_regex_stack_check_t my_regex_enough_mem_in_stack= NULL;
|
||||||
|
|
||||||
#include "regcomp.ih"
|
#include "regcomp.ih"
|
||||||
|
|
||||||
static char nuls[10]; /* place to point scanner in event of error */
|
static char nuls[10]; /* place to point scanner in event of error */
|
||||||
@ -117,7 +120,7 @@ CHARSET_INFO *charset;
|
|||||||
# define GOODFLAGS(f) ((f)&~REG_DUMP)
|
# define GOODFLAGS(f) ((f)&~REG_DUMP)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
my_regex_init(charset); /* Init cclass if neaded */
|
my_regex_init(charset, NULL); /* Init cclass if neaded */
|
||||||
preg->charset=charset;
|
preg->charset=charset;
|
||||||
cflags = GOODFLAGS(cflags);
|
cflags = GOODFLAGS(cflags);
|
||||||
if ((cflags®_EXTENDED) && (cflags®_NOSPEC))
|
if ((cflags®_EXTENDED) && (cflags®_NOSPEC))
|
||||||
@ -222,7 +225,15 @@ int stop; /* character this ERE should end at */
|
|||||||
/* do a bunch of concatenated expressions */
|
/* do a bunch of concatenated expressions */
|
||||||
conc = HERE();
|
conc = HERE();
|
||||||
while (MORE() && (c = PEEK()) != '|' && c != stop)
|
while (MORE() && (c = PEEK()) != '|' && c != stop)
|
||||||
p_ere_exp(p);
|
{
|
||||||
|
if (my_regex_enough_mem_in_stack &&
|
||||||
|
my_regex_enough_mem_in_stack())
|
||||||
|
{
|
||||||
|
SETERROR(REG_ESPACE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p_ere_exp(p);
|
||||||
|
}
|
||||||
if(REQUIRE(HERE() != conc, REG_EMPTY)) {}/* require nonempty */
|
if(REQUIRE(HERE() != conc, REG_EMPTY)) {}/* require nonempty */
|
||||||
|
|
||||||
if (!EAT('|'))
|
if (!EAT('|'))
|
||||||
|
@ -4,10 +4,12 @@
|
|||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
#include "cclass.h"
|
#include "cclass.h"
|
||||||
|
#include "my_regex.h"
|
||||||
|
|
||||||
static my_bool regex_inited=0;
|
static my_bool regex_inited=0;
|
||||||
|
extern my_regex_stack_check_t my_regex_enough_mem_in_stack;
|
||||||
|
|
||||||
void my_regex_init(CHARSET_INFO *cs)
|
void my_regex_init(CHARSET_INFO *cs, my_regex_stack_check_t func)
|
||||||
{
|
{
|
||||||
char buff[CCLASS_LAST][256];
|
char buff[CCLASS_LAST][256];
|
||||||
int count[CCLASS_LAST];
|
int count[CCLASS_LAST];
|
||||||
@ -16,6 +18,7 @@ void my_regex_init(CHARSET_INFO *cs)
|
|||||||
if (!regex_inited)
|
if (!regex_inited)
|
||||||
{
|
{
|
||||||
regex_inited=1;
|
regex_inited=1;
|
||||||
|
my_regex_enough_mem_in_stack= func;
|
||||||
bzero((uchar*) &count,sizeof(count));
|
bzero((uchar*) &count,sizeof(count));
|
||||||
|
|
||||||
for (i=1 ; i<= 255; i++)
|
for (i=1 ; i<= 255; i++)
|
||||||
@ -74,6 +77,7 @@ void my_regex_end()
|
|||||||
int i;
|
int i;
|
||||||
for (i=0; i < CCLASS_LAST ; i++)
|
for (i=0; i < CCLASS_LAST ; i++)
|
||||||
free((char*) cclasses[i].chars);
|
free((char*) cclasses[i].chars);
|
||||||
|
my_regex_enough_mem_in_stack= NULL;
|
||||||
regex_inited=0;
|
regex_inited=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2879,6 +2879,19 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
static
|
||||||
|
int
|
||||||
|
check_enough_stack_size()
|
||||||
|
{
|
||||||
|
uchar stack_top;
|
||||||
|
|
||||||
|
return check_stack_overrun(current_thd, STACK_MIN_SIZE,
|
||||||
|
&stack_top);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize one of the global date/time format variables.
|
Initialize one of the global date/time format variables.
|
||||||
|
|
||||||
@ -3340,7 +3353,11 @@ static int init_common_variables()
|
|||||||
if (item_create_init())
|
if (item_create_init())
|
||||||
return 1;
|
return 1;
|
||||||
item_init();
|
item_init();
|
||||||
my_regex_init(&my_charset_latin1);
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
my_regex_init(&my_charset_latin1, check_enough_stack_size);
|
||||||
|
#else
|
||||||
|
my_regex_init(&my_charset_latin1, NULL);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
Process a comma-separated character set list and choose
|
Process a comma-separated character set list and choose
|
||||||
the first available character set. This is mostly for
|
the first available character set. This is mostly for
|
||||||
|
Loading…
x
Reference in New Issue
Block a user