List:Internals« Previous MessageNext Message »
From:sanja Date:July 15 2005 10:22pm
Subject:bk commit into 5.0 tree (bell:1.2002) BUG#7291
View as plain text  
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/15 23:22:43 bell@stripped +13 -0
  stop evaluation constant functions in WHERE (BUG#4663)
  correct value of CURRENT_USER() in SP with "security definer" (BUG#7291)

  sql/sql_yacc.yy
    1.402 05/07/15 23:22:37 bell@stripped +1 -1
    Item_func_user now support both USER() and CURRENT_USER(), so we have to pass parametr
what it is

  sql/sql_class.h
    1.244 05/07/15 23:22:36 bell@stripped +2 -0
    new method

  sql/item_strfunc.h
    1.93 05/07/15 23:22:36 bell@stripped +21 -5
    support of correct charset conversion procedure in Item_func_sysconst

  sql/item_strfunc.cc
    1.234 05/07/15 23:22:36 bell@stripped +21 -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/15 23:22:36 bell@stripped +2 -10
    create Item_func_user

  sql/item_cmpfunc.cc
    1.158 05/07/15 23:22:36 bell@stripped +22 -18
    do not evaluate items during view creation

  sql/item.h
    1.145 05/07/15 23:22:36 bell@stripped +1 -0
    support of Item_static_string_func creation

  sql/item.cc
    1.142 05/07/15 23:22:36 bell@stripped +27 -0
    Item_static_string_func creation if it is need

  mysql-test/t/view.test
    1.74 05/07/15 23:22:36 bell@stripped +21 -0
    evaluation constant functions in WHERE (BUG#4663)

  mysql-test/t/sp-security.test
    1.16 05/07/15 23:22:35 bell@stripped +29 -0
    correct value from current_user() in function run from "security definer"

  mysql-test/r/view.result
    1.86 05/07/15 23:22:35 bell@stripped +25 -0
    evaluation constant functions in WHERE (BUG#4663)

  mysql-test/r/sp-security.result
    1.14 05/07/15 23:22:35 bell@stripped +24 -0
    correct value from current_user() in function run from "security definer"

  BitKeeper/etc/config
    1.12 05/07/15 23:22:35 bell@stripped +1 -1
    switch off open logging

# 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-15 23:22:36 +03:00
@@ -635,6 +635,33 @@
 }
 
 
+Item *Item_static_string_func::safe_charset_converter(CHARSET_INFO *tocs)
+{
+  Item_string *conv;
+  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_static_string_func(func_name,
+                                          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.
+    */
+    return NULL;
+  }
+  conv->str_value.copy();
+  /* Ensure that no one is going to change the result string */
+  conv->str_value.mark_as_const();
+  return conv;
+}
+
+
 bool Item_string::eq(const Item *item, bool binary_cmp) const
 {
   if (type() == item->type() && item->basic_const_item())

--- 1.144/sql/item.h	2005-06-22 23:56:00 +03:00
+++ 1.145/sql/item.h	2005-07-15 23:22:36 +03:00
@@ -1221,6 +1221,7 @@
                           Derivation dv= DERIVATION_COERCIBLE)
     :Item_string(NullS, str, length, cs, dv), func_name(name_par)
   {}
+  Item *safe_charset_converter(CHARSET_INFO *tocs);
   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-15 23:22:36 +03:00
@@ -237,30 +237,33 @@
     set_cmp_func();
     return;
   }
-    
-  if (args[0]->type() == FIELD_ITEM)
+
+  if (!thd->is_context_analysis_only())
   {
-    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,8 @@
   if (args[0]->type() == FIELD_ITEM)
   {
     Field *field=((Item_field*) args[0])->field;
-    if (field->can_be_compared_as_longlong())
+    if (!thd->is_context_analysis_only() &&
+        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-15 23:22:36 +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-15 23:22:36 +03:00
@@ -1522,9 +1522,11 @@
   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 +1556,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 (is_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 +1581,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-15 23:22:36 +03:00
@@ -356,8 +356,15 @@
   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
 {
 public:
@@ -369,18 +376,27 @@
     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 is_current;
+
 public:
-  Item_func_user() :Item_func_sysconst() {}
+  Item_func_user(bool is_current_arg)
+    :Item_func_sysconst(), is_current(is_current_arg) {}
   String *val_str(String *);
-  void fix_length_and_dec() 
-  { 
-    max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*system_charset_info->mbmaxlen;
+  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 is_current ? "current_user" : "user"; }
+  const char *func_call_representation() const
+    { return is_current ? "current_user()" : "user()"; }
 };
 
 

--- 1.243/sql/sql_class.h	2005-06-22 22:12:19 +03:00
+++ 1.244/sql/sql_class.h	2005-07-15 23:22:36 +03:00
@@ -1417,6 +1417,8 @@
              (variables.sql_mode & MODE_STRICT_ALL_TABLES)));
   }
   void set_status_var_init();
+  bool is_context_analysis_only()
+    { return current_arena->is_stmt_prepare() || lex->view_prepare_mode; }
 };
 
 #define tmp_disable_binlog(A)       \

--- 1.401/sql/sql_yacc.yy	2005-06-23 00:02:41 +03:00
+++ 1.402/sql/sql_yacc.yy	2005-07-15 23:22:37 +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-15 23:22:35 +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-15 23:22:36 +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-15 23:22:35 +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-15 23:22:35 +03:00
@@ -194,3 +194,27 @@
 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_0 () sql security invoker select current_user(), user();
+create procedure bug7291_1 () sql security definer call bug7291_0();
+create procedure bug7291_2 () sql security invoker call bug7291_0();
+grant execute on procedure bug7291_0 to user1@localhost;
+grant execute on procedure bug7291_1 to user1@localhost;
+grant execute on procedure bug7291_2 to user1@localhost;
+call bug7291_2();
+current_user()	user()
+user1@localhost	user1@localhost
+call bug7291_1();
+current_user()	user()
+root@localhost	user1@localhost
+drop procedure bug7291_1;
+drop procedure bug7291_2;
+drop procedure bug7291_0;
+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-15 23:22:35 +03:00
@@ -304,3 +304,32 @@
 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_0 () sql security invoker select current_user(), user();
+create procedure bug7291_1 () sql security definer call bug7291_0();
+create procedure bug7291_2 () sql security invoker call bug7291_0();
+grant execute on procedure bug7291_0 to user1@localhost;
+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_2();
+call bug7291_1();
+
+connection con1root;
+drop procedure bug7291_1;
+drop procedure bug7291_2;
+drop procedure bug7291_0;
+disconnect user1;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
+drop user user1@localhost;
Thread
bk commit into 5.0 tree (bell:1.2002) BUG#7291sanja15 Jul