]> granicus.if.org Git - php/commitdiff
Fixed bug #71447 (Quotes inside comments not properly handled)
authorMatteo Beccati <mbeccati@php.net>
Mon, 4 Apr 2016 21:45:10 +0000 (23:45 +0200)
committerMatteo Beccati <mbeccati@php.net>
Mon, 4 Apr 2016 21:50:28 +0000 (23:50 +0200)
NEWS
ext/pdo/pdo_sql_parser.c
ext/pdo/pdo_sql_parser.re
ext/pdo/tests/bug_71447.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 8653e4dc7507896c794c68964488fa635f92e631..0f9594ec8a943477152b85465e14e1f347719138 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,8 @@ PHP                                                                        NEWS
 - PDO:
   . Fixed bug #52098 (Own PDOStatement implementation ignore __call()).
     (Daniel kalaspuffar, Julien)
+  . Fixed bug #71447 (Quotes inside comments not properly handled).
+    (Matteo)
 
 - Postgres:
   . Fixed bug #71820 (pg_fetch_object binds parameters before call
index 22fd696155fc4b6e791a35ecc6dd36992113e723..5a419782b53be3db3bc7c6daf1bc49fb2eccb33a 100644 (file)
@@ -54,7 +54,6 @@ static int scan(Scanner *s)
 #line 55 "ext/pdo/pdo_sql_parser.c"
 {
        YYCTYPE yych;
-       unsigned int yyaccept = 0;
 
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
@@ -62,31 +61,32 @@ static int scan(Scanner *s)
        case 0x00:      goto yy2;
        case '"':       goto yy3;
        case '\'':      goto yy5;
-       case '-':       goto yy11;
-       case '/':       goto yy9;
+       case '(':
+       case ')':
+       case '*':
+       case '+':
+       case ',':
+       case '.':       goto yy9;
+       case '-':       goto yy10;
+       case '/':       goto yy11;
        case ':':       goto yy6;
        case '?':       goto yy7;
        default:        goto yy12;
        }
 yy2:
        YYCURSOR = YYMARKER;
-       switch (yyaccept) {
-       case 0:         goto yy4;
-       case 1:         goto yy10;
-       }
+       goto yy4;
 yy3:
-       yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych >= 0x01) goto yy43;
+       if (yych >= 0x01) goto yy37;
 yy4:
 #line 63 "ext/pdo/pdo_sql_parser.re"
        { SKIP_ONE(PDO_PARSER_TEXT); }
-#line 85 "ext/pdo/pdo_sql_parser.c"
+#line 86 "ext/pdo/pdo_sql_parser.c"
 yy5:
-       yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
        if (yych <= 0x00) goto yy4;
-       goto yy38;
+       goto yy32;
 yy6:
        yych = *++YYCURSOR;
        switch (yych) {
@@ -152,14 +152,14 @@ yy6:
        case 'w':
        case 'x':
        case 'y':
-       case 'z':       goto yy32;
-       case ':':       goto yy35;
+       case 'z':       goto yy26;
+       case ':':       goto yy29;
        default:        goto yy4;
        }
 yy7:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '?':       goto yy29;
+       case '?':       goto yy23;
        default:        goto yy8;
        }
 yy8:
@@ -167,133 +167,89 @@ yy8:
        { RET(PDO_PARSER_BIND_POS); }
 #line 169 "ext/pdo/pdo_sql_parser.c"
 yy9:
-       ++YYCURSOR;
-       switch ((yych = *YYCURSOR)) {
-       case '*':       goto yy19;
-       default:        goto yy13;
-       }
+       yych = *++YYCURSOR;
+       goto yy4;
 yy10:
-#line 65 "ext/pdo/pdo_sql_parser.re"
-       { RET(PDO_PARSER_TEXT); }
-#line 179 "ext/pdo/pdo_sql_parser.c"
-yy11:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '-':       goto yy14;
-       default:        goto yy13;
+       case '-':       goto yy21;
+       default:        goto yy4;
+       }
+yy11:
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case '*':       goto yy15;
+       default:        goto yy4;
        }
 yy12:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy13:
        switch (yych) {
        case 0x00:
        case '"':
        case '\'':
+       case '(':
+       case ')':
+       case '*':
+       case '+':
+       case ',':
+       case '-':
+       case '.':
+       case '/':
        case ':':
-       case '?':       goto yy10;
+       case '?':       goto yy14;
        default:        goto yy12;
        }
 yy14:
