]> granicus.if.org Git - php/commitdiff
Fixed bug #40285 (The PDO prepare parser goes into an infinite loop in
authorIlia Alshanetsky <iliaa@php.net>
Thu, 1 Feb 2007 00:12:39 +0000 (00:12 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Thu, 1 Feb 2007 00:12:39 +0000 (00:12 +0000)
some instances).

NEWS
ext/pdo/pdo_sql_parser.c
ext/pdo/pdo_sql_parser.re
ext/pdo/tests/bug_39656.phpt

diff --git a/NEWS b/NEWS
index f3fac8545234cc1a37e23a4ab4394704de6b4d23..8f7a4d0635a52b296b49ab69054afabecb286e05 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -101,6 +101,8 @@ PHP                                                                        NEWS
   the user part of the email address. (Derick)
 - Fixed bug #40297 (compile failure in ZTS mode when collections support is 
   missing). (Tony)
+- Fixed bug #40285 (The PDO prepare parser goes into an infinite loop in
+  some instances). (Ilia)
 - Fixed bug #40259 (ob_start call many times - memory error). (Dmitry)
 - Fixed bug #40231 (file_exists incorrectly reports false). (Dmitry)
 - Fixed bug #40228 (ZipArchive::extractTo does create empty directories 
index 492fd62c7b71cb5035513c4cee0bd575714c3014..00f0fea0c3d7fe4f44d0f4c01292443cd55e803a 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.10.4 on Wed Jan  3 22:04:03 2007 */
+/* Generated by re2c 0.11.0 on Wed Jan 31 18:53:45 2007 */
 #line 1 "ext/pdo/pdo_sql_parser.re"
 /*
   +----------------------------------------------------------------------+
@@ -46,194 +46,253 @@ static int scan(Scanner *s)
        char *cursor = s->cur;
 
        s->tok = cursor;
-       #line 53 "ext/pdo/pdo_sql_parser.re"
-
-
-       {
-       static unsigned char yybm[] = {
-               160, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162,  52, 162, 162, 162, 162, 196, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               170, 170, 170, 170, 170, 170, 170, 170, 
-               170, 170, 244, 162, 162, 162, 162, 244, 
-               162, 170, 170, 170, 170, 170, 170, 170, 
-               170, 170, 170, 170, 170, 170, 170, 170, 
-               170, 170, 170, 170, 170, 170, 170, 170, 
-               170, 170, 170, 162, 162, 162, 162, 170, 
-               162, 170, 170, 170, 170, 170, 170, 170, 
-               170, 170, 170, 170, 170, 170, 170, 170, 
-               170, 170, 170, 170, 170, 170, 170, 170, 
-               170, 170, 170, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-               162, 162, 162, 162, 162, 162, 162, 162, 
-       };
-
-#line 89 "ext/pdo/pdo_sql_parser.c"
-       {
-               YYCTYPE yych;
-
-               if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 2) {
-                       goto yy8;
-               }
-               if(yych <= 0x00) goto yy11;
-               if(yych <= '&') goto yy2;
-               if(yych <= '\'') goto yy4;
-               if(yych <= '>') goto yy5;
-               goto yy6;
+       #line 54 "ext/pdo/pdo_sql_parser.re"
+
+
+       
+#line 54 "ext/pdo/pdo_sql_parser.c"
+{
+       YYCTYPE yych;
+
+       if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       switch(yych) {
+       case 0x00:      goto yy11;
+       case '"':       goto yy2;
+       case '\'':      goto yy4;
+       case ':':       goto yy5;
+       case '?':       goto yy6;
+       default:        goto yy8;
+       }
 yy2:
-               yych = *++YYCURSOR;
-               if(yybm[0+yych] & 64) {
-                       goto yy28;
-               }
-               if(yych == '"') goto yy26;
-               goto yy30;
+       yych = *++YYCURSOR;
+       goto yy24;
 yy3:
-#line 61 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_TEXT); }
-#line 113 "ext/pdo/pdo_sql_parser.c"
+#line 62 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_TEXT); }
+#line 74 "ext/pdo/pdo_sql_parser.c"
 yy4:
-               yych = *++YYCURSOR;
-               if(yybm[0+yych] & 16) {
-                       goto yy19;
-               }
-               if(yych == '\'') goto yy21;
-               goto yy23;
+       yych = *++YYCURSOR;
+       goto yy20;
 yy5:
-               yych = *++YYCURSOR;
-               if(yybm[0+yych] & 4) {
-                       goto yy13;
-               }
-               if(yych <= 'Z') {
-                       if(yych <= '/') goto yy3;
-                       if(yych <= ':') goto yy16;
-                       if(yych <= '@') goto yy3;
-                       goto yy16;
-               } else {
-                       if(yych <= '_') {
-                               if(yych <= '^') goto yy3;
-                               goto yy16;
-                       } else {
-                               if(yych <= '`') goto yy3;
-                               if(yych <= 'z') goto yy16;
-                               goto yy3;
-                       }
-               }
+       yych = *++YYCURSOR;
+       switch(yych) {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+       case 'A':
+       case 'B':
+       case 'C':
+       case 'D':
+       case 'E':
+       case 'F':
+       case 'G':
+       case 'H':
+       case 'I':
+       case 'J':
+       case 'K':
+       case 'L':
+       case 'M':
+       case 'N':
+       case 'O':
+       case 'P':
+       case 'Q':
+       case 'R':
+       case 'S':
+       case 'T':
+       case 'U':
+       case 'V':
+       case 'W':
+       case 'X':
+       case 'Y':
+       case 'Z':
+       case '_':
+       case 'a':
+       case 'b':
+       case 'c':
+       case 'd':
+       case 'e':
+       case 'f':
+       case 'g':
+       case 'h':
+       case 'i':
+       case 'j':
+       case 'k':
+       case 'l':
+       case 'm':
+       case 'n':
+       case 'o':
+       case 'p':
+       case 'q':
+       case 'r':
+       case 's':
+       case 't':
+       case 'u':
+       case 'v':
+       case 'w':
+       case 'x':
+       case 'y':
+       case 'z':       goto yy16;
+       case ':':
+       case '?':       goto yy13;
+       default:        goto yy3;
+       }
 yy6:
-               ++YYCURSOR;
-               if(yybm[0+(yych = *YYCURSOR)] & 4) {
-                       goto yy13;
-               }
-#line 60 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_BIND_POS); }
-#line 148 "ext/pdo/pdo_sql_parser.c"
-yy8:
-               ++YYCURSOR;
-               if(YYLIMIT == YYCURSOR) YYFILL(1);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 2) {
-                       goto yy8;
-               }
-#line 62 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_TEXT); }
+       ++YYCURSOR;
+       switch((yych = *YYCURSOR)) {
+       case ':':
+       case '?':       goto yy13;
+       default:        goto yy7;
+       }
+yy7:
+#line 61 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_BIND_POS); }
 #line 158 "ext/pdo/pdo_sql_parser.c"
-yy11:
-               ++YYCURSOR;
+yy8:
+       ++YYCURSOR;
+       if(YYLIMIT == YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch(yych) {
+       case 0x00:
+       case '"':
+       case '\'':
+       case ':':
+       case '?':       goto yy10;
+       default:        goto yy8;
+       }
+yy10:
 #line 63 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_EOI); }
-#line 163 "ext/pdo/pdo_sql_parser.c"
+       { RET(PDO_PARSER_TEXT); }
+#line 174 "ext/pdo/pdo_sql_parser.c"
+yy11:
+       ++YYCURSOR;
+#line 64 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_EOI); }
+#line 179 "ext/pdo/pdo_sql_parser.c"
 yy13:
-               ++YYCURSOR;
-               if(YYLIMIT == YYCURSOR) YYFILL(1);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 4) {
-                       goto yy13;
-               }
-#line 58 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_TEXT); }
-#line 173 "ext/pdo/pdo_sql_parser.c"
-yy16:
-               ++YYCURSOR;
-               if(YYLIMIT == YYCURSOR) YYFILL(1);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 8) {
-                       goto yy16;
-               }
+       ++YYCURSOR;
+       if(YYLIMIT == YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch(yych) {
+       case ':':
+       case '?':       goto yy13;
+       default:        goto yy15;
+       }
+yy15:
 #line 59 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_BIND); }
-#line 183 "ext/pdo/pdo_sql_parser.c"
+       { RET(PDO_PARSER_TEXT); }
+#line 192 "ext/pdo/pdo_sql_parser.c"
+yy16:
+       ++YYCURSOR;
+       if(YYLIMIT == YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch(yych) {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+       case 'A':
+       case 'B':
+       case 'C':
+       case 'D':
+       case 'E':
+       case 'F':
+       case 'G':
+       case 'H':
+       case 'I':
+       case 'J':
+       case 'K':
+       case 'L':
+       case 'M':
+       case 'N':
+       case 'O':
+       case 'P':
+       case 'Q':
+       case 'R':
+       case 'S':
+       case 'T':
+       case 'U':
+       case 'V':
+       case 'W':
+       case 'X':
+       case 'Y':
+       case 'Z':
+       case '_':
+       case 'a':
+       case 'b':
+       case 'c':
+       case 'd':
+       case 'e':
+       case 'f':
+       case 'g':
+       case 'h':
+       case 'i':
+       case 'j':
+       case 'k':
+       case 'l':
+       case 'm':
+       case 'n':
+       case 'o':
+       case 'p':
+       case 'q':
+       case 'r':
+       case 's':
+       case 't':
+       case 'u':
+       case 'v':
+       case 'w':
+       case 'x':
+       case 'y':
+       case 'z':       goto yy16;
+       default:        goto yy18;
+       }
+yy18:
+#line 60 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_BIND); }
+#line 266 "ext/pdo/pdo_sql_parser.c"
 yy19:
-               if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 16) {
-                       goto yy19;
-               }
-               if(yych != '\'') goto yy23;
+       ++YYCURSOR;
+       if(YYLIMIT == YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+yy20:
+       switch(yych) {
+       case '\'':      goto yy21;
+       default:        goto yy19;
+       }
 yy21:
-               ++YYCURSOR;
-               if(yybm[0+(yych = *YYCURSOR)] & 4) {
-                       goto yy13;
-               }
-yy22:
-#line 57 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_TEXT); }
-#line 199 "ext/pdo/pdo_sql_parser.c"
+       ++YYCURSOR;
+#line 58 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_TEXT); }
+#line 280 "ext/pdo/pdo_sql_parser.c"
 yy23:
-               ++YYCURSOR;
-               if(YYLIMIT == YYCURSOR) YYFILL(1);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 32) {
-                       goto yy23;
-               }
-               yych = *++YYCURSOR;
-               goto yy22;
-yy26:
-               ++YYCURSOR;
-               if(yybm[0+(yych = *YYCURSOR)] & 4) {
-                       goto yy13;
-               }
-yy27:
-#line 56 "ext/pdo/pdo_sql_parser.re"
-               { RET(PDO_PARSER_TEXT); }
-#line 217 "ext/pdo/pdo_sql_parser.c"
-yy28:
-               if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 64) {
-                       goto yy28;
-               }
-               if(yych == '"') goto yy26;
-yy30:
-               ++YYCURSOR;
-               if(YYLIMIT == YYCURSOR) YYFILL(1);
-               yych = *YYCURSOR;
-               if(yybm[0+yych] & 128) {
-                       goto yy30;
-               }
-               ++YYCURSOR;
-               yych = *YYCURSOR;
-               goto yy27;
+       ++YYCURSOR;
+       if(YYLIMIT == YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+yy24:
+       switch(yych) {
+       case '"':       goto yy25;
+       default:        goto yy23;
        }
+yy25:
+       ++YYCURSOR;
+#line 57 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_TEXT); }
+#line 294 "ext/pdo/pdo_sql_parser.c"
 }
-#line 64 "ext/pdo/pdo_sql_parser.re"
+#line 65 "ext/pdo/pdo_sql_parser.re"
        
 }
 
index c5c8cbaaf44ed3a159bb62962632fd4f3cb13532..59fd5145cf49c48c06986a7fd353cc402463894c 100644 (file)
@@ -48,6 +48,7 @@ static int scan(Scanner *s)
        BINDCHR         = [:][a-zA-Z0-9_]+;
        QUESTION        = [?];
        SPECIALS        = [:?"'];
+       MULTICHAR       = [:?];
        EOF             = [\000];
        ANYNOEOF        = [\001-\377];
        */
