]> granicus.if.org Git - php/commitdiff
Fix bug #64953 (Postgres prepared statement positional parameter casting)
authorMichael Wallner <mike@php.net>
Tue, 20 Aug 2013 17:19:02 +0000 (19:19 +0200)
committerMichael Wallner <mike@php.net>
Tue, 20 Aug 2013 17:19:02 +0000 (19:19 +0200)
NEWS
ext/pdo/pdo_sql_parser.c
ext/pdo/pdo_sql_parser.re
ext/pdo_pgsql/tests/bug64953.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index aeae233dc8d81313cfaa25e08fd4934bc32d0bf5..1218c5069aba844beab36a4a10f8ad833a7602ce 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,10 @@ PHP                                                                        NEWS
 - SPL:
   . Fixed bug #65328 (Segfault when getting SplStack object Value). (Laruence)
 
+- PDO:
+  . Fixed bug #64953 (Postgres prepared statement positional parameter 
+    casting). (Mike)
+
 - Phar:
   . Fixed bug #65028 (Phar::buildFromDirectory creates corrupt archives for 
     some specific contents). (Stas)
index 4c523506c4554ed7997eed4de60d45786167ac34..1ed78c1cc5e6ad5d4bb162bbf76ba6431900a38e 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Thu Apr 19 12:42:11 2012 */
+/* Generated by re2c 0.13.5 on Tue Aug 20 18:02:48 2013 */
 #line 1 "ext/pdo/pdo_sql_parser.re"
 /*
   +----------------------------------------------------------------------+
@@ -77,7 +77,7 @@ yy2:
 yy3:
        yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych >= 0x01) goto yy41;
+       if (yych >= 0x01) goto yy43;
 yy4:
 #line 63 "ext/pdo/pdo_sql_parser.re"
        { SKIP_ONE(PDO_PARSER_TEXT); }
@@ -86,7 +86,7 @@ yy5:
        yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
        if (yych <= 0x00) goto yy4;
-       goto yy36;
+       goto yy38;
 yy6:
        yych = *++YYCURSOR;
        switch (yych) {
@@ -153,21 +153,19 @@ yy6:
        case 'x':
        case 'y':
        case 'z':       goto yy32;
-       case ':':
-       case '?':       goto yy29;
+       case ':':       goto yy35;
        default:        goto yy4;
        }
 yy7:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case ':':
        case '?':       goto yy29;
        default:        goto yy8;
        }
 yy8:
 #line 62 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_BIND_POS); }
-#line 171 "ext/pdo/pdo_sql_parser.c"
+#line 169 "ext/pdo/pdo_sql_parser.c"
 yy9:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
@@ -177,7 +175,7 @@ yy9:
 yy10:
 #line 65 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 181 "ext/pdo/pdo_sql_parser.c"
+#line 179 "ext/pdo/pdo_sql_parser.c"
 yy11:
        yych = *++YYCURSOR;
        switch (yych) {
@@ -214,7 +212,7 @@ yy14:
 yy16:
 #line 64 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 218 "ext/pdo/pdo_sql_parser.c"
+#line 216 "ext/pdo/pdo_sql_parser.c"
 yy17:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -288,14 +286,13 @@ yy29:
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        switch (yych) {
-       case ':':
        case '?':       goto yy29;
        default:        goto yy31;
        }
 yy31:
 #line 60 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 299 "ext/pdo/pdo_sql_parser.c"
+#line 296 "ext/pdo/pdo_sql_parser.c"
 yy32:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -369,51 +366,59 @@ yy32:
 yy34:
 #line 61 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_BIND); }
-#line 373 "ext/pdo/pdo_sql_parser.c"
+#line 370 "ext/pdo/pdo_sql_parser.c"
 yy35:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy36:
        switch (yych) {
-       case 0x00:      goto yy2;
-       case '\'':      goto yy38;
-       case '\\':      goto yy37;
-       default:        goto yy35;
+       case ':':       goto yy35;
+       default:        goto yy31;
        }
 yy37:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-       if (yych <= 0x00) goto yy2;
-       goto yy35;
 yy38:
+       switch (yych) {
+       case 0x00:      goto yy2;
+       case '\'':      goto yy40;
+       case '\\':      goto yy39;
+       default:        goto yy37;
+       }
+yy39:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       if (yych <= 0x00) goto yy2;
+       goto yy37;
+yy40:
        ++YYCURSOR;
 #line 59 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 395 "ext/pdo/pdo_sql_parser.c"
-yy40:
+#line 400 "ext/pdo/pdo_sql_parser.c"
+yy42:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy41:
+yy43:
        switch (yych) {
        case 0x00:      goto yy2;
-       case '"':       goto yy43;
-       case '\\':      goto yy42;
-       default:        goto yy40;
+       case '"':       goto yy45;
+       case '\\':      goto yy44;
+       default:        goto yy42;
        }
-yy42:
+yy44:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        if (yych <= 0x00) goto yy2;
-       goto yy40;
-yy43:
+       goto yy42;
+yy45:
        ++YYCURSOR;
 #line 58 "ext/pdo/pdo_sql_parser.re"
        { RET(PDO_PARSER_TEXT); }
-#line 417 "ext/pdo/pdo_sql_parser.c"
+#line 422 "ext/pdo/pdo_sql_parser.c"
 }
 #line 66 "ext/pdo/pdo_sql_parser.re"
        
index 80e3b4f95f6f0e09756c395a36a057b9b07fce8f..1936a37340bb130ccbe386c542648febfd75d20b 100644 (file)
@@ -50,14 +50,14 @@ static int scan(Scanner *s)
        QUESTION        = [?];
        COMMENTS        = ("/*"([^*]+|[*]+[^/*])*[*]*"*/"|"--"[^\r\n]*);
        SPECIALS        = [:?"'];
-       MULTICHAR       = [:?];
+       MULTICHAR       = ([:]{2,}|[?]{2,});
        ANYNOEOF        = [\001-\377];
        */
 
        /*!re2c
                (["](([\\]ANYNOEOF)|ANYNOEOF\["\\])*["]) { RET(PDO_PARSER_TEXT); }
                (['](([\\]ANYNOEOF)|ANYNOEOF\['\\])*[']) { RET(PDO_PARSER_TEXT); }
-               MULTICHAR{2,}                                                   { RET(PDO_PARSER_TEXT); }
+               MULTICHAR                                                               { RET(PDO_PARSER_TEXT); }
                BINDCHR                                                                 { RET(PDO_PARSER_BIND); }
                QUESTION                                                                { RET(PDO_PARSER_BIND_POS); }
                SPECIALS                                                                { SKIP_ONE(PDO_PARSER_TEXT); }
diff --git a/ext/pdo_pgsql/tests/bug64953.phpt b/ext/pdo_pgsql/tests/bug64953.phpt
new file mode 100644 (file)
index 0000000..6e72bca
--- /dev/null
@@ -0,0 +1,71 @@
+--TEST--
+PDO PgSQL Bug #64953 (Postgres prepared statement positional parameter casting)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+echo "Taken from the bug report:\n";
+
+$st = $pdo->prepare('SELECT ?::char as i');
+$st->bindValue(1, '1');
+$st->execute();
+var_dump($st->fetch()); // return false
+
+
+$st = $pdo->prepare('SELECT (?)::char as i');
+$st->bindValue(1, '1');
+$st->execute();
+var_dump($st->fetch());  // return array(1) { ["i"]=> string(1) "1" }
+
+echo "Something more nasty:\n";
+
+$st = $pdo->prepare("SELECT :int::int as i");
+$st->execute(array(":int" => 123));
+var_dump($st->fetch());
+
+$st = $pdo->prepare("SELECT '''?'''::text as \":text\"");
+$st->execute();
+var_dump($st->fetch());
+
+?>
+Done
+--EXPECT--
+Test
+Taken from the bug report:
+array(2) {
+  ["i"]=>
+  string(1) "1"
+  [0]=>
+  string(1) "1"
+}
+array(2) {
+  ["i"]=>
+  string(1) "1"
+  [0]=>
+  string(1) "1"
+}
+Something more nasty:
+array(2) {
+  ["i"]=>
+  string(3) "123"
+  [0]=>
+  string(3) "123"
+}
+array(2) {
+  [":text"]=>
+  string(3) "'?'"
+  [0]=>
+  string(3) "'?'"
+}
+Done