+#line 65 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_TEXT); }
+#line 208 "ext/pdo/pdo_sql_parser.c"
+yy15:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        switch (yych) {
-       case 0x00:
-       case '"':
-       case '\'':
-       case ':':
-       case '?':       goto yy17;
-       case '\n':
-       case '\r':      goto yy12;
-       default:        goto yy14;
+       case '*':       goto yy17;
+       default:        goto yy15;
        }
-yy16:
-#line 64 "ext/pdo/pdo_sql_parser.re"
-       { RET(PDO_PARSER_TEXT); }
-#line 216 "ext/pdo/pdo_sql_parser.c"
 yy17:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        switch (yych) {
-       case '\n':
-       case '\r':      goto yy16;
-       default:        goto yy17;
+       case '*':       goto yy17;
+       case '/':       goto yy19;
+       default:        goto yy15;
        }
 yy19:
-       yyaccept = 1;
-       YYMARKER = ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
-       switch (yych) {
-       case 0x00:
-       case '"':
-       case '\'':
-       case ':':
-       case '?':       goto yy21;
-       case '*':       goto yy23;
-       default:        goto yy19;
-       }
+       ++YYCURSOR;
+yy20:
+#line 64 "ext/pdo/pdo_sql_parser.re"
+       { RET(PDO_PARSER_TEXT); }
+#line 231 "ext/pdo/pdo_sql_parser.c"
 yy21:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        switch (yych) {
-       case '*':       goto yy26;
+       case '\n':
+       case '\r':      goto yy20;
        default:        goto yy21;
        }
 yy23:
-       yyaccept = 1;
-       YYMARKER = ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-       yych = *YYCURSOR;
-       switch (yych) {
-       case 0x00:
-       case '"':
-       case '\'':
-       case ':':
-       case '?':       goto yy21;
-       case '*':       goto yy23;
-       case '/':       goto yy25;
-       default:        goto yy19;
-       }
-yy25:
-       yych = *++YYCURSOR;
-       switch (yych) {
-       case 0x00:
-       case '"':
-       case '\'':
-       case ':':
-       case '?':       goto yy16;
-       default:        goto yy12;
-       }
-yy26:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        switch (yych) {
-       case '*':       goto yy26;
-       case '/':       goto yy28;
-       default:        goto yy21;
+       case '?':       goto yy23;
+       default:        goto yy25;
        }
-yy28:
-       yych = *++YYCURSOR;
-       goto yy16;
-yy29:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
-       switch (yych) {
-       case '?':       goto yy29;
-       default:        goto yy31;
-       }
-yy31:
+yy25:
 #line 60 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 296 "ext/pdo/pdo_sql_parser.c"
-yy32:
+#line 252 "ext/pdo/pdo_sql_parser.c"
+yy26:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
@@ -360,65 +316,65 @@ yy32:
        case 'w':
        case 'x':
        case 'y':
-       case 'z':       goto yy32;
-       default:        goto yy34;
+       case 'z':       goto yy26;
+       default:        goto yy28;
        }
-yy34:
+yy28:
 #line 61 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_BIND); }
-#line 370 "ext/pdo/pdo_sql_parser.c"
-yy35:
+#line 326 "ext/pdo/pdo_sql_parser.c"
+yy29:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        switch (yych) {
-       case ':':       goto yy35;
-       default:        goto yy31;
+       case ':':       goto yy29;
+       default:        goto yy25;
        }
-yy37:
+yy31:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy38:
+yy32:
        switch (yych) {
        case 0x00:      goto yy2;
-       case '\'':      goto yy40;
-       case '\\':      goto yy39;
-       default:        goto yy37;
+       case '\'':      goto yy34;
+       case '\\':      goto yy33;
+       default:        goto yy31;
        }
-yy39:
+yy33:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        if (yych <= 0x00) goto yy2;
-       goto yy37;
-yy40:
+       goto yy31;
+yy34:
        ++YYCURSOR;
 #line 59 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 400 "ext/pdo/pdo_sql_parser.c"
