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.
This commit is contained in:
parent
290d724943
commit
6f72d99099
@ -26,3 +26,18 @@ select 1 # The rest of the row will be ignored
|
|||||||
1
|
1
|
||||||
1
|
1
|
||||||
/* line with only comment */;
|
/* line with only comment */;
|
||||||
|
drop table if exists table_28779;
|
||||||
|
create table table_28779 (a int);
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*' AND b = 'bar'' at line 1
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*' AND b = 'bar';*' at line 1
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';*' at line 1
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!98765' AND b = 'bar'' at line 1
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!98765' AND b = 'bar';*' at line 1
|
||||||
|
drop table table_28779;
|
||||||
|
@ -19,3 +19,36 @@ select 1 # The rest of the row will be ignored
|
|||||||
/* line with only comment */;
|
/* line with only comment */;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#28779 (mysql_query() allows execution of statements with unbalanced
|
||||||
|
# comments)
|
||||||
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists table_28779;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table table_28779 (a int);
|
||||||
|
|
||||||
|
--error 1064
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';";
|
||||||
|
|
||||||
|
--error 1064
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*";
|
||||||
|
|
||||||
|
--error 1064
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
|
||||||
|
|
||||||
|
--error 1064
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
|
||||||
|
|
||||||
|
--error 1064
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
|
||||||
|
|
||||||
|
--error 1064
|
||||||
|
prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
|
||||||
|
|
||||||
|
drop table table_28779;
|
||||||
|
|
||||||
|
@ -526,6 +526,7 @@ static inline uint int_token(const char *str,uint length)
|
|||||||
int MYSQLlex(void *arg, void *yythd)
|
int MYSQLlex(void *arg, void *yythd)
|
||||||
{
|
{
|
||||||
reg1 uchar c;
|
reg1 uchar c;
|
||||||
|
bool comment_closed;
|
||||||
int tokval, result_state;
|
int tokval, result_state;
|
||||||
uint length;
|
uint length;
|
||||||
enum my_lex_states state;
|
enum my_lex_states state;
|
||||||
@ -961,15 +962,34 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
break;
|
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')
|
c= yyGet();
|
||||||
lip->yylineno++;
|
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)
|
/* Unbalanced comments with a missing '*' '/' are a syntax error */
|
||||||
yySkip(); // remove last '/'
|
if (! comment_closed)
|
||||||
state = MY_LEX_START; // Try again
|
return (ABORT_SYM);
|
||||||
break;
|
break;
|
||||||
case MY_LEX_END_LONG_COMMENT:
|
case MY_LEX_END_LONG_COMMENT:
|
||||||
if (lex->in_comment && yyPeek() == '/')
|
if (lex->in_comment && yyPeek() == '/')
|
||||||
@ -1009,6 +1029,9 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
if (lip->ptr >= lip->end_of_query)
|
if (lip->ptr >= lip->end_of_query)
|
||||||
{
|
{
|
||||||
lip->next_state=MY_LEX_END; // Mark for next loop
|
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);
|
return(END_OF_INPUT);
|
||||||
}
|
}
|
||||||
state=MY_LEX_CHAR;
|
state=MY_LEX_CHAR;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user