List:Commits« Previous MessageNext Message »
From:marc.alff Date:August 30 2007 6:57pm
Subject:bk commit into 5.1 tree (malff:1.2589) BUG#28779
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of marcsql. When marcsql does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-08-30 12:57:05-06:00, malff@weblab.(none) +3 -0
  Bug#28779 (mysql_query() allows execution of statements with unbalanced
  comments)
  
  This change set is for 5.1 (manually merged)
  
  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@stripped, 2007-08-30 12:57:00-06:00, malff@weblab.(none) +15 -0
    Unbalanced comments are a syntax error.

  mysql-test/t/comments.test@stripped, 2007-08-30 12:57:00-06:00, malff@weblab.(none) +31 -0
    Unbalanced comments are a syntax error.

  sql/sql_lex.cc@stripped, 2007-08-30 12:57:00-06:00, malff@weblab.(none) +35 -8
    Unbalanced comments are a syntax error.

diff -Nrup a/mysql-test/r/comments.result b/mysql-test/r/comments.result
--- a/mysql-test/r/comments.result	2007-08-30 10:52:46 -06:00
+++ b/mysql-test/r/comments.result	2007-08-30 12:57:00 -06:00
@@ -36,3 +36,18 @@ select 1/*!999992*/;
 select 1 + /*!00000 2 */ + 3 /*!99999 noise*/ + 4;
 1 +  2  + 3  + 4
 10
+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;
diff -Nrup a/mysql-test/t/comments.test b/mysql-test/t/comments.test
--- a/mysql-test/t/comments.test	2007-08-30 10:52:54 -06:00
+++ b/mysql-test/t/comments.test	2007-08-30 12:57:00 -06:00
@@ -34,3 +34,34 @@ select 1/*!999992*/;
 
 select 1 + /*!00000 2 */ + 3 /*!99999 noise*/ + 4;
 
+#
+# 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;
+
diff -Nrup a/sql/sql_lex.cc b/sql/sql_lex.cc
--- a/sql/sql_lex.cc	2007-08-30 10:53:01 -06:00
+++ b/sql/sql_lex.cc	2007-08-30 12:57:00 -06:00
@@ -719,6 +719,7 @@ static inline uint int_token(const char 
 int MYSQLlex(void *arg, void *yythd)
 {
   reg1	uchar c;
+  bool comment_closed;
   int	tokval, result_state;
   uint length;
   enum my_lex_states state;
@@ -1211,7 +1212,10 @@ int MYSQLlex(void *arg, void *yythd)
         /*
           The special comment format is very strict:
           '/' '*' '!', followed by exactly
-          2 digits (major), then 3 digits (minor).
+          1 digit (major), 2 digits (minor), then 2 digits (dot).
+          32302 -> 3.23.02
+          50032 -> 5.0.32
+          50114 -> 5.1.14
         */
         char version_str[6];
         version_str[0]= lip->yyPeekn(0);
@@ -1230,7 +1234,7 @@ int MYSQLlex(void *arg, void *yythd)
           ulong version;
           version=strtol(version_str, NULL, 10);
 
-          /* Accept 'M' 'M' 'm' 'm' 'm' */
+          /* Accept 'M' 'm' 'm' 'd' 'd' */
           lip->yySkipn(5);
 
           if (version <= MYSQL_VERSION_ID)
@@ -1254,16 +1258,36 @@ int MYSQLlex(void *arg, void *yythd)
         lip->yySkip();                  // Accept /
         lip->yySkip();                  // Accept *
       }
-
-      while (! lip->eof() &&
-            ((c=lip->yyGet()) != '*' || lip->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->eof())
       {
-        if (c == '\n')
+        c= lip->yyGet();
+        if (c == '*')
+        {
+          if (lip->yyPeek() == '/')
+          {
+            lip->yySkip();
+            comment_closed= TRUE;
+            state = MY_LEX_START;
+            break;
+          }
+        }
+        else if (c == '\n')
           lip->yylineno++;
       }
-      if (! lip->eof())
-        lip->yySkip();                  // remove last '/'
+      /* Unbalanced comments with a missing '*' '/' are a syntax error */
+      if (! comment_closed)
+        return (ABORT_SYM);
       state = MY_LEX_START;             // Try again
+      lip->in_comment= NO_COMMENT;
       lip->set_echo(TRUE);
       break;
     case MY_LEX_END_LONG_COMMENT:
@@ -1315,6 +1339,9 @@ int MYSQLlex(void *arg, void *yythd)
         lip->set_echo(FALSE);
         lip->yySkip();
         lip->set_echo(TRUE);
+        /* Unbalanced comments with a missing '*' '/' are a syntax error */
+        if (lip->in_comment != NO_COMMENT)
+          return (ABORT_SYM);
         lip->next_state=MY_LEX_END;     // Mark for next loop
         return(END_OF_INPUT);
       }
Thread
bk commit into 5.1 tree (malff:1.2589) BUG#28779marc.alff30 Aug