@@ -55,7 +56,7 @@ static int scan(Scanner *s)
        /*!re2c
                (["] ([^"])* ["])               { RET(PDO_PARSER_TEXT); }
                (['] ([^'])* ['])               { RET(PDO_PARSER_TEXT); }
-               SPECIALS{2,}                                                    { RET(PDO_PARSER_TEXT); }
+               MULTICHAR{2,}                                                   { RET(PDO_PARSER_TEXT); }
                BINDCHR                                                                 { RET(PDO_PARSER_BIND); }
                QUESTION                                                                { RET(PDO_PARSER_BIND_POS); }
                SPECIALS                                                                { RET(PDO_PARSER_TEXT); }
index e1a283ce09572640e8b816a93c7ba203095855fe..c0a56743893974e76ae61b6b0232acb07eab8c4f 100644 (file)
@@ -1,5 +1,5 @@
 --TEST--
-PDO Common: Bug #39656 (Crash when calling fetch() on a PDO statment object after closeCursor())
+PDO Common: Bug #40285 (The prepare parser goes into an infinite loop on ': or ":)
 --SKIPIF--
 <?php  
 if (!extension_loaded('pdo')) die('skip');
@@ -15,36 +15,13 @@ if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE_
 require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
 $db = PDOTest::factory();
 
-@$db->exec("DROP TABLE testtable");
-$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$db->exec('CREATE TABLE test (field1 VARCHAR(32), field2 VARCHAR(32), field3 VARCHAR(32), field4 INT)');
 
-$db->exec("CREATE TABLE testtable (id INTEGER NOT NULL PRIMARY KEY, usr VARCHAR( 256 ) NOT NULL)");
-$db->exec("INSERT INTO testtable (id, usr) VALUES (1, 'user')");
-
-$stmt = $db->prepare("SELECT * FROM testtable WHERE id = ?");
-$stmt->bindValue(1, 1, PDO::PARAM_INT );
-$stmt->execute();
-$row = $stmt->fetch();
-var_dump( $row );
-
-$stmt->execute();
-$stmt->closeCursor();
-$row = $stmt->fetch(); // this line will crash CLI
-var_dump( $row );
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+$s = $db->prepare("INSERT INTO test VALUES( ':id', 'name', 'section', 22)" );
+$s->execute();
 
 echo "Done\n";
 ?>
 --EXPECT--     
-array(4) {
-  ["id"]=>
-  string(1) "1"
-  [0]=>
-  string(1) "1"
-  ["usr"]=>
-  string(4) "user"
-  [1]=>
-  string(4) "user"
-}
-bool(false)
 Done
-