From b176870cf6e1413001652631c0658a9cf9089e48 Mon Sep 17 00:00:00 2001 From: "petr/cps@mysql.com/owlet." <> Date: Tue, 11 Jul 2006 15:54:52 +0400 Subject: [PATCH 01/13] Fix Bug#15205 "Select from CSV table without the datafile causes crash" --- mysql-test/r/csv.result | 10 ++++++++++ mysql-test/t/csv.test | 24 ++++++++++++++++++++++++ sql/examples/ha_tina.cc | 13 ++++++++----- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 3c87c1f4b92..f3e91a663b8 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5000,3 +5000,13 @@ insert t1 values (1),(2),(3),(4),(5); truncate table t1; affected rows: 0 drop table t1; +create table bug15205 (val int(11) default null) engine=csv; +create table bug15205_2 (val int(11) default null) engine=csv; +select * from bug15205; +ERROR HY000: Got error 1 from storage engine +select * from bug15205_2; +val +select * from bug15205; +val +drop table bug15205; +drop table bug15205_2; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index a028f6ced6d..8bd48b7da2c 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1384,3 +1384,27 @@ truncate table t1; -- truncate --disable_info drop table t1; +# +# Bug #15205 Select from CSV table without the datafile causes crash +# +# NOTE: the bug is not deterministic + +# The crash happens because the necessary cleanup after an error wasn't +# performed. Namely, the table share, inserted in the hash during table +# open, was not deleted from hash. At the same time the share was freed +# when an error was encountered. Thus, subsequent access to the hash +# resulted in scanning through deleted memory and we were geting a crash. +# that's why we need two tables in the bugtest + +create table bug15205 (val int(11) default null) engine=csv; +create table bug15205_2 (val int(11) default null) engine=csv; +--exec rm $MYSQLTEST_VARDIR/master-data/test/bug15205.CSV +# system error (can't open the datafile) +--error ER_GET_ERRNO +select * from bug15205; +select * from bug15205_2; +--exec touch $MYSQLTEST_VARDIR/master-data/test/bug15205.CSV +select * from bug15205; +drop table bug15205; +drop table bug15205_2; + diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 8ae82f97d0b..ebddfc244b8 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -184,16 +184,18 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table) share->table_name_length=length; share->table_name=tmp_name; strmov(share->table_name,table_name); - fn_format(data_file_name, table_name, "", ".CSV",MY_REPLACE_EXT|MY_UNPACK_FILENAME); + fn_format(data_file_name, table_name, "", ".CSV", + MY_REPLACE_EXT | MY_UNPACK_FILENAME); + + if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND, + MYF(0))) == -1) + goto error; + if (my_hash_insert(&tina_open_tables, (byte*) share)) goto error; thr_lock_init(&share->lock); pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST); - if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND, - MYF(0))) == -1) - goto error2; - /* We only use share->data_file for writing, so we scan to the end to append */ if (my_seek(share->data_file, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR) goto error2; @@ -212,6 +214,7 @@ error3: error2: thr_lock_delete(&share->lock); pthread_mutex_destroy(&share->mutex); + hash_delete(&tina_open_tables, (byte*) share); error: pthread_mutex_unlock(&tina_mutex); my_free((gptr) share, MYF(0)); From dbf62f252a7d0dbfa0fa0d99e18ff5f21e670c0a Mon Sep 17 00:00:00 2001 From: "tnurnberg@salvation.intern.azundris.com" <> Date: Mon, 7 Aug 2006 07:35:28 +0200 Subject: [PATCH 02/13] Bug #20987: str_to_date doesn't accept user variable for specification str_to_date() would sometimes render NULL if %D was used as rule other than last. since this was due to two pointers getting mixed up in the server, this behaviour seemed somewhat non-deterministic at SQL level. --- mysql-test/r/func_time.result | 34 ++++++++++++++++++++++++++++++++++ mysql-test/t/func_time.test | 32 +++++++++++++++++++++++++++++++- sql/item_timefunc.cc | 2 +- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index d8ba606a558..d8797fd454b 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -695,3 +695,37 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +SET @df:="%M %D, %Y"; +SELECT DATE_FORMAT('2005-10-31', "%M %D, %Y"); +DATE_FORMAT('2005-10-31', "%M %D, %Y") +October 31st, 2005 +SELECT DATE_FORMAT('2005-10-31', @df); +DATE_FORMAT('2005-10-31', @df) +October 31st, 2005 +SELECT STR_TO_DATE('October 31st, 2005', "%M %D, %Y"); +STR_TO_DATE('October 31st, 2005', "%M %D, %Y") +2005-10-31 +SELECT STR_TO_DATE('October 31st, 2005', @df); +STR_TO_DATE('October 31st, 2005', @df) +2005-10-31 +CREATE TABLE `dt` ( +d datetime, +ds char(30) +); +INSERT INTO `dt` (d) VALUES ('2005-10-31'), ('2005-11-30'); +SET @df:="%M %D, %Y"; +UPDATE dt SET ds = DATE_FORMAT(d, @df); +SELECT * FROM dt; +d ds +2005-10-31 00:00:00 October 31st, 2005 +2005-11-30 00:00:00 November 30th, 2005 +SELECT d, ds, STR_TO_DATE(ds, @df) FROM dt; +d ds STR_TO_DATE(ds, @df) +2005-10-31 00:00:00 October 31st, 2005 2005-10-31 +2005-11-30 00:00:00 November 30th, 2005 2005-11-30 +SELECT d, ds, STR_TO_DATE(ds, "%M %D, %Y") FROM dt; +d ds STR_TO_DATE(ds, "%M %D, %Y") +2005-10-31 00:00:00 October 31st, 2005 2005-10-31 +2005-11-30 00:00:00 November 30th, 2005 2005-11-30 +DROP TABLE `dt`; +End of 4.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index b8647a281d4..bf17efbd67e 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -368,4 +368,34 @@ create table t1 select now() - now(), curtime() - curtime(), show create table t1; drop table t1; -# End of 4.1 tests + + +# +# Bug #20987: str_to_date doesn't accept user variable for specification +# + +SET @df:="%M %D, %Y"; +SELECT DATE_FORMAT('2005-10-31', "%M %D, %Y"); +SELECT DATE_FORMAT('2005-10-31', @df); +SELECT STR_TO_DATE('October 31st, 2005', "%M %D, %Y"); +SELECT STR_TO_DATE('October 31st, 2005', @df); + +CREATE TABLE `dt` ( + d datetime, + ds char(30) +); + +INSERT INTO `dt` (d) VALUES ('2005-10-31'), ('2005-11-30'); +SET @df:="%M %D, %Y"; + +UPDATE dt SET ds = DATE_FORMAT(d, @df); + +SELECT * FROM dt; +SELECT d, ds, STR_TO_DATE(ds, @df) FROM dt; +SELECT d, ds, STR_TO_DATE(ds, "%M %D, %Y") FROM dt; + +DROP TABLE `dt`; + + + +--echo End of 4.1 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 44d9b422263..e3b71851824 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -223,7 +223,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, tmp= (char*) val + min(2, val_len); l_time->day= (int) my_strtoll10(val, &tmp, &error); /* Skip 'st, 'nd, 'th .. */ - val= tmp + min((int) (end-tmp), 2); + val= tmp + min((int) (val_end-tmp), 2); break; /* Hour */ From d6b00b72eb43559cb4857bc9d11ca8c8bb2af02b Mon Sep 17 00:00:00 2001 From: "cmiller@zippy.cornsilk.net" <> Date: Fri, 11 Aug 2006 15:31:06 -0400 Subject: [PATCH 03/13] Bug#21224: mysql_upgrade uses possibly insecure temporary files We open for writing a known location, which is exploitable with a symlink attack. Now, use the EXCLusive flag, so that the presence of anything at that location causes a failure. Try once to open safely, and if failure then remove that location and try again to open safely. If both fail, then raise an error. --- client/mysql_upgrade.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 3288b627554..053eb86b051 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -149,17 +149,29 @@ static int create_defaults_file(const char *path, const char *our_defaults_path) File our_defaults_file, defaults_file; char buffer[512]; char *buffer_end; + int failed_to_open_count= 0; int error; /* check if the defaults file is needed at all */ if (!opt_password) return 0; - defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY, +retry_open: + defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY | O_EXCL, MYF(MY_FAE | MY_WME)); if (defaults_file < 0) - return 1; + { + if (failed_to_open_count == 0) + { + remove(path); + failed_to_open_count+= 1; + goto retry_open; + } + else + return 1; + } + upgrade_defaults_created= 1; if (our_defaults_path) { From 72d55f38789334e71a9c1de97c9a611e25c6bd66 Mon Sep 17 00:00:00 2001 From: "tsmith/tim@siva.hindu.god" <> Date: Fri, 11 Aug 2006 17:09:19 -0600 Subject: [PATCH 04/13] Bug #20536: md5() with GROUP BY and UCS2 return different results on myisam/innodb Make the encryption functions MD5(), SHA1() and ENCRYPT() return binary results. Make MAKE_SET() and EXPORT_SET() use the correct character set for their default separator strings. --- mysql-test/r/ctype_ucs.result | 43 +++++++++++++++++++++++++++++++++++ mysql-test/t/ctype_ucs.test | 41 ++++++++++++++++++++++++++++++++- sql/item_strfunc.cc | 14 ++++++++---- sql/item_strfunc.h | 26 +++++++++++++++++---- 4 files changed, 115 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index bcf9cc77519..3a65287ffc5 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -722,3 +722,46 @@ id MIN(s) 1 ZZZ 2 ZZZ DROP TABLE t1; +drop table if exists bug20536; +set names latin1; +create table bug20536 (id bigint not null auto_increment primary key, name +varchar(255) character set ucs2 not null); +insert into `bug20536` (`id`,`name`) values (1, _latin1 x'74657374311a'), (2, "'test\\_2'"); +select md5(name) from bug20536; +md5(name) +3417d830fe24ffb2f81a28e54df2d1b3 +48d95db0d8305c2fe11548a3635c9385 +select sha1(name) from bug20536; +sha1(name) +72228a6d56efb7a89a09543068d5d8fa4c330881 +677d4d505355eb5b0549b865fcae4b7f0c28aef5 +select make_set(3, name, upper(name)) from bug20536; +make_set(3, name, upper(name)) +test1,TEST1 +'test\_2','TEST\_2' +select export_set(5, name, upper(name)) from bug20536; +export_set(5, name, upper(name)) +test1,TEST1,test1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1 +'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2' +select export_set(5, name, upper(name), ",", 5) from bug20536; +export_set(5, name, upper(name), ",", 5) +test1,TEST1,test1,TEST1,TEST1 +'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2' +select password(name) from bug20536; +password(name) +???????????????????? +???????????????????? +select old_password(name) from bug20536; +old_password(name) +???????? +???????? +select encrypt(name, 'SALT') from bug20536; +encrypt(name, 'SALT') +SA5pDi1UPZdys +SA5pDi1UPZdys +select quote(name) from bug20536; +quote(name) +?????????? +???????????????? +drop table bug20536; +End of 4.1 tests diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index a4d4d1846a7..0ad38d98403 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -463,4 +463,43 @@ INSERT INTO t1 VALUES (1, 'ZZZZZ'), (1, 'ZZZ'), (2, 'ZZZ'), (2, 'ZZZZZ'); SELECT id, MIN(s) FROM t1 GROUP BY id; DROP TABLE t1; -# End of 4.1 tests + +# +# Bug #20536: md5() with GROUP BY and UCS2 return different results on myisam/innodb +# + +--disable_warnings +drop table if exists bug20536; +--enable_warnings + +set names latin1; +create table bug20536 (id bigint not null auto_increment primary key, name +varchar(255) character set ucs2 not null); +insert into `bug20536` (`id`,`name`) values (1, _latin1 x'74657374311a'), (2, "'test\\_2'"); +select md5(name) from bug20536; +select sha1(name) from bug20536; +select make_set(3, name, upper(name)) from bug20536; +select export_set(5, name, upper(name)) from bug20536; +select export_set(5, name, upper(name), ",", 5) from bug20536; + +# Some broken functions: add these tests just to document current behavior. + +# PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would +# not be backwards compatible in all cases, so it's best to leave it alone +select password(name) from bug20536; +select old_password(name) from bug20536; + +# ENCRYPT relies on OS function crypt() which takes a NUL-terminated string; it +# doesn't return good results for strings with embedded 0 bytes. It won't be +# fixed unless we choose to re-implement the crypt() function ourselves to take +# an extra size_t string_length argument. +select encrypt(name, 'SALT') from bug20536; + +# QUOTE doesn't work with UCS2 data. It would require a total rewrite +# of Item_func_quote::val_str(), which isn't worthwhile until UCS2 is +# supported fully as a client character set. +select quote(name) from bug20536; + +drop table bug20536; + +--echo End of 4.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7bc7956283b..56a31d074ac 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -88,6 +88,7 @@ String *Item_func_md5::val_str(String *str) { DBUG_ASSERT(fixed == 1); String * sptr= args[0]->val_str(str); + str->set_charset(&my_charset_bin); if (sptr) { my_MD5_CTX context; @@ -134,6 +135,7 @@ String *Item_func_sha::val_str(String *str) { DBUG_ASSERT(fixed == 1); String * sptr= args[0]->val_str(str); + str->set_charset(&my_charset_bin); if (sptr) /* If we got value different from NULL */ { SHA1_CONTEXT context; /* Context used to generate SHA1 hash */ @@ -1529,7 +1531,7 @@ String *Item_func_encrypt::val_str(String *str) null_value= 1; return 0; } - str->set(tmp,(uint) strlen(tmp),res->charset()); + str->set(tmp, (uint) strlen(tmp), &my_charset_bin); str->copy(); pthread_mutex_unlock(&LOCK_crypt); return str; @@ -1926,7 +1928,7 @@ String *Item_func_make_set::val_str(String *str) return &my_empty_string; result= &tmp_str; } - if (tmp_str.append(',') || tmp_str.append(*res)) + if (tmp_str.append(",", 1, &my_charset_bin) || tmp_str.append(*res)) return &my_empty_string; } } @@ -2592,8 +2594,12 @@ String* Item_func_export_set::val_str(String* str) } break; case 3: - sep_buf.set(",", 1, default_charset()); - sep = &sep_buf; + { + /* errors is not checked - assume "," can always be converted */ + uint errors; + sep_buf.copy(",", 1, &my_charset_bin, collation.collation, &errors); + sep = &sep_buf; + } break; default: DBUG_ASSERT(0); // cannot happen diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index f800c17182b..d3e2d24099b 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -41,7 +41,10 @@ class Item_func_md5 :public Item_str_func { String tmp_value; public: - Item_func_md5(Item *a) :Item_str_func(a) {} + Item_func_md5(Item *a) :Item_str_func(a) + { + collation.set(&my_charset_bin); + } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "md5"; } @@ -51,7 +54,10 @@ public: class Item_func_sha :public Item_str_func { public: - Item_func_sha(Item *a) :Item_str_func(a) {} + Item_func_sha(Item *a) :Item_str_func(a) + { + collation.set(&my_charset_bin); + } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "sha"; } @@ -306,9 +312,21 @@ public: class Item_func_encrypt :public Item_str_func { String tmp_value; + + /* Encapsulate common constructor actions */ + void constructor_helper() + { + collation.set(&my_charset_bin); + } public: - Item_func_encrypt(Item *a) :Item_str_func(a) {} - Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) {} + Item_func_encrypt(Item *a) :Item_str_func(a) + { + constructor_helper(); + } + Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) + { + constructor_helper(); + } String *val_str(String *); void fix_length_and_dec() { maybe_null=1; max_length = 13; } const char *func_name() const { return "ecrypt"; } From 53bb6a47cd67fb988c5cf6f1fff48b5a5023bcd1 Mon Sep 17 00:00:00 2001 From: "cmiller@maint1.mysql.com" <> Date: Tue, 15 Aug 2006 18:41:21 +0200 Subject: [PATCH 05/13] Bug #20908: Crash if select @@"" Zero-length variables caused failures when using the length to look up the name in a hash. Instead, signal that no zero-length name can ever be found and that to encounter one is a syntax error. --- mysql-test/r/variables.result | 6 ++++++ mysql-test/t/variables.test | 11 +++++++++++ sql/gen_lex_hash.cc | 13 +++++++++++-- sql/sql_lex.cc | 2 ++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index a0e516d2397..cd834a789bd 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -689,6 +689,12 @@ select @@log_queries_not_using_indexes; show variables like 'log_queries_not_using_indexes'; Variable_name Value log_queries_not_using_indexes OFF +select @@""; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '""' at line 1 +select @@&; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '&' at line 1 +select @@@; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@' at line 1 End of 5.0 tests set global binlog_cache_size =@my_binlog_cache_size; set global connect_timeout =@my_connect_timeout; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 68efcafd1e0..d855b4d8266 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -585,6 +585,16 @@ show variables like 'ssl%'; select @@log_queries_not_using_indexes; show variables like 'log_queries_not_using_indexes'; +# +# Bug#20908: Crash if select @@"" +# +--error ER_PARSE_ERROR +select @@""; +--error ER_PARSE_ERROR +select @@&; +--error ER_PARSE_ERROR +select @@@; + --echo End of 5.0 tests # This is at the very after the versioned tests, since it involves doing @@ -620,3 +630,4 @@ set global server_id =@my_server_id; set global slow_launch_time =@my_slow_launch_time; set global storage_engine =@my_storage_engine; set global thread_cache_size =@my_thread_cache_size; + diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 7e0b178f7af..e59986092e4 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -442,13 +442,16 @@ int main(int argc,char **argv) if (get_options(argc,(char **) argv)) exit(1); + /* Broken up to indicate that it's not advice to you, gentle reader. */ + printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n"); + printf("/* Copyright (C) 2001-2004 MySQL AB\n\ This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ and you are welcome to modify and redistribute it under the GPL license\n\ \n*/\n\n"); - printf("/* This code is generated by gen_lex_hash.cc that seeks for\ - a perfect\nhash function */\n\n"); + printf("/* Do " "not " "edit " "this " "file! This is generated by " + "gen_lex_hash.cc\nthat seeks for a perfect hash function */\n\n"); printf("#include \"lex.h\"\n\n"); calc_length(); @@ -468,6 +471,12 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\ {\n\ register uchar *hash_map;\n\ register const char *cur_str= s;\n\ +\n\ + if (len == 0) {\n\ + DBUG_PRINT(\"warning\", (\"get_hash_symbol() received a request for a zero-length symbol, which is probably a mistake.\"));\ + return(NULL);\n\ + }\ +\n\ if (function){\n\ if (len>sql_functions_max_len) return 0;\n\ hash_map= sql_functions_map;\n\ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7d4dca15608..479db7b5b99 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1042,6 +1042,8 @@ int MYSQLlex(void *arg, void *yythd) if (c == '.') lex->next_state=MY_LEX_IDENT_SEP; length= (uint) (lex->ptr - lex->tok_start)-1; + if (length == 0) + return(ABORT_SYM); // Names must be nonempty. if ((tokval= find_keyword(lex,length,0))) { yyUnget(); // Put back 'c' From 88b91d1e020ec91af90cb82c4f426efc7711c5ed Mon Sep 17 00:00:00 2001 From: "jani@ua141d10.elisa.omakaista.fi" <> Date: Wed, 16 Aug 2006 19:30:46 +0300 Subject: [PATCH 06/13] Fix for bug#21537, "Error at startup" These variables must be defined for Netware, or it fails to recognize hard paths starting from the device. --- include/config-netware.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/config-netware.h b/include/config-netware.h index 5a8b926a669..a3cd6635bae 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -101,6 +101,10 @@ extern "C" { /* On NetWare, to fix the problem with the deletion of open files */ #define CANT_DELETE_OPEN_FILES 1 +#define FN_LIBCHAR '\\' +#define FN_ROOTDIR "\\" +#define FN_DEVCHAR ':' + /* default directory information */ #define DEFAULT_MYSQL_HOME "sys:/mysql" #define PACKAGE "mysql" From 442c111b72561a514412c6bec31ad4dd6f7cd190 Mon Sep 17 00:00:00 2001 From: "kent@mysql.com/g4-2.local" <> Date: Tue, 22 Aug 2006 11:48:58 +0200 Subject: [PATCH 07/13] mysql.spec.sh: Added ndb_size.{pl,tmpl} to the RPM install (bug#20426) --- support-files/mysql.spec.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 454ec522f0e..befd9f48fed 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -647,6 +647,8 @@ fi %attr(755, root, root) %{_bindir}/ndb_show_tables %attr(755, root, root) %{_bindir}/ndb_test_platform %attr(755, root, root) %{_bindir}/ndb_config +%attr(755, root, root) %{_bindir}/ndb_size.pl +%attr(-, root, root) %{_datadir}/mysql/ndb_size.tmpl %files ndb-extra %defattr(-,root,root,0755) From c8b6563dfc0bf677d34aed18426800d5d77de270 Mon Sep 17 00:00:00 2001 From: "kent@mysql.com/g4-2.local" <> Date: Tue, 22 Aug 2006 11:55:08 +0200 Subject: [PATCH 08/13] mysql.spec.sh: Added ndb_error_reporter to the RPM install (bug#20426) --- support-files/mysql.spec.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 89cf998f8fd..f5db4e8ae18 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -675,6 +675,7 @@ fi %attr(755, root, root) %{_bindir}/ndb_show_tables %attr(755, root, root) %{_bindir}/ndb_test_platform %attr(755, root, root) %{_bindir}/ndb_config +%attr(755, root, root) %{_bindir}/ndb_error_reporter %attr(755, root, root) %{_bindir}/ndb_size.pl %attr(-, root, root) %{_datadir}/mysql/ndb_size.tmpl From 002adef0e184a3dd28ab162a27fce402c66e0f57 Mon Sep 17 00:00:00 2001 From: "tnurnberg@salvation.intern.azundris.com" <> Date: Tue, 22 Aug 2006 14:29:48 +0200 Subject: [PATCH 09/13] Bug#20411: "GRANT ... REQUIRE ISSUER nnn AND SUBJECT mmm" fails to require both when X.509 subject was required for a connect, we tested whether it was the right one, but did not refuse the connexion if not. fixed. (corrected CS now --replace_results socket-path) --- mysql-test/r/openssl_1.result | 9 ++++++--- mysql-test/t/openssl_1.test | 10 +++++++--- sql/sql_acl.cc | 9 ++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 1fcfb11525e..8f9fd50eced 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -3,9 +3,12 @@ create table t1(f1 int); insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/emailAddress=abstract.mysql.developer@mysql.com"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; +connect(localhost,ssl_user5,,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'ssl_user5'@'localhost' (using password: NO) SHOW STATUS LIKE 'Ssl_cipher'; Variable_name Value Ssl_cipher DHE-RSA-AES256-SHA @@ -39,7 +42,7 @@ f1 delete from t1; ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1' drop user ssl_user1@localhost, ssl_user2@localhost, -ssl_user3@localhost, ssl_user4@localhost; +ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; drop table t1; mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index afee381f5b7..49f8fc4d7d4 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -10,14 +10,18 @@ insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/emailAddress=abstract.mysql.developer@mysql.com"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; connect (con1,localhost,ssl_user1,,,,,SSL); connect (con2,localhost,ssl_user2,,,,,SSL); connect (con3,localhost,ssl_user3,,,,,SSL); connect (con4,localhost,ssl_user4,,,,,SSL); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (con5,localhost,ssl_user5,,,,,SSL); connection con1; # Check ssl turned on @@ -49,7 +53,7 @@ delete from t1; connection default; drop user ssl_user1@localhost, ssl_user2@localhost, -ssl_user3@localhost, ssl_user4@localhost; +ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; drop table t1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3735f4403de..11e40473ffc 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -874,6 +874,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, sql_print_information("X509 issuer mismatch: should be '%s' " "but is '%s'", acl_user->x509_issuer, ptr); free(ptr); + user_access=NO_ACCESS; break; } user_access= acl_user->access; @@ -889,11 +890,13 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, if (strcmp(acl_user->x509_subject,ptr)) { if (global_system_variables.log_warnings) - sql_print_information("X509 subject mismatch: '%s' vs '%s'", + sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", acl_user->x509_subject, ptr); + free(ptr); + user_access=NO_ACCESS; + break; } - else - user_access= acl_user->access; + user_access= acl_user->access; free(ptr); } break; From 977e6966779db2177927a1662e198ec11faa5678 Mon Sep 17 00:00:00 2001 From: "cmiller@maint1.mysql.com" <> Date: Wed, 23 Aug 2006 19:14:58 +0200 Subject: [PATCH 10/13] Bug #20908: Crash if select @@"" Zero-length variables caused failures when using the length to look up the name in a hash. Instead, signal that no zero-length name can ever be found and that to encounter one is a syntax error. --- mysql-test/r/variables.result | 6 ++++++ mysql-test/t/variables.test | 11 +++++++++++ sql/gen_lex_hash.cc | 11 +++++++++-- sql/sql_lex.cc | 2 ++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index a0e516d2397..cd834a789bd 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -689,6 +689,12 @@ select @@log_queries_not_using_indexes; show variables like 'log_queries_not_using_indexes'; Variable_name Value log_queries_not_using_indexes OFF +select @@""; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '""' at line 1 +select @@&; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '&' at line 1 +select @@@; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@' at line 1 End of 5.0 tests set global binlog_cache_size =@my_binlog_cache_size; set global connect_timeout =@my_connect_timeout; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 68efcafd1e0..d855b4d8266 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -585,6 +585,16 @@ show variables like 'ssl%'; select @@log_queries_not_using_indexes; show variables like 'log_queries_not_using_indexes'; +# +# Bug#20908: Crash if select @@"" +# +--error ER_PARSE_ERROR +select @@""; +--error ER_PARSE_ERROR +select @@&; +--error ER_PARSE_ERROR +select @@@; + --echo End of 5.0 tests # This is at the very after the versioned tests, since it involves doing @@ -620,3 +630,4 @@ set global server_id =@my_server_id; set global slow_launch_time =@my_slow_launch_time; set global storage_engine =@my_storage_engine; set global thread_cache_size =@my_thread_cache_size; + diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 7e0b178f7af..89af0d30076 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -447,8 +447,9 @@ int main(int argc,char **argv) and you are welcome to modify and redistribute it under the GPL license\n\ \n*/\n\n"); - printf("/* This code is generated by gen_lex_hash.cc that seeks for\ - a perfect\nhash function */\n\n"); + /* Broken up to indicate that it's not advice to you, gentle reader. */ + printf("/* Do " "not " "edit " "this " "file! This is generated by " + "gen_lex_hash.cc\nthat seeks for a perfect hash function */\n\n"); printf("#include \"lex.h\"\n\n"); calc_length(); @@ -468,6 +469,12 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\ {\n\ register uchar *hash_map;\n\ register const char *cur_str= s;\n\ +\n\ + if (len == 0) {\n\ + DBUG_PRINT(\"warning\", (\"get_hash_symbol() received a request for a zero-length symbol, which is probably a mistake.\"));\ + return(NULL);\n\ + }\ +\n\ if (function){\n\ if (len>sql_functions_max_len) return 0;\n\ hash_map= sql_functions_map;\n\ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7d4dca15608..479db7b5b99 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1042,6 +1042,8 @@ int MYSQLlex(void *arg, void *yythd) if (c == '.') lex->next_state=MY_LEX_IDENT_SEP; length= (uint) (lex->ptr - lex->tok_start)-1; + if (length == 0) + return(ABORT_SYM); // Names must be nonempty. if ((tokval= find_keyword(lex,length,0))) { yyUnget(); // Put back 'c' From dba7b8e81c462e81256c95986d0b5daec9ba36ac Mon Sep 17 00:00:00 2001 From: "tsmith/tim@siva.hindu.god" <> Date: Wed, 23 Aug 2006 15:37:54 -0600 Subject: [PATCH 11/13] Bug #20402: DROP USER failure logged as ERROR rather than WARNING Remove some sql_print_error() calls which were triggered by user error (i.e., not server-level events at all). Also, convert an sql_print_error -> sql_print_information for a non-error server event. --- sql/slave.cc | 2 +- sql/sql_acl.cc | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index b2862a437bb..bceeca1055c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2946,7 +2946,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) rli->is_until_satisfied()) { char buf[22]; - sql_print_error("Slave SQL thread stopped because it reached its" + sql_print_information("Slave SQL thread stopped because it reached its" " UNTIL position %s", llstr(rli->until_pos(), buf)); /* Setting abort_slave flag because we do not want additional message about diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 204a38dfb64..5b3e2619d21 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3669,17 +3669,11 @@ int mysql_drop_user(THD *thd, List &list) { if (!(acl_user= check_acl_user(user_name, &counter))) { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; No such user", - user_name->user.str, - user_name->host.str); result= -1; continue; } if ((acl_user->access & ~0)) { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; Global privileges exists", - user_name->user.str, - user_name->host.str); result= -1; continue; } @@ -3700,9 +3694,6 @@ int mysql_drop_user(THD *thd, List &list) } if (counter != acl_dbs.elements) { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; Database privileges exists", - user_name->user.str, - user_name->host.str); result= -1; continue; } @@ -3723,9 +3714,6 @@ int mysql_drop_user(THD *thd, List &list) } if (counter != column_priv_hash.records) { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; Table privileges exists", - user_name->user.str, - user_name->host.str); result= -1; continue; } @@ -3791,9 +3779,6 @@ int mysql_revoke_all(THD *thd, List &list) { if (!check_acl_user(lex_user, &counter)) { - sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' not exists", - lex_user->user.str, - lex_user->host.str); result= -1; continue; } From a4f32ff2e85294f93cfe5513839fb75e0150facd Mon Sep 17 00:00:00 2001 From: "cmiller@zippy.cornsilk.net" <> Date: Wed, 23 Aug 2006 18:29:05 -0400 Subject: [PATCH 12/13] String broken up to avoid silly MICROS~1 string-size limit. --- .bzrignore | 1 + sql/gen_lex_hash.cc | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.bzrignore b/.bzrignore index 68e8120fae0..68365ad40c2 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1296,3 +1296,4 @@ vio/viotest-sslconnect.cpp vio/viotest.cpp zlib/*.ds? zlib/*.vcproj +sql/f.c diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 89af0d30076..1a7710dba0d 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -473,8 +473,10 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\ if (len == 0) {\n\ DBUG_PRINT(\"warning\", (\"get_hash_symbol() received a request for a zero-length symbol, which is probably a mistake.\"));\ return(NULL);\n\ - }\ -\n\ + }\n" +); + + printf("\ if (function){\n\ if (len>sql_functions_max_len) return 0;\n\ hash_map= sql_functions_map;\n\ @@ -505,7 +507,10 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\ cur_struct= uint4korr(hash_map+\n\ (((uint16)cur_struct + cur_char - first_char)*4));\n\ cur_str++;\n\ - }\n\ + }\n" +); + + printf("\ }else{\n\ if (len>symbols_max_len) return 0;\n\ hash_map= symbols_map;\n\ From 45460bd0afbf5f31111ee44f352622cd79402a0d Mon Sep 17 00:00:00 2001 From: "tsmith/tim@siva.hindu.god" <> Date: Wed, 23 Aug 2006 18:02:31 -0600 Subject: [PATCH 13/13] Bug #21531: EXPORT_SET() doesn't accept args with coercible character sets - Fix typo in Item_func_export_set::fix_length_and_dec() which caused character set aggregation to fail - Remove default argument from last arg of agg_arg_charsets() function, to reduce potential errors --- mysql-test/r/func_misc.result | 4 ++++ mysql-test/t/func_misc.test | 7 ++++++- sql/item_func.h | 3 +-- sql/item_strfunc.cc | 4 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 8bcdd8b7cbc..adf2035173f 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -93,3 +93,7 @@ SELECT IS_USED_LOCK('bug16501'); IS_USED_LOCK('bug16501') NULL DROP TABLE t1; +select export_set(3, _latin1'foo', _utf8'bar', ',', 4); +export_set(3, _latin1'foo', _utf8'bar', ',', 4) +foo,foo,bar,bar +End of 4.1 tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index e2641f8d6cd..a7dc9e7c966 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -83,4 +83,9 @@ connection default; DROP TABLE t1; -# End of 4.1 tests +# +# Bug #21531: EXPORT_SET() doesn't accept args with coercible character sets +# +select export_set(3, _latin1'foo', _utf8'bar', ',', 4); + +--echo End of 4.1 tests diff --git a/sql/item_func.h b/sql/item_func.h index 51f9d3fb36f..aaf74e4f7af 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -156,8 +156,7 @@ public: return agg_item_collations_for_comparison(c, func_name(), items, nitems, flags); } - bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, - uint flags= 0) + bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, uint flags) { return agg_item_charsets(c, func_name(), items, nitems, flags); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 56a31d074ac..a43f8b5a22a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2624,8 +2624,8 @@ void Item_func_export_set::fix_length_and_dec() uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); max_length=length*64+sep_length*63; - if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1), - MY_COLL_ALLOW_CONV) + if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1, + MY_COLL_ALLOW_CONV)) return; }