diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-08-07 23:32:01 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-08-07 23:32:01 -0300 |
commit | c7163c630a7ab5c9770c9ae07355acc531f110a1 (patch) | |
tree | ffaa8e6fff678b5b86aabefb449700837770e903 /sql/sql_lex.cc | |
parent | a791f20089a6e5a0f89f93aa427b43c7ec920079 (diff) | |
download | mariadb-git-c7163c630a7ab5c9770c9ae07355acc531f110a1.tar.gz |
Bug#45010: invalid memory reads during parsing some strange statements
The problem is that the lexer could inadvertently skip over the
end of a query being parsed if it encountered a malformed multibyte
character. A specially crated query string could cause the lexer
to jump up to six bytes past the end of the query buffer. Another
problem was that the laxer could use unfiltered user input as
a signed array index for the parser maps (having upper and lower
bounds 0 and 256 respectively).
The solution is to ensure that the lexer only skips over well-formed
multibyte characters and that the index value of the parser maps
is always a unsigned value.
mysql-test/r/ctype_recoding.result:
Update test case result: ending backtick is not skipped over anymore.
sql/sql_lex.cc:
Characters being analyzed must be unsigned as they can be
used as indexes for the parser maps. Only skip over if the
string is a valid multi-byte sequence.
tests/mysql_client_test.c:
Add test case for Bug#45010
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r-- | sql/sql_lex.cc | 16 |
1 files changed, 9 insertions, 7 deletions
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) |