diff options
author | unknown <malff/marcsql@weblab.(none)> | 2007-08-29 14:50:32 -0600 |
---|---|---|
committer | unknown <malff/marcsql@weblab.(none)> | 2007-08-29 14:50:32 -0600 |
commit | b0f899e9779764aee7b08021a179599e27a209e8 (patch) | |
tree | 61bd01778d20b6437e16ed980da1cdd23f4ca5e1 /sql/sql_lex.cc | |
parent | 3d5440505cf530404b7b4d9ef544718ffb8c637f (diff) | |
download | mariadb-git-b0f899e9779764aee7b08021a179599e27a209e8.tar.gz |
Bug#28779 (mysql_query() allows execution of statements with unbalanced
comments)
Before this fix, the server would accept queries that contained comments,
even when the comments were not properly closed with a '*' '/' marker.
For example,
select 1 /* + 2 <EOF>
would be accepted as
select 1 /* + 2 */ <EOF>
and executed as
select 1
With this fix, the server now rejects queries with unclosed comments
as syntax errors.
Both regular comments ('/' '*') and special comments ('/' '*' '!') must be
closed with '*' '/' to be parsed correctly.
mysql-test/r/comments.result:
Unbalanced comments are a syntax error.
mysql-test/t/comments.test:
Unbalanced comments are a syntax error.
sql/sql_lex.cc:
Unbalanced comments are a syntax error.
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r-- | sql/sql_lex.cc | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7911da69862..1770ff358a2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -526,6 +526,7 @@ static inline uint int_token(const char *str,uint length) int MYSQLlex(void *arg, void *yythd) { reg1 uchar c; + bool comment_closed; int tokval, result_state; uint length; enum my_lex_states state; @@ -961,15 +962,34 @@ int MYSQLlex(void *arg, void *yythd) break; } } - while (lip->ptr != lip->end_of_query && - ((c=yyGet()) != '*' || yyPeek() != '/')) + /* + Discard: + - regular '/' '*' comments, + - special comments '/' '*' '!' for a future version, + by scanning until we find a closing '*' '/' marker. + Note: There is no such thing as nesting comments, + the first '*' '/' sequence seen will mark the end. + */ + comment_closed= FALSE; + while (lip->ptr != lip->end_of_query) { - if (c == '\n') - lip->yylineno++; + c= yyGet(); + if (c == '*') + { + if (yyPeek() == '/') + { + yySkip(); + comment_closed= TRUE; + state = MY_LEX_START; + break; + } + } + else if (c == '\n') + lip->yylineno++; } - if (lip->ptr != lip->end_of_query) - yySkip(); // remove last '/' - state = MY_LEX_START; // Try again + /* Unbalanced comments with a missing '*' '/' are a syntax error */ + if (! comment_closed) + return (ABORT_SYM); break; case MY_LEX_END_LONG_COMMENT: if (lex->in_comment && yyPeek() == '/') @@ -1009,6 +1029,9 @@ int MYSQLlex(void *arg, void *yythd) if (lip->ptr >= lip->end_of_query) { lip->next_state=MY_LEX_END; // Mark for next loop + /* Unbalanced comments with a missing '*' '/' are a syntax error */ + if (lex->in_comment) + return (ABORT_SYM); return(END_OF_INPUT); } state=MY_LEX_CHAR; |