From: Date: July 14 2005 11:19am Subject: bk commit into 5.0 tree (bell:1.2002) BUG#7291 List-Archive: http://lists.mysql.com/internals/27055 X-Bug: 7291 Message-Id: <20050714091947.A74AD455F1E@sanja.is.com.ua> Below is the list of changes that have just been committed into a local 5.0 repository of bell. When bell does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2002 05/07/14 12:19:41 bell@stripped +12 -0 stop evaluation constant functions in WHERE (BUG#4663) correct value of CURRENT_USER() in SP with "security definer" (BUG#7291) BitKeeper/etc/config 1.12 05/07/14 12:19:24 bell@stripped +1 -1 switch off open logging sql/sql_yacc.yy 1.402 05/07/14 12:15:04 bell@stripped +1 -1 Item_func_user now support both USER() and CURRENT_USER(), so we have to pass parametr what it is sql/item_strfunc.h 1.93 05/07/14 12:15:04 bell@stripped +15 -2 support of correct charset conversion procedure in Item_func_sysconst sql/item_strfunc.cc 1.234 05/07/14 12:15:04 bell@stripped +22 -7 Item_func_sysconst in case of converting value still have to correctly print itself => use Item_static_string_func instead of Item_string Item_func_user return USER() or CURRENT_USER() sql/item_create.cc 1.54 05/07/14 12:15:04 bell@stripped +2 -10 create Item_func_user sql/item_cmpfunc.cc 1.158 05/07/14 12:15:04 bell@stripped +21 -18 do not evaluate items during view creation sql/item.h 1.145 05/07/14 12:15:04 bell@stripped +6 -0 support of Item_static_string_func creation sql/item.cc 1.142 05/07/14 12:15:04 bell@stripped +21 -10 Item_static_string_func creation if it is need mysql-test/t/view.test 1.74 05/07/14 12:15:04 bell@stripped +21 -0 evaluation constant functions in WHERE (BUG#4663) mysql-test/t/sp-security.test 1.16 05/07/14 12:15:04 bell@stripped +27 -0 correct value from current_user() in function run from "security definer" mysql-test/r/view.result 1.86 05/07/14 12:15:04 bell@stripped +25 -0 evaluation constant functions in WHERE (BUG#4663) mysql-test/r/sp-security.result 1.14 05/07/14 12:15:04 bell@stripped +21 -0 correct value from current_user() in function run from "security definer" # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: bell # Host: sanja.is.com.ua # Root: /home/bell/mysql/bk/work-bug6-5.0 --- 1.141/sql/item.cc 2005-06-22 23:56:00 +03:00 +++ 1.142/sql/item.cc 2005-07-14 12:15:04 +03:00 @@ -616,17 +616,28 @@ uint conv_errors; String tmp, cstr, *ostr= val_str(&tmp); cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); - if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(), - cstr.charset(), - collation.derivation))) - { - /* - Safe conversion is not possible (or EOM). - We could not convert a string into the requested character set - without data loss. The target charset does not cover all the - characters from the string. Operation cannot be done correctly. - */ + if (conv_errors) return NULL; + { + const char* func_name= static_string_func(); + if (func_name) + conv= new Item_static_string_func(func_name, cstr.ptr(), cstr.length(), + cstr.charset(), + collation.derivation); + else + conv= new Item_string(cstr.ptr(), cstr.length(), + cstr.charset(), + collation.derivation); + if (!conv) + { + /* + Safe conversion is not possible (or EOM). + We could not convert a string into the requested character set + without data loss. The target charset does not cover all the + characters from the string. Operation cannot be done correctly. + */ + return NULL; + } } conv->str_value.copy(); /* Ensure that no one is going to change the result string */ --- 1.144/sql/item.h 2005-06-22 23:56:00 +03:00 +++ 1.145/sql/item.h 2005-07-14 12:15:04 +03:00 @@ -1209,6 +1209,11 @@ void print(String *str); // to prevent drop fixed flag (no need parent cleanup call) void cleanup() {} + /* + method to detect Item_static_string_func, and made correct item in + safe_charset_converter + */ + virtual const char * static_string_func() { return 0; } }; @@ -1221,6 +1226,7 @@ Derivation dv= DERIVATION_COERCIBLE) :Item_string(NullS, str, length, cs, dv), func_name(name_par) {} + const char * static_string_func() { return func_name; } void print(String *str) { str->append(func_name); } }; --- 1.157/sql/item_cmpfunc.cc 2005-06-17 22:26:18 +03:00 +++ 1.158/sql/item_cmpfunc.cc 2005-07-14 12:15:04 +03:00 @@ -237,30 +237,33 @@ set_cmp_func(); return; } - - if (args[0]->type() == FIELD_ITEM) + + if (!thd->lex->view_prepare_mode) { - Field *field=((Item_field*) args[0])->field; - if (field->can_be_compared_as_longlong()) + if (args[0]->type() == FIELD_ITEM) { - if (convert_constant_item(thd, field,&args[1])) + Field *field=((Item_field*) args[0])->field; + if (field->can_be_compared_as_longlong()) { - cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, - INT_RESULT); // Works for all types. - return; + if (convert_constant_item(thd, field,&args[1])) + { + cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, + INT_RESULT); // Works for all types. + return; + } } } - } - if (args[1]->type() == FIELD_ITEM /* && !args[1]->const_item() */) - { - Field *field=((Item_field*) args[1])->field; - if (field->can_be_compared_as_longlong()) + if (args[1]->type() == FIELD_ITEM /* && !args[1]->const_item() */) { - if (convert_constant_item(thd, field,&args[0])) + Field *field=((Item_field*) args[1])->field; + if (field->can_be_compared_as_longlong()) { - cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, - INT_RESULT); // Works for all types. - return; + if (convert_constant_item(thd, field,&args[0])) + { + cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, + INT_RESULT); // Works for all types. + return; + } } } } @@ -991,7 +994,7 @@ if (args[0]->type() == FIELD_ITEM) { Field *field=((Item_field*) args[0])->field; - if (field->can_be_compared_as_longlong()) + if (!thd->lex->view_prepare_mode && field->can_be_compared_as_longlong()) { /* The following can't be recoded with || as convert_constant_item --- 1.53/sql/item_create.cc 2005-04-11 17:29:42 +03:00 +++ 1.54/sql/item_create.cc 2005-07-14 12:15:04 +03:00 @@ -299,16 +299,8 @@ Item *create_func_current_user() { - THD *thd=current_thd; - char buff[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; - uint length; - - thd->lex->safe_to_cache_query= 0; - length= (uint) (strxmov(buff, thd->priv_user, "@", thd->priv_host, NullS) - - buff); - return new Item_static_string_func("current_user()", - thd->memdup(buff, length), length, - system_charset_info); + current_thd->lex->safe_to_cache_query= 0; + return new Item_func_user(TRUE); } Item *create_func_radians(Item *a) --- 1.233/sql/item_strfunc.cc 2005-06-17 17:27:43 +03:00 +++ 1.234/sql/item_strfunc.cc 2005-07-14 12:15:04 +03:00 @@ -1522,9 +1522,12 @@ uint conv_errors; String tmp, cstr, *ostr= val_str(&tmp); cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); - if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(), - cstr.charset(), - collation.derivation))) + if (conv_errors || + !(conv= new Item_static_string_func(func_call_representation(), + cstr.ptr(), + cstr.length(), + cstr.charset(), + collation.derivation))) { return NULL; } @@ -1554,13 +1557,24 @@ DBUG_ASSERT(fixed == 1); THD *thd=current_thd; CHARSET_INFO *cs= system_charset_info; - const char *host= thd->host_or_ip; + const char *host, *user; uint res_length; + if (current) + { + user= thd->priv_user; + host= thd->priv_host; + } + else + { + user= thd->user; + host= thd->host_or_ip; + } + // For system threads (e.g. replication SQL thread) user may be empty - if (!thd->user) + if (!user) return &my_empty_string; - res_length= (strlen(thd->user)+strlen(host)+2) * cs->mbmaxlen; + res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen; if (str->alloc(res_length)) { @@ -1568,11 +1582,12 @@ return 0; } res_length=cs->cset->snprintf(cs, (char*)str->ptr(), res_length, "%s@%s", - thd->user, host); + user, host); str->length(res_length); str->set_charset(cs); return str; } + void Item_func_soundex::fix_length_and_dec() { --- 1.92/sql/item_strfunc.h 2005-06-17 17:27:43 +03:00 +++ 1.93/sql/item_strfunc.h 2005-07-14 12:15:04 +03:00 @@ -356,6 +356,12 @@ Item_func_sysconst() { collation.set(system_charset_info,DERIVATION_SYSCONST); } Item *safe_charset_converter(CHARSET_INFO *tocs); + /* + Used to create correct Item name in new converted item in + safe_charset_converter, return string representation of this function + call + */ + virtual const char *func_call_representation() const = 0; }; class Item_func_database :public Item_func_sysconst @@ -369,18 +375,25 @@ maybe_null=1; } const char *func_name() const { return "database"; } + const char *func_call_representation() const { return "database()"; } }; + class Item_func_user :public Item_func_sysconst { + bool current; + public: - Item_func_user() :Item_func_sysconst() {} + Item_func_user(bool current_arg) + :Item_func_sysconst(), current(current_arg) {} String *val_str(String *); void fix_length_and_dec() { max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*system_charset_info->mbmaxlen; } - const char *func_name() const { return "user"; } + const char *func_name() const { return current ? "current_user" : "user"; } + const char *func_call_representation() const + { return current ? "current_user()" : "user()"; } }; --- 1.401/sql/sql_yacc.yy 2005-06-23 00:02:41 +03:00 +++ 1.402/sql/sql_yacc.yy 2005-07-14 12:15:04 +03:00 @@ -4794,7 +4794,7 @@ | UNIX_TIMESTAMP '(' expr ')' { $$= new Item_func_unix_timestamp($3); } | USER '(' ')' - { $$= new Item_func_user(); Lex->safe_to_cache_query=0; } + { $$= new Item_func_user(FALSE); Lex->safe_to_cache_query=0; } | UTC_DATE_SYM optional_braces { $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;} | UTC_TIME_SYM optional_braces --- 1.85/mysql-test/r/view.result 2005-06-22 08:52:02 +03:00 +++ 1.86/mysql-test/r/view.result 2005-07-14 12:15:04 +03:00 @@ -1831,3 +1831,28 @@ t 01:00 drop view v1; +create table t1 (a timestamp default now()); +create table t2 (b timestamp default now()); +create view v1 as select a,b,t1.a < now() from t1,t2 where t1.a < now(); +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b`,(`test`.`t1`.`a` < now()) AS `t1.a < now()` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` < now()) +drop view v1; +drop table t1, t2; +CREATE TABLE t1 ( a varchar(50) ); +CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = CURRENT_USER(); +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = current_user()) +DROP VIEW v1; +CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = VERSION(); +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = version()) +DROP VIEW v1; +CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = DATABASE(); +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = database()) +DROP VIEW v1; +DROP TABLE t1; --- 1.73/mysql-test/t/view.test 2005-06-22 08:42:00 +03:00 +++ 1.74/mysql-test/t/view.test 2005-07-14 12:15:04 +03:00 @@ -1673,3 +1673,24 @@ create view v1 as SELECT TIME_FORMAT(SEC_TO_TIME(3600),'%H:%i') as t; select * from v1; drop view v1; + +# +# evaluation constant functions in WHERE (BUG#4663) +# +create table t1 (a timestamp default now()); +create table t2 (b timestamp default now()); +create view v1 as select a,b,t1.a < now() from t1,t2 where t1.a < now(); +SHOW CREATE VIEW v1; +drop view v1; +drop table t1, t2; +CREATE TABLE t1 ( a varchar(50) ); +CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = CURRENT_USER(); +SHOW CREATE VIEW v1; +DROP VIEW v1; +CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = VERSION(); +SHOW CREATE VIEW v1; +DROP VIEW v1; +CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = DATABASE(); +SHOW CREATE VIEW v1; +DROP VIEW v1; +DROP TABLE t1; --- 1.11/BitKeeper/etc/config 2005-05-13 10:34:57 +03:00 +++ 1.12/BitKeeper/etc/config 2005-07-14 12:19:24 +03:00 @@ -24,7 +24,7 @@ # repository is commercial it can be an internal email address or "none" # to disable logging. # -logging: logging@stripped +logging: none # # If this field is set, all checkins will appear to be made by this user, # in effect making this a single user package. Single user packages are --- 1.13/mysql-test/r/sp-security.result 2005-05-17 11:50:38 +03:00 +++ 1.14/mysql-test/r/sp-security.result 2005-07-14 12:15:04 +03:00 @@ -194,3 +194,24 @@ drop database sptest; delete from mysql.user where user='usera' or user='userb' or user='userc'; delete from mysql.procs_priv where user='usera' or user='userb' or user='userc'; +use test; +select current_user(); +current_user() +root@localhost +select user(); +user() +root@localhost +create procedure bug7291_1 () sql security definer select current_user(); +create procedure bug7291_2 () sql security definer select user(); +grant execute on procedure bug7291_1 to user1@localhost; +grant execute on procedure bug7291_2 to user1@localhost; +call bug7291_1(); +current_user() +root@localhost +call bug7291_2(); +user() +user1@localhost +drop procedure bug7291_1; +drop procedure bug7291_2; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost; +drop user user1@localhost; --- 1.15/mysql-test/t/sp-security.test 2005-05-17 11:50:39 +03:00 +++ 1.16/mysql-test/t/sp-security.test 2005-07-14 12:15:04 +03:00 @@ -304,3 +304,30 @@ delete from mysql.user where user='usera' or user='userb' or user='userc'; delete from mysql.procs_priv where user='usera' or user='userb' or user='userc'; +# +# correct value from current_user() in function run from "security definer" +# (BUG#7291) +# +connection con1root; +use test; + +select current_user(); +select user(); +create procedure bug7291_1 () sql security definer select current_user(); +create procedure bug7291_2 () sql security definer select user(); +grant execute on procedure bug7291_1 to user1@localhost; +grant execute on procedure bug7291_2 to user1@localhost; + + +connect (user1,localhost,user1,,); +connection user1; + +call bug7291_1(); +call bug7291_2(); + +connection con1root; +drop procedure bug7291_1; +drop procedure bug7291_2; +disconnect user1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost; +drop user user1@localhost;