-yy42:
+#line 356 "ext/pdo/pdo_sql_parser.c"
+yy36:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy43:
+yy37:
        switch (yych) {
        case 0x00:      goto yy2;
-       case '"':       goto yy45;
-       case '\\':      goto yy44;
-       default:        goto yy42;
+       case '"':       goto yy39;
+       case '\\':      goto yy38;
+       default:        goto yy36;
        }
-yy44:
+yy38:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        if (yych <= 0x00) goto yy2;
-       goto yy42;
-yy45:
+       goto yy36;
+yy39:
        ++YYCURSOR;
 #line 58 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 422 "ext/pdo/pdo_sql_parser.c"
+#line 378 "ext/pdo/pdo_sql_parser.c"
 }
 #line 66 "ext/pdo/pdo_sql_parser.re"
        
index 0bf7bffaec45ee3b56af90188bf5c7966a102bef..bed5befa87feeb6360925231a278af9a63c2413d 100644 (file)
@@ -49,7 +49,7 @@ static int scan(Scanner *s)
        BINDCHR         = [:][a-zA-Z0-9_]+;
        QUESTION        = [?];
        COMMENTS        = ("/*"([^*]+|[*]+[^/*])*[*]*"*/"|"--"[^\r\n]*);
-       SPECIALS        = [:?"'];
+       SPECIALS        = [:?"'-/];
        MULTICHAR       = ([:]{2,}|[?]{2,});
        ANYNOEOF        = [\001-\377];
        */
diff --git a/ext/pdo/tests/bug_71447.phpt b/ext/pdo/tests/bug_71447.phpt
new file mode 100644 (file)
index 0000000..8b5c073
--- /dev/null
@@ -0,0 +1,104 @@
+--TEST--
+PDO Common: Bug #71447 (Quotes inside comments not properly handled)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_WARNING);
+$db->setAttribute (\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_NUM);
+$db->setAttribute (\PDO::ATTR_EMULATE_PREPARES, false);
+$db->exec('CREATE TABLE test(id int)');
+$db->exec('INSERT INTO test VALUES(1)');
+
+// Comment without quotes or placeholders
+$stmt = $db->prepare("
+       SELECT -- Thats all folks!
+               '\"abc\":8000'
+       FROM test
+");
+
+$stmt->execute();
+var_dump($stmt->fetchColumn());
+
+// Comment and placeholder within a string
+$stmt = $db->prepare("
+       SELECT
+               '\"abc\":8001 -- Wat?'
+       FROM test
+");
+
+$stmt->execute();
+var_dump($stmt->fetchColumn());
+
+// Comment with single quote
+$stmt = $db->prepare("
+       SELECT -- That's all folks!
+               '\"abc\":8002'
+       FROM test
+");
+
+$stmt->execute();
+var_dump($stmt->fetchColumn());
+
+// C-Style comment with single quote
+$stmt = $db->prepare("
+       SELECT /* That's all folks! */
+               '\"abc\":8003'
+       FROM test
+");
+
+$stmt->execute();
+var_dump($stmt->fetchColumn());
+
+// Comment with double quote
+$stmt = $db->prepare("
+       SELECT -- Is it only \"single quotes?
+               '\"abc\":8004'
+       FROM test
+");
+
+$stmt->execute();
+var_dump($stmt->fetchColumn());
+
+// Comment with ? placeholder
+$stmt = $db->prepare("
+       SELECT -- What about question marks here?
+               *
+       FROM test
+       WHERE id = ?
+");
+
+$stmt->execute([1]);
+var_dump($stmt->fetchColumn());
+
+// Comment with named placeholder
+$stmt = $db->prepare("
+       SELECT -- What about placeholders :bar
+               *
+       FROM test
+       WHERE id = :id
+");
+
+$stmt->execute(['id' => 1]);
+var_dump($stmt->fetchColumn());
+
+
+?>
+--EXPECT--
+string(10) ""abc":8000"
+string(18) ""abc":8001 -- Wat?"
+string(10) ""abc":8002"
+string(10) ""abc":8003"
+string(10) ""abc":8004"
+string(1) "1"
+string(1) "1"