From d4967659032b18a5504198b41dd3d0a1813d79ef Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 4 Aug 2020 09:49:44 +0400 Subject: [PATCH] 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. --- mysql-test/main/ctype_filename.result | 7 +++++++ mysql-test/main/ctype_filename.test | 10 ++++++++++ mysql-test/main/parser.result | 7 +++++++ mysql-test/main/parser.test | 9 +++++++++ sql/sql_lex.cc | 11 ++++++++++- 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/ctype_filename.result b/mysql-test/main/ctype_filename.result index c6d7d1e39b9..7536ea97fb1 100644 --- a/mysql-test/main/ctype_filename.result +++ b/mysql-test/main/ctype_filename.result @@ -21,3 +21,10 @@ SET NAMES utf8; SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a)); @a BINARY @a REVERSE(@a) HEX(@a) HEX(REVERSE(@a)) aя a@r1 яa 61407231 40723161 +# +# MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +# +SET CHARACTER_SET_CLIENT=17; +SELECT doc.`Children`.0 FROM t1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?Children??0?FROM?t1' at line 1 +SET NAMES latin1; diff --git a/mysql-test/main/ctype_filename.test b/mysql-test/main/ctype_filename.test index 7ec07293a2b..6f77a6c5a3a 100644 --- a/mysql-test/main/ctype_filename.test +++ b/mysql-test/main/ctype_filename.test @@ -27,3 +27,13 @@ select convert(convert(',' using filename) using binary); --echo # SET NAMES utf8; SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a)); + + +--echo # +--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +--echo # + +SET CHARACTER_SET_CLIENT=17; +--error ER_PARSE_ERROR +SELECT doc.`Children`.0 FROM t1; +SET NAMES latin1; diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 002993eb128..f66fa7c457f 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -1760,4 +1760,11 @@ SELECT @@GLOBAL.password; ERROR HY000: Unknown system variable 'password' SELECT @@GLOBAL.role; ERROR HY000: Unknown system variable 'role' +# +# MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +# +EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`systeminfo /FO LIST' at line 1 +EXECUTE IMMEDIATE 'if(`systeminfo'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`systeminfo' at line 1 End of 10.3 tests diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test index 4ee335dbbb4..5a2d0294171 100644 --- a/mysql-test/main/parser.test +++ b/mysql-test/main/parser.test @@ -1538,4 +1538,13 @@ SELECT @@GLOBAL.password; --error ER_UNKNOWN_SYSTEM_VARIABLE SELECT @@GLOBAL.role; +--echo # +--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +--echo # + +--error ER_PARSE_ERROR +EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST'; +--error ER_PARSE_ERROR +EXECUTE IMMEDIATE 'if(`systeminfo'; + --echo End of 10.3 tests 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) {