diff options
Diffstat (limited to 'ext/pdo')
| -rw-r--r-- | ext/pdo/pdo_dbh.c | 4 | ||||
| -rw-r--r-- | ext/pdo/pdo_sql_parser.c | 204 | ||||
| -rw-r--r-- | ext/pdo/pdo_sql_parser.re | 2 | ||||
| -rw-r--r-- | ext/pdo/pdo_stmt.c | 20 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_44159.phpt | 2 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_47769.phpt (renamed from ext/pdo/tests/bug47769.phpt) | 2 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_52098.phpt | 59 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_61292.phpt (renamed from ext/pdo/tests/bug61292.phpt) | 2 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_65946.phpt (renamed from ext/pdo/tests/bug65946.phpt) | 2 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_71447.phpt | 104 |
10 files changed, 262 insertions, 139 deletions
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 0b2053d0d3..624281c18b 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -436,10 +436,8 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt zval retval; fci.size = sizeof(zend_fcall_info); - fci.function_table = &dbstmt_ce->function_table; ZVAL_UNDEF(&fci.function_name); fci.object = Z_OBJ_P(object); - fci.symbol_table = NULL; fci.retval = &retval; fci.param_count = 0; fci.params = NULL; @@ -449,7 +447,7 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt fcc.initialized = 1; fcc.function_handler = dbstmt_ce->constructor; - fcc.calling_scope = EG(scope); + fcc.calling_scope = zend_get_executed_scope(); fcc.called_scope = Z_OBJCE_P(object); fcc.object = Z_OBJ_P(object); diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c index 84f6ac3c6e..0095c3d8dc 100644 --- a/ext/pdo/pdo_sql_parser.c +++ b/ext/pdo/pdo_sql_parser.c @@ -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" diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index af6c278fef..3279b47056 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -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/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 6019c39aba..c2f3c13399 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -740,9 +740,7 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt) /* {{{ */ } if (ce->constructor) { - fci->function_table = &ce->function_table; ZVAL_UNDEF(&fci->function_name); - fci->symbol_table = NULL; fci->retval = &stmt->fetch.cls.retval; fci->param_count = 0; fci->params = NULL; @@ -752,7 +750,7 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt) /* {{{ */ fcc->initialized = 1; fcc->function_handler = ce->constructor; - fcc->calling_scope = EG(scope); + fcc->calling_scope = zend_get_executed_scope(); fcc->called_scope = ce; return 1; } else if (!Z_ISUNDEF(stmt->fetch.cls.ctor_args)) { @@ -1241,7 +1239,6 @@ static int pdo_stmt_verify_mode(pdo_stmt_t *stmt, zend_long mode, int fetch_all) return 0; } /* fall through */ - default: if ((flags & PDO_FETCH_SERIALIZE) == PDO_FETCH_SERIALIZE) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO::FETCH_SERIALIZE can only be used together with PDO::FETCH_CLASS"); @@ -1542,16 +1539,16 @@ static int register_bound_param(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, { struct pdo_bound_param_data param = {{{0}}}; zend_long param_type = PDO_PARAM_STR; - zval *parameter; + zval *parameter, *driver_params = NULL; param.paramno = -1; if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "lz|llz!", ¶m.paramno, ¶meter, ¶m_type, ¶m.max_value_len, - ¶m.driver_params)) { + &driver_params)) { if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "Sz|llz!", ¶m.name, ¶meter, ¶m_type, ¶m.max_value_len, - ¶m.driver_params)) { + &driver_params)) { return 0; } } @@ -1565,6 +1562,10 @@ static int register_bound_param(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, return 0; } + if (driver_params) { + ZVAL_COPY(¶m.driver_params, driver_params); + } + ZVAL_COPY(¶m.parameter, parameter); if (!really_register_bound_param(¶m, stmt, is_param)) { if (!Z_ISUNDEF(param.parameter)) { @@ -2215,6 +2216,7 @@ static union _zend_function *dbstmt_method_get(zend_object **object_pp, zend_str lc_method_name = zend_string_alloc(ZSTR_LEN(method_name), 0); zend_str_tolower_copy(ZSTR_VAL(lc_method_name), ZSTR_VAL(method_name), ZSTR_LEN(method_name)); + if ((fbc = zend_hash_find_ptr(&object->ce->function_table, lc_method_name)) == NULL) { pdo_stmt_t *stmt = php_pdo_stmt_fetch_object(object); /* instance not created by PDO object */ @@ -2239,6 +2241,9 @@ static union _zend_function *dbstmt_method_get(zend_object **object_pp, zend_str out: zend_string_release(lc_method_name); + if (!fbc) { + fbc = std_object_handlers.get_method(object_pp, method_name, key); + } return fbc; } @@ -2619,6 +2624,7 @@ static union _zend_function *row_method_get( } zend_string_release(lc_method_name); + return fbc; } diff --git a/ext/pdo/tests/bug_44159.phpt b/ext/pdo/tests/bug_44159.phpt index 9f1961c267..4382fbddda 100644 --- a/ext/pdo/tests/bug_44159.phpt +++ b/ext/pdo/tests/bug_44159.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #44159 (Crash: $pdo->setAttribute(PDO::STATEMENT_ATTR_CLASS, NULL)) +PDO Common: Bug #44159 (Crash: $pdo->setAttribute(PDO::STATEMENT_ATTR_CLASS, NULL)) --SKIPIF-- <?php # vim:ft=php if (!extension_loaded('pdo')) die('skip PDO not available'); diff --git a/ext/pdo/tests/bug47769.phpt b/ext/pdo/tests/bug_47769.phpt index b0b38325d1..f713effd5d 100644 --- a/ext/pdo/tests/bug47769.phpt +++ b/ext/pdo/tests/bug_47769.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #47769 (Strange extends PDO) +PDO Common: Bug #47769 (Strange extends PDO) --SKIPIF-- <?php if (!extension_loaded("pdo_sqlite")) diff --git a/ext/pdo/tests/bug_52098.phpt b/ext/pdo/tests/bug_52098.phpt new file mode 100644 index 0000000000..c9d39af522 --- /dev/null +++ b/ext/pdo/tests/bug_52098.phpt @@ -0,0 +1,59 @@ +--TEST-- +PDO Common: Bug #52098 Own PDOStatement implementation ignore __call() +--SKIPIF-- +<?php # vim:ft=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->exec("DROP TABLE test"); +$db->exec("CREATE TABLE test (x int)"); +$db->exec("INSERT INTO test VALUES (1)"); + +class MyStatement extends PDOStatement +{ + public function __call($name, $arguments) + { + echo "Calling object method '$name'" . implode(', ', $arguments). "\n"; + } +} +/* +Test prepared statement with PDOStatement class. +*/ +$derived = $db->prepare('SELECT * FROM test', array(PDO::ATTR_STATEMENT_CLASS=>array('MyStatement'))); +$derived->execute(); +$derived->foo(); +$derived->fetchAll(); +$derived = null; + +/* +Test regular statement with PDOStatement class. +*/ +$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('MyStatement')); +$r = $db->query('SELECT * FROM test'); +echo $r->bar(); +$r->fetchAll(); +$r = null; + +/* +Test object instance of PDOStatement class. +*/ +$obj = new MyStatement; +echo $obj->lucky(); + +$db->exec("DROP TABLE test"); +?> +===DONE=== +--EXPECTF-- +Calling object method 'foo' +Calling object method 'bar' +Calling object method 'lucky' +===DONE===
\ No newline at end of file diff --git a/ext/pdo/tests/bug61292.phpt b/ext/pdo/tests/bug_61292.phpt index 05b2e9c011..0e41be3859 100644 --- a/ext/pdo/tests/bug61292.phpt +++ b/ext/pdo/tests/bug_61292.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #61292 (Segfault while calling a method on an overloaded PDO object) +PDO Common: Bug #61292 (Segfault while calling a method on an overloaded PDO object) --SKIPIF-- <?php if (!extension_loaded('pdo')) die('skip'); diff --git a/ext/pdo/tests/bug65946.phpt b/ext/pdo/tests/bug_65946.phpt index af6088cea9..13a622ecb8 100644 --- a/ext/pdo/tests/bug65946.phpt +++ b/ext/pdo/tests/bug_65946.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #65946 (pdo_sql_parser.c permanently converts values bound to strings) +PDO Common: Bug #65946 (pdo_sql_parser.c permanently converts values bound to strings) --SKIPIF-- <?php if (!extension_loaded('pdo')) die('skip'); diff --git a/ext/pdo/tests/bug_71447.phpt b/ext/pdo/tests/bug_71447.phpt new file mode 100644 index 0000000000..8b5c0732f1 --- /dev/null +++ b/ext/pdo/tests/bug_71447.phpt @@ -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" |
