summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-08-04 09:49:44 +0400
committerAlexander Barkov <bar@mariadb.com>2020-08-04 09:49:44 +0400
commitd4967659032b18a5504198b41dd3d0a1813d79ef (patch)
treef22108a6726433b43a5f4a6ce3642d0785d2f059 /sql/sql_lex.cc
parentb3e9798ff3fe4dcdda841dc72bd5d9a26db9eaa1 (diff)
downloadmariadb-git-d4967659032b18a5504198b41dd3d0a1813d79ef.tar.gz
MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
Lex_input_stream::scan_ident_delimited() could go beyond the end of the input when a starting backtick (`) delimiter did not have a corresponding ending backtick. Fix: catch the case when yyGet() returns 0, which means either eof-of-query or straight 0x00 byte inside backticks, and make the parser fail on syntax error, displaying the left backtick as the syntax error place. In case of filename in a script like this: SET CHARACTER_SET_CLIENT=17; -- 17 is 'filename' SELECT doc.`Children`.0 FROM t1; the ending backtick was not recognized as such because my_charlen() returns 0 for a straight backtick (backticks must normally be encoded as @0060 in filename). The same fix works for 'filename': the execution skips the backtick and reaches the end of the query, then yyGet() returns 0. This fix is OK for now. But eventually 'filename' should either be disallowed as a parser character set, or fixed to handle encoded punctuation properly.
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r--sql/sql_lex.cc11
1 files changed, 10 insertions, 1 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 89f74b6537b..1ef917f6964 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2206,8 +2206,17 @@ int Lex_input_stream::scan_ident_delimited(THD *thd,
uchar c, quote_char= m_tok_start[0];
DBUG_ASSERT(m_ptr == m_tok_start + 1);
- while ((c= yyGet()))
+ for ( ; ; )
{
+ if (!(c= yyGet()))
+ {
+ /*
+ End-of-query or straight 0x00 inside a delimited identifier.
+ Return the quote character, to have the parser fail on syntax error.
+ */
+ m_ptr= (char *) m_tok_start + 1;
+ return quote_char;
+ }
int var_length= my_charlen(cs, get_ptr() - 1, get_end_of_query());
if (var_length == 1)
{