summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavi Arnaut <Davi.Arnaut@Sun.COM>2009-08-10 19:47:28 -0300
committerDavi Arnaut <Davi.Arnaut@Sun.COM>2009-08-10 19:47:28 -0300
commita19cb30283b873bd1809b2d6e5f34aaf052d08f5 (patch)
treef922cfa9e7f169151e93e3bb24093d910941844d
parentad624f1d0d0270de77958da59dabc6dd4ae9c303 (diff)
parent357430de54b391f52b7bb19d578132b386bfb163 (diff)
downloadmariadb-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.result2
-rw-r--r--sql/mysqld.cc17
-rw-r--r--sql/sql_lex.cc16
-rw-r--r--tests/mysql_client_test.c33
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 }
};