summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp_notembedded.result14
-rw-r--r--mysql-test/r/strict.result46
-rw-r--r--mysql-test/t/sp_notembedded.test20
-rw-r--r--mysql-test/t/strict.test39
-rw-r--r--sql/handler.h3
-rw-r--r--sql/item.cc13
-rw-r--r--sql/item.h22
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_acl.cc73
-rw-r--r--sql/sql_parse.cc54
-rw-r--r--sql/sql_show.cc22
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_yacc.yy42
-rw-r--r--sql/table.cc4
-rw-r--r--sql/table.h2
-rw-r--r--sql/unireg.cc49
-rw-r--r--tests/mysql_client_test.c34
17 files changed, 375 insertions, 70 deletions
diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result
index c8cafe5ace1..bcde32572c2 100644
--- a/mysql-test/r/sp_notembedded.result
+++ b/mysql-test/r/sp_notembedded.result
@@ -206,3 +206,17 @@ drop procedure bug10100pd|
drop procedure bug10100pc|
drop view v1|
drop table t3|
+drop procedure if exists bug15298_1;
+drop procedure if exists bug15298_2;
+grant all privileges on test.* to 'mysqltest_1'@'localhost';
+create procedure 15298_1 () sql security definer show grants for current_user;
+create procedure 15298_2 () sql security definer show grants;
+call 15298_1();
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+call 15298_2();
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+drop user mysqltest_1@localhost;
+drop procedure 15298_1;
+drop procedure 15298_2;
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 271cd7bf486..d0cf11d0511 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -1298,3 +1298,49 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t2,t1;
set @@sql_mode= @org_mode;
+set @@sql_mode='traditional';
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*123456789*';
+ERROR HY000: Too long comment for table 't1'
+create table t1 (
+i int comment
+'123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+ERROR HY000: Too long comment for field 'i'
+set @@sql_mode= @org_mode;
+create table t1
+(i int comment
+'123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+Warnings:
+Warning 1105 Unknown error
+select column_name, column_comment from information_schema.columns where
+table_schema = 'test' and table_name = 't1';
+column_name column_comment
+i 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+drop table t1;
+set names utf8;
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*123456789*';
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*'
+drop table t1;
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
index 0adbeb2d98b..b087f699f86 100644
--- a/mysql-test/t/sp_notembedded.test
+++ b/mysql-test/t/sp_notembedded.test
@@ -265,3 +265,23 @@ drop view v1|
drop table t3|
delimiter ;|
+
+#
+# Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
+#
+--disable_warnings
+drop procedure if exists bug15298_1;
+drop procedure if exists bug15298_2;
+--enable_warnings
+grant all privileges on test.* to 'mysqltest_1'@'localhost';
+create procedure 15298_1 () sql security definer show grants for current_user;
+create procedure 15298_2 () sql security definer show grants;
+
+connect (con1,localhost,mysqltest_1,,test);
+call 15298_1();
+call 15298_2();
+
+connection default;
+drop user mysqltest_1@localhost;
+drop procedure 15298_1;
+drop procedure 15298_2;
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 5044a20ae9f..ce269b42ee9 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -1155,3 +1155,42 @@ create table t2 select date from t1;
show create table t2;
drop table t2,t1;
set @@sql_mode= @org_mode;
+
+#
+# Bug #13934 Silent truncation of table comments
+#
+set @@sql_mode='traditional';
+--error 1105
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*123456789*';
+--error 1105
+create table t1 (
+i int comment
+'123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+set @@sql_mode= @org_mode;
+create table t1
+(i int comment
+ '123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+
+select column_name, column_comment from information_schema.columns where
+table_schema = 'test' and table_name = 't1';
+drop table t1;
+
+set names utf8;
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*123456789*';
+show create table t1;
+drop table t1;
diff --git a/sql/handler.h b/sql/handler.h
index 31aac075a5e..6efb6e9e470 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -428,7 +428,8 @@ typedef struct st_ha_create_information
{
CHARSET_INFO *table_charset, *default_table_charset;
LEX_STRING connect_string;
- const char *comment,*password;
+ LEX_STRING comment;
+ const char *password;
const char *data_file_name, *index_file_name;
const char *alias;
ulonglong max_rows,min_rows;
diff --git a/sql/item.cc b/sql/item.cc
index 0448ef8dd65..a50356e331c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1469,7 +1469,18 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
}
-
+void Item_ident_for_show::make_field(Send_field *tmp_field)
+{
+ tmp_field->table_name= tmp_field->org_table_name= table_name;
+ tmp_field->db_name= db_name;
+ tmp_field->col_name= tmp_field->org_col_name= field->field_name;
+ tmp_field->charsetnr= field->charset()->number;
+ tmp_field->length=field->field_length;
+ tmp_field->type=field->type();
+ tmp_field->flags= field->table->maybe_null ?
+ (field->flags & ~NOT_NULL_FLAG) : field->flags;
+ tmp_field->decimals= 0;
+}
/**********************************************/
diff --git a/sql/item.h b/sql/item.h
index 2190ce78374..b7b9f972f67 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1134,6 +1134,28 @@ public:
bool any_privileges);
};
+
+class Item_ident_for_show :public Item
+{
+public:
+ Field *field;
+ const char *db_name;
+ const char *table_name;
+
+ Item_ident_for_show(Field *par_field, const char *db_arg,
+ const char *table_name_arg)
+ :field(par_field), db_name(db_arg), table_name(table_name_arg)
+ {}
+
+ enum Type type() const { return FIELD_ITEM; }
+ double val_real() { return field->val_real(); }
+ longlong val_int() { return field->val_int(); }
+ String *val_str(String *str) { return field->val_str(str); }
+ my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); }
+ void make_field(Send_field *tmp_field);
+};
+
+
class Item_equal;
class COND_EQUAL;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 3c58f2cbc6b..fcdfe1567e3 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -537,6 +537,7 @@ int append_query_string(CHARSET_INFO *csinfo,
void get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_default_definer(THD *thd);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
+LEX_USER *get_current_user(THD *thd, LEX_USER *user);
enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 124d3566b19..f7dac349d8a 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2766,7 +2766,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
{
ulong column_priv= 0;
List_iterator <LEX_USER> str_list (user_list);
- LEX_USER *Str;
+ LEX_USER *Str, *tmp_Str;
TABLE_LIST tables[3];
bool create_new_users=0;
char *db_name, *table_name;
@@ -2891,10 +2891,15 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
thd->mem_root= &memex;
grant_version++;
- while ((Str = str_list++))
+ while ((tmp_Str = str_list++))
{
int error;
GRANT_TABLE *grant_table;
+ if (!(Str= get_current_user(thd, tmp_Str)))
+ {
+ result= TRUE;
+ continue;
+ }
if (Str->host.length > HOSTNAME_LENGTH ||
Str->user.length > USERNAME_LENGTH)
{
@@ -3030,7 +3035,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
bool revoke_grant, bool no_error)
{
List_iterator <LEX_USER> str_list (user_list);
- LEX_USER *Str;
+ LEX_USER *Str, *tmp_Str;
TABLE_LIST tables[2];
bool create_new_users=0, result=0;
char *db_name, *table_name;
@@ -3098,10 +3103,15 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
DBUG_PRINT("info",("now time to iterate and add users"));
- while ((Str= str_list++))
+ while ((tmp_Str= str_list++))
{
int error;
GRANT_NAME *grant_name;
+ if (!(Str= get_current_user(thd, tmp_Str)))
+ {
+ result= TRUE;
+ continue;
+ }
if (Str->host.length > HOSTNAME_LENGTH ||
Str->user.length > USERNAME_LENGTH)
{
@@ -3170,7 +3180,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
ulong rights, bool revoke_grant)
{
List_iterator <LEX_USER> str_list (list);
- LEX_USER *Str;
+ LEX_USER *Str, *tmp_Str;
char tmp_db[NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
@@ -3229,8 +3239,13 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
grant_version++;
int result=0;
- while ((Str = str_list++))
+ while ((tmp_Str = str_list++))
{
+ if (!(Str= get_current_user(thd, tmp_Str)))
+ {
+ result= TRUE;
+ continue;
+ }
if (Str->host.length > HOSTNAME_LENGTH ||
Str->user.length > USERNAME_LENGTH)
{
@@ -5187,7 +5202,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
int result;
String wrong_users;
ulong sql_mode;
- LEX_USER *user_name;
+ LEX_USER *user_name, *tmp_user_name;
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
DBUG_ENTER("mysql_create_user");
@@ -5199,8 +5214,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
- while ((user_name= user_list++))
+ while ((tmp_user_name= user_list++))
{
+ if (!(user_name= get_current_user(thd, tmp_user_name)))
+ {
+ result= TRUE;
+ continue;
+ }
/*
Search all in-memory structures and grant tables
for a mention of the new user name.
@@ -5246,7 +5266,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
{
int result;
String wrong_users;
- LEX_USER *user_name;
+ LEX_USER *user_name, *tmp_user_name;
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
DBUG_ENTER("mysql_drop_user");
@@ -5258,8 +5278,14 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
- while ((user_name= user_list++))
+ while ((tmp_user_name= user_list++))
{
+ user_name= get_current_user(thd, tmp_user_name);
+ if (!(user_name= get_current_user(thd, tmp_user_name)))
+ {
+ result= TRUE;
+ continue;
+ }
if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
{
append_user(&wrong_users, user_name);
@@ -5296,8 +5322,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
{
int result;
String wrong_users;
- LEX_USER *user_from;
- LEX_USER *user_to;
+ LEX_USER *user_from, *tmp_user_from;
+ LEX_USER *user_to, *tmp_user_to;
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
DBUG_ENTER("mysql_rename_user");
@@ -5309,9 +5335,19 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
- while ((user_from= user_list++))
+ while ((tmp_user_from= user_list++))
{
- user_to= user_list++;
+ if (!(user_from= get_current_user(thd, tmp_user_from)))
+ {
+ result= TRUE;
+ continue;
+ }
+ tmp_user_to= user_list++;
+ if (!(user_to= get_current_user(thd, tmp_user_to)))
+ {
+ result= TRUE;
+ continue;
+ }
DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */
/*
@@ -5366,10 +5402,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
- LEX_USER *lex_user;
+ LEX_USER *lex_user, *tmp_lex_user;
List_iterator <LEX_USER> user_list(list);
- while ((lex_user=user_list++))
+ while ((tmp_lex_user= user_list++))
{
+ if (!(lex_user= get_current_user(thd, tmp_lex_user)))
+ {
+ result= -1;
+ continue;
+ }
if (!find_acl_user(lex_user->host.str, lex_user->user.str, TRUE))
{
sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not "
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4ffa56404a5..bde88d648ca 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3893,11 +3893,13 @@ end_with_restore_list:
if (thd->security_ctx->user) // If not replication
{
- LEX_USER *user;
+ LEX_USER *user, *tmp_user;
List_iterator <LEX_USER> user_list(lex->users_list);
- while ((user= user_list++))
+ while ((tmp_user= user_list++))
{
+ if (!(user= get_current_user(thd, tmp_user)))
+ goto error;
if (specialflag & SPECIAL_NO_RESOLVE &&
hostname_requires_resolving(user->host.str))
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -3979,9 +3981,13 @@ end_with_restore_list:
if (lex->sql_command == SQLCOM_GRANT)
{
List_iterator <LEX_USER> str_list(lex->users_list);
- LEX_USER *user;
- while ((user=str_list++))
+ LEX_USER *user, *tmp_user;
+ while ((tmp_user=str_list++))
+ {
+ if (!(user= get_current_user(thd, tmp_user)))
+ goto error;
reset_mqh(user);
+ }
}
}
}
@@ -4036,13 +4042,18 @@ end_with_restore_list:
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
case SQLCOM_SHOW_GRANTS:
+ {
+ LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
+ if (!grant_user)
+ goto error;
if ((thd->security_ctx->priv_user &&
- !strcmp(thd->security_ctx->priv_user, lex->grant_user->user.str)) ||
+ !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
!check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
{
- res = mysql_show_grants(thd,lex->grant_user);
+ res = mysql_show_grants(thd, grant_user);
}
break;
+ }
#endif
case SQLCOM_HA_OPEN:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -7501,3 +7512,34 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
return definer;
}
+
+
+/*
+ Retuns information about user or current user.
+
+ SYNOPSIS
+ get_current_user()
+ thd [in] thread handler
+ user [in] user
+
+ RETURN
+ On success, return a valid pointer to initialized
+ LEX_USER, which contains user information.
+ On error, return 0.
+*/
+
+LEX_USER *get_current_user(THD *thd, LEX_USER *user)
+{
+ LEX_USER *curr_user;
+ if (!user->user.str) // current_user
+ {
+ if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0), sizeof(LEX_USER));
+ return 0;
+ }
+ get_default_definer(thd, curr_user);
+ return curr_user;
+ }
+ return user;
+}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2c7a9b05cd9..cabb04c5f16 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -582,7 +582,14 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
{
if (!wild || !wild[0] ||
!wild_case_compare(system_charset_info, field->field_name,wild))
- field_list.push_back(new Item_field(field));
+ {
+ if (table_list->view)
+ field_list.push_back(new Item_ident_for_show(field,
+ table_list->view_db.str,
+ table_list->view_name.str));
+ else
+ field_list.push_back(new Item_field(field));
+ }
}
restore_record(table, s->default_values); // Get empty record
if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
@@ -1073,10 +1080,10 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
packet->append(ha_row_type[(uint) share->row_type]);
}
table->file->append_create_info(packet);
- if (share->comment && share->comment[0])
+ if (share->comment.length)
{
packet->append(STRING_WITH_LEN(" COMMENT="));
- append_unescaped(packet, share->comment, strlen(share->comment));
+ append_unescaped(packet, share->comment.str, share->comment.length);
}
if (share->connect_string.length)
{
@@ -2540,11 +2547,14 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
(uint) (ptr-option_buff)-1), cs);
{
char *comment;
- comment= show_table->file->update_table_comment(share->comment);
+ comment= show_table->file->update_table_comment(share->comment.str);
if (comment)
{
- table->field[20]->store(comment, strlen(comment), cs);
- if (comment != share->comment)
+ table->field[20]->store(comment,
+ (comment == share->comment.str ?
+ share->comment.length :
+ strlen(comment)), cs);
+ if (comment != share->comment.str)
my_free(comment, MYF(0));
}
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 91c71193df2..1d69c69b5cf 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3598,8 +3598,11 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
create_info->db_type=new_db_type;
- if (!create_info->comment)
- create_info->comment= table->s->comment;
+ if (!create_info->comment.str)
+ {
+ create_info->comment.str= table->s->comment.str;
+ create_info->comment.length= table->s->comment.length;
+ }
table->file->update_create_info(create_info);
if ((create_info->table_options &
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 952a8eb44ea..426c996ab01 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2529,7 +2529,7 @@ create_table_option:
| MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
| AVG_ROW_LENGTH opt_equal ulong_num { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
| PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; }
- | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; }
+ | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; }
| AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
| PACK_KEYS_SYM opt_equal ulong_num
{
@@ -6522,24 +6522,10 @@ show_param:
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_GRANTS;
- THD *thd= lex->thd;
- Security_context *sctx= thd->security_ctx;
LEX_USER *curr_user;
- if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
+ if (!(curr_user= (LEX_USER*) lex->thd->alloc(sizeof(st_lex_user))))
YYABORT;
- curr_user->user.str= sctx->priv_user;
- curr_user->user.length= strlen(sctx->priv_user);
- if (*sctx->priv_host != 0)
- {
- curr_user->host.str= sctx->priv_host;
- curr_user->host.length= strlen(sctx->priv_host);
- }
- else
- {
- curr_user->host.str= (char *) "%";
- curr_user->host.length= 1;
- }
- curr_user->password=null_lex_str;
+ bzero(curr_user, sizeof(st_lex_user));
lex->grant_user= curr_user;
}
| GRANTS FOR_SYM user
@@ -7489,22 +7475,14 @@ user:
}
| CURRENT_USER optional_braces
{
- THD *thd= YYTHD;
- Security_context *sctx= thd->security_ctx;
- if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
+ if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
YYABORT;
- $$->user.str= sctx->priv_user;
- $$->user.length= strlen(sctx->priv_user);
- if (*sctx->priv_host != 0)
- {
- $$->host.str= sctx->priv_host;
- $$->host.length= strlen(sctx->priv_host);
- }
- else
- {
- $$->host.str= (char *) "%";
- $$->host.length= 1;
- }
+ /*
+ empty LEX_USER means current_user and
+ will be handled in the get_current_user() function
+ later
+ */
+ bzero($$, sizeof(LEX_USER));
};
/* Keyword that we allow for identifiers (except SP labels) */
diff --git a/sql/table.cc b/sql/table.cc
index cfdb9bd93aa..83711577699 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -410,7 +410,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
int_length= uint2korr(head+274);
share->null_fields= uint2korr(head+282);
com_length= uint2korr(head+284);
- share->comment= strdup_root(&outparam->mem_root, (char*) head+47);
+ share->comment.length= (int) (head[46]);
+ share->comment.str= strmake_root(&outparam->mem_root, (char*) head+47,
+ share->comment.length);
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length));
diff --git a/sql/table.h b/sql/table.h
index ebb4481ef3a..d23d58e964f 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -124,7 +124,7 @@ typedef struct st_table_share
#endif
uint *blob_field; /* Index to blobs in Field arrray*/
byte *default_values; /* row with default values */
- char *comment; /* Comment about table */
+ LEX_STRING comment; /* Comment about table */
CHARSET_INFO *table_charset; /* Default charset of string fields */
/* A pair "database_name\0table_name\0", widely used as simply a db name */
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 0ab77462f61..3a139aea4c7 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -76,7 +76,7 @@ bool mysql_create_frm(THD *thd, my_string file_name,
handler *db_file)
{
LEX_STRING str_db_type;
- uint reclength,info_length,screens,key_info_length,maxlength;
+ uint reclength, info_length, screens, key_info_length, maxlength, tmp_len;
ulong key_buff_length;
File file;
ulong filepos, data_offset;
@@ -143,10 +143,30 @@ bool mysql_create_frm(THD *thd, my_string file_name,
fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
(create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length);
- strmake((char*) forminfo+47,create_info->comment ? create_info->comment : "",
- 60);
- forminfo[46]=(uchar) strlen((char*)forminfo+47); // Length of comment
+ tmp_len= system_charset_info->cset->charpos(system_charset_info,
+ create_info->comment.str,
+ create_info->comment.str +
+ create_info->comment.length, 60);
+ if (tmp_len < create_info->comment.length)
+ {
+ char buff[128];
+ (void) my_snprintf(buff, sizeof(buff), "Too long comment for table '%s'",
+ table);
+ if ((thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
+ {
+ my_message(ER_UNKNOWN_ERROR, buff, MYF(0));
+ goto err;
+ }
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), buff);
+ create_info->comment.length= tmp_len;
+ }
+
+ strmake((char*) forminfo+47, create_info->comment.str ?
+ create_info->comment.str : "", create_info->comment.length);
+ forminfo[46]=(uchar) create_info->comment.length;
if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) ||
my_pwrite(file,(byte*) keybuff,key_info_length,
(ulong) uint2korr(fileinfo+6),MYF_RW))
@@ -449,6 +469,27 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
create_field *field;
while ((field=it++))
{
+
+ uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
+ field->comment.str,
+ field->comment.str +
+ field->comment.length, 255);
+ if (tmp_len < field->comment.length)
+ {
+ char buff[128];
+ (void) my_snprintf(buff,sizeof(buff), "Too long comment for field '%s'",
+ field->field_name);
+ if ((current_thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
+ {
+ my_message(ER_UNKNOWN_ERROR, buff, MYF(0));
+ DBUG_RETURN(1);
+ }
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), buff);
+ field->comment.length= tmp_len;
+ }
+
totlength+= field->length;
com_length+= field->comment.length;
if (MTYP_TYPENR(field->unireg_check) == Field::NOEMPTY ||
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 0b3928e400b..7ad902afb6c 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -8311,6 +8311,39 @@ static void test_list_fields()
}
+static void test_bug19671()
+{
+ MYSQL_RES *result;
+ int rc;
+ myheader("test_bug19671");
+
+ rc= mysql_query(mysql, "drop table if exists t1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "drop view if exists v1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "create table t1(f1 int)");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
+ myquery(rc);
+
+ result= mysql_list_fields(mysql, "v1", NULL);
+ mytest(result);
+
+ rc= my_process_result_set(result);
+ DIE_UNLESS(rc == 0);
+
+ verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
+ "v1", "v1", current_db, 11, "0");
+
+ mysql_free_result(result);
+ myquery(mysql_query(mysql, "drop view v1"));
+ myquery(mysql_query(mysql, "drop table t1"));
+}
+
+
/* Test a memory ovverun bug */
static void test_mem_overun()
@@ -15254,6 +15287,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug20152", test_bug20152 },
{ "test_bug14169", test_bug14169 },
{ "test_bug17667", test_bug17667 },
+ { "test_bug19671", test_bug19671},
{ 0, 0 }
};