Commit 0994c961 authored by Ramil Kalimullin's avatar Ramil Kalimullin
Browse files

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.
parent cdec56dc
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -114,4 +114,16 @@ End of 4.1 tests
SELECT 1 REGEXP NULL;
1 REGEXP 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
+10 −0
Original line number Diff line number Diff line
@@ -64,4 +64,14 @@ drop table t1;

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
+22 −9
Original line number Diff line number Diff line
@@ -4341,8 +4341,20 @@ void Item_func_like::cleanup()

#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];
  String tmp(buff,sizeof(buff),&my_charset_bin);
@@ -4350,12 +4362,12 @@ Item_func_regex::regcomp(bool send_error)
  int error;

  if (args[1]->null_value)
    return TRUE;
    return -1;

  if (regex_compiled)
  {
    if (!stringcmp(res, &prev_regexp))
      return FALSE;
      return 0;
    prev_regexp.copy(*res);
    my_regfree(&preg);
    regex_compiled= 0;
@@ -4367,7 +4379,7 @@ Item_func_regex::regcomp(bool send_error)
    uint dummy_errors;
    if (conv.copy(res->ptr(), res->length(), res->charset(),
                  regex_lib_charset, &dummy_errors))
      return TRUE;
      return 1;
    res= &conv;
  }

@@ -4379,10 +4391,10 @@ Item_func_regex::regcomp(bool send_error)
      (void) my_regerror(error, &preg, buff, sizeof(buff));
      my_error(ER_REGEXP_ERROR, MYF(0), buff);
    }
    return TRUE;
    return 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();
  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
      maybe_null=1;
      fixed= 1;
      return FALSE;
    }
    if (regcomp(TRUE))
    else if (comp_res)
      return TRUE;
    regex_is_const= 1;
    maybe_null= args[0]->maybe_null;
+1 −1
Original line number Diff line number Diff line
@@ -1323,7 +1323,7 @@ class Item_func_regex :public Item_bool_func
  CHARSET_INFO *regex_lib_charset;
  int regex_lib_flags;
  String conv;
  bool regcomp(bool send_error);
  int regcomp(bool send_error);
public:
  Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
    regex_compiled(0),regex_is_const(0) {}