diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-08-10 19:47:28 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-08-10 19:47:28 -0300 |
commit | a19cb30283b873bd1809b2d6e5f34aaf052d08f5 (patch) | |
tree | f922cfa9e7f169151e93e3bb24093d910941844d | |
parent | ad624f1d0d0270de77958da59dabc6dd4ae9c303 (diff) | |
parent | 357430de54b391f52b7bb19d578132b386bfb163 (diff) | |
download | mariadb-git-a19cb30283b873bd1809b2d6e5f34aaf052d08f5.tar.gz |
Merge from mysql-5.0-bugteam.mysql-5.0.85clone-5.0.85-build
-rw-r--r-- | mysql-test/r/ctype_recoding.result | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 17 | ||||
-rw-r--r-- | sql/sql_lex.cc | 16 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 33 |
4 files changed, 58 insertions, 10 deletions
diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 3f8ab75957b..4d7d33933cf 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -165,7 +165,7 @@ CREATE TABLE `goodÐÌÏÈÏ` (a int); ERROR HY000: Invalid utf8 character string: 'ÐÌÏÈÏ' SET NAMES utf8; CREATE TABLE `goodÐÌÏÈÏ` (a int); -ERROR HY000: Invalid utf8 character string: 'ÐÌÏÈÏ` (a int)' +ERROR HY000: Invalid utf8 character string: 'ÐÌÏÈÏ' set names latin1; create table t1 (a char(10) character set koi8r, b text character set koi8r); insert into t1 values ('test','test'); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 37b3754d716..afbbf753813 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4006,15 +4006,28 @@ default_service_handling(char **argv, const char *account_name) { char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end; + const char *opt_delim; end= path_and_service + sizeof(path_and_service)-3; /* We have to quote filename if it contains spaces */ pos= add_quoted_string(path_and_service, file_path, end); if (*extra_opt) { - /* Add (possible quoted) option after file_path */ + /* + Add option after file_path. There will be zero or one extra option. It's + assumed to be --defaults-file=file but isn't checked. The variable (not + the option name) should be quoted if it contains a string. + */ *pos++= ' '; - pos= add_quoted_string(pos, extra_opt, end); + if (opt_delim= strchr(extra_opt, '=')) + { + size_t length= ++opt_delim - extra_opt; + strnmov(pos, extra_opt, length); + } + else + opt_delim= extra_opt; + + pos= add_quoted_string(pos, opt_delim, end); } /* We must have servicename last */ *pos++= ' '; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 061a20679e7..b0b4256184c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -32,10 +32,10 @@ sys_var_long_ptr trg_new_row_fake_var(0, 0); /* Macros to look like lex */ -#define yyGet() *(lip->ptr++) -#define yyGetLast() lip->ptr[-1] -#define yyPeek() lip->ptr[0] -#define yyPeek2() lip->ptr[1] +#define yyGet() ((uchar)*(lip->ptr++)) +#define yyGetLast() ((uchar)lip->ptr[-1]) +#define yyPeek() ((uchar)lip->ptr[0]) +#define yyPeek2() ((uchar)lip->ptr[1]) #define yyUnget() lip->ptr-- #define yySkip() lip->ptr++ #define yyLength() ((uint) (lip->ptr - lip->tok_start)-1) @@ -813,9 +813,11 @@ int MYSQLlex(void *arg, void *yythd) } } #ifdef USE_MB - else if (var_length < 1) - break; // Error - lip->ptr+= var_length-1; + else if (use_mb(cs)) + { + if ((var_length= my_ismbchar(cs, lip->ptr-1, lip->end_of_query))) + lip->ptr+= var_length-1; + } #endif } if (double_quotes) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 040ef4d050d..63137bdba93 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16647,6 +16647,38 @@ static void test_bug41078(void) DBUG_VOID_RETURN; } + +/** + Bug#45010: invalid memory reads during parsing some strange statements +*/ + +static void test_bug45010() +{ + int rc; + const char query1[]= "select a.\x80", + query2[]= "describe `table\xef"; + + DBUG_ENTER("test_bug45010"); + myheader("test_bug45010"); + + rc= mysql_query(mysql, "set names utf8"); + myquery(rc); + + /* \x80 (-128) could be used as a index of ident_map. */ + rc= mysql_real_query(mysql, query1, sizeof(query1) - 1); + DIE_UNLESS(rc); + + /* \xef (-17) could be used to skip 3 bytes past the buffer end. */ + rc= mysql_real_query(mysql, query2, sizeof(query2) - 1); + DIE_UNLESS(rc); + + rc= mysql_query(mysql, "set names default"); + myquery(rc); + + DBUG_VOID_RETURN; +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -16949,6 +16981,7 @@ static struct my_tests_st my_tests[]= { #endif { "test_bug41078", test_bug41078 }, { "test_bug20023", test_bug20023 }, + { "test_bug45010", test_bug45010 }, { 0, 0 } }; |