Fix for bug #39021: SELECT REGEXP BINARY NULL never returns
Problem: SELECT ... REGEXP BINARY NULL may lead to server crash/hang. Fix: properly handle NULL regular expressions. mysql-test/r/func_regexp.result: Fix for bug #39021: SELECT REGEXP BINARY NULL never returns - test result. mysql-test/t/func_regexp.test: Fix for bug #39021: SELECT REGEXP BINARY NULL never returns - test case. sql/item_cmpfunc.cc: Fix for bug #39021: SELECT REGEXP BINARY NULL never returns - checking regular expressions' null_value we tested it without a val_xxx() call before, which is wrong. Now Item_func_regex::regcomp() returns -1 in the case and allows to handle NULL expessions properly. sql/item_cmpfunc.h: Fix for bug #39021: SELECT REGEXP BINARY NULL never returns - checking regular expressions' null_value we tested it without a val_xxx() call before, which is wrong. Now Item_func_regex::regcomp() returns -1 in the case and allows to handle NULL expessions properly.
This commit is contained in:
parent
bcbff0b93b
commit
788be2aebd
@ -114,4 +114,16 @@ End of 4.1 tests
|
|||||||
SELECT 1 REGEXP NULL;
|
SELECT 1 REGEXP NULL;
|
||||||
1 REGEXP NULL
|
1 REGEXP NULL
|
||||||
NULL
|
NULL
|
||||||
|
SELECT '' REGEXP BINARY NULL;
|
||||||
|
'' REGEXP BINARY NULL
|
||||||
|
NULL
|
||||||
|
SELECT NULL REGEXP BINARY NULL;
|
||||||
|
NULL REGEXP BINARY NULL
|
||||||
|
NULL
|
||||||
|
SELECT 'A' REGEXP BINARY NULL;
|
||||||
|
'A' REGEXP BINARY NULL
|
||||||
|
NULL
|
||||||
|
SELECT "ABC" REGEXP BINARY NULL;
|
||||||
|
"ABC" REGEXP BINARY NULL
|
||||||
|
NULL
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -64,4 +64,14 @@ drop table t1;
|
|||||||
|
|
||||||
SELECT 1 REGEXP NULL;
|
SELECT 1 REGEXP NULL;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #39021: SELECT REGEXP BINARY NULL never returns
|
||||||
|
#
|
||||||
|
|
||||||
|
SELECT '' REGEXP BINARY NULL;
|
||||||
|
SELECT NULL REGEXP BINARY NULL;
|
||||||
|
SELECT 'A' REGEXP BINARY NULL;
|
||||||
|
SELECT "ABC" REGEXP BINARY NULL;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -4341,8 +4341,20 @@ void Item_func_like::cleanup()
|
|||||||
|
|
||||||
#ifdef USE_REGEX
|
#ifdef USE_REGEX
|
||||||
|
|
||||||
bool
|
/**
|
||||||
Item_func_regex::regcomp(bool send_error)
|
@brief Compile regular expression.
|
||||||
|
|
||||||
|
@param[in] send_error send error message if any.
|
||||||
|
|
||||||
|
@details Make necessary character set conversion then
|
||||||
|
compile regular expression passed in the args[1].
|
||||||
|
|
||||||
|
@retval 0 success.
|
||||||
|
@retval 1 error occurred.
|
||||||
|
@retval -1 given null regular expression.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Item_func_regex::regcomp(bool send_error)
|
||||||
{
|
{
|
||||||
char buff[MAX_FIELD_WIDTH];
|
char buff[MAX_FIELD_WIDTH];
|
||||||
String tmp(buff,sizeof(buff),&my_charset_bin);
|
String tmp(buff,sizeof(buff),&my_charset_bin);
|
||||||
@ -4350,12 +4362,12 @@ Item_func_regex::regcomp(bool send_error)
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (args[1]->null_value)
|
if (args[1]->null_value)
|
||||||
return TRUE;
|
return -1;
|
||||||
|
|
||||||
if (regex_compiled)
|
if (regex_compiled)
|
||||||
{
|
{
|
||||||
if (!stringcmp(res, &prev_regexp))
|
if (!stringcmp(res, &prev_regexp))
|
||||||
return FALSE;
|
return 0;
|
||||||
prev_regexp.copy(*res);
|
prev_regexp.copy(*res);
|
||||||
my_regfree(&preg);
|
my_regfree(&preg);
|
||||||
regex_compiled= 0;
|
regex_compiled= 0;
|
||||||
@ -4367,7 +4379,7 @@ Item_func_regex::regcomp(bool send_error)
|
|||||||
uint dummy_errors;
|
uint dummy_errors;
|
||||||
if (conv.copy(res->ptr(), res->length(), res->charset(),
|
if (conv.copy(res->ptr(), res->length(), res->charset(),
|
||||||
regex_lib_charset, &dummy_errors))
|
regex_lib_charset, &dummy_errors))
|
||||||
return TRUE;
|
return 1;
|
||||||
res= &conv;
|
res= &conv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4379,10 +4391,10 @@ Item_func_regex::regcomp(bool send_error)
|
|||||||
(void) my_regerror(error, &preg, buff, sizeof(buff));
|
(void) my_regerror(error, &preg, buff, sizeof(buff));
|
||||||
my_error(ER_REGEXP_ERROR, MYF(0), buff);
|
my_error(ER_REGEXP_ERROR, MYF(0), buff);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return 1;
|
||||||
}
|
}
|
||||||
regex_compiled= 1;
|
regex_compiled= 1;
|
||||||
return FALSE;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4420,13 +4432,14 @@ Item_func_regex::fix_fields(THD *thd, Item **ref)
|
|||||||
const_item_cache=args[0]->const_item() && args[1]->const_item();
|
const_item_cache=args[0]->const_item() && args[1]->const_item();
|
||||||
if (!regex_compiled && args[1]->const_item())
|
if (!regex_compiled && args[1]->const_item())
|
||||||
{
|
{
|
||||||
if (args[1]->null_value)
|
int comp_res= regcomp(TRUE);
|
||||||
|
if (comp_res == -1)
|
||||||
{ // Will always return NULL
|
{ // Will always return NULL
|
||||||
maybe_null=1;
|
maybe_null=1;
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (regcomp(TRUE))
|
else if (comp_res)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
regex_is_const= 1;
|
regex_is_const= 1;
|
||||||
maybe_null= args[0]->maybe_null;
|
maybe_null= args[0]->maybe_null;
|
||||||
|
@ -1323,7 +1323,7 @@ class Item_func_regex :public Item_bool_func
|
|||||||
CHARSET_INFO *regex_lib_charset;
|
CHARSET_INFO *regex_lib_charset;
|
||||||
int regex_lib_flags;
|
int regex_lib_flags;
|
||||||
String conv;
|
String conv;
|
||||||
bool regcomp(bool send_error);
|
int regcomp(bool send_error);
|
||||||
public:
|
public:
|
||||||
Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
|
Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
|
||||||
regex_compiled(0),regex_is_const(0) {}
|
regex_compiled(0),regex_is_const(0) {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user