From: Date: September 5 2008 10:30am Subject: bzr commit into mysql-5.0 branch (ramil:2683) Bug#39021 List-Archive: http://lists.mysql.com/commits/53300 X-Bug: 39021 Message-Id: <200809050830.m858U9Qx013544@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/ram/mysql/mysql-5.0-5.1.29-rc/ 2683 Ramil Kalimullin 2008-09-05 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. modified: mysql-test/r/func_regexp.result mysql-test/t/func_regexp.test sql/item_cmpfunc.cc sql/item_cmpfunc.h per-file messages: 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. === modified file 'mysql-test/r/func_regexp.result' --- a/mysql-test/r/func_regexp.result 2007-10-30 08:21:44 +0000 +++ b/mysql-test/r/func_regexp.result 2008-09-05 08:30:01 +0000 @@ -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 === modified file 'mysql-test/t/func_regexp.test' --- a/mysql-test/t/func_regexp.test 2007-10-30 08:21:44 +0000 +++ b/mysql-test/t/func_regexp.test 2008-09-05 08:30:01 +0000 @@ -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 === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2008-07-30 11:07:37 +0000 +++ b/sql/item_cmpfunc.cc 2008-09-05 08:30:01 +0000 @@ -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, It 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; === modified file 'sql/item_cmpfunc.h' --- a/sql/item_cmpfunc.h 2008-01-23 15:03:58 +0000 +++ b/sql/item_cmpfunc.h 2008-09-05 08:30:01 +0000 @@ -1323,7 +1323,7 @@ class Item_func_regex :public Item_bool_ 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) {}