From: Daniel Persson Date: Sat, 26 Sep 2015 10:43:40 +0000 (+0200) Subject: Fix bug #52098 X-Git-Tag: php-5.6.21RC1~27 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e541cd8e6bcf5a80b85379afa35e54a82c74bde2;p=php Fix bug #52098 --- diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 1609306552..d027d97963 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1348,18 +1348,12 @@ int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC) } static union _zend_function *dbh_method_get( -#if PHP_API_VERSION >= 20041225 zval **object_pp, -#else - zval *object, -#endif char *method_name, int method_len, const zend_literal *key TSRMLS_DC) { zend_function *fbc = NULL; char *lc_method_name; -#if PHP_API_VERSION >= 20041225 zval *object = *object_pp; -#endif pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC); lc_method_name = emalloc(method_len + 1); diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 2dca387313..db295ee430 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -145,7 +145,7 @@ static inline int rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_pa pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC); return 0; } - + zend_hash_internal_pointer_reset(stmt->bound_param_map); while (SUCCESS == zend_hash_get_current_data(stmt->bound_param_map, (void**)&name)) { if (strcmp(name, param->name)) { @@ -163,7 +163,7 @@ static inline int rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_pa pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC); return 0; } - return 1; + return 1; } /* }}} */ @@ -188,7 +188,7 @@ iterate: ret = 0; break; } - + zend_hash_move_forward(ht); } } @@ -442,14 +442,14 @@ static PHP_METHOD(PDOStatement, execute) } PDO_STMT_CLEAR_ERR(); - + if (input_params) { struct pdo_bound_param_data param; zval **tmp; uint str_length; ulong num_index; - - if (stmt->bound_params) { + + if (stmt->bound_params) { zend_hash_destroy(stmt->bound_params); FREE_HASHTABLE(stmt->bound_params); stmt->bound_params = NULL; @@ -490,7 +490,7 @@ static PHP_METHOD(PDOStatement, execute) if (PDO_PLACEHOLDER_NONE == stmt->supports_placeholders) { /* handle the emulated parameter binding, - * stmt->active_query_string holds the query with binds expanded and + * stmt->active_query_string holds the query with binds expanded and * quoted. */ @@ -531,7 +531,7 @@ static PHP_METHOD(PDOStatement, execute) if (ret && !dispatch_param_event(stmt, PDO_PARAM_EVT_EXEC_POST TSRMLS_CC)) { RETURN_FALSE; } - + RETURN_BOOL(ret); } if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) { @@ -569,12 +569,12 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ } else { ZVAL_NULL(dest); } - + if (Z_TYPE_P(dest) == IS_NULL) { type = new_type; } break; - + case PDO_PARAM_INT: if (value && value_len == sizeof(long)) { ZVAL_LONG(dest, *(long*)value); @@ -635,7 +635,7 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ } } break; - + case PDO_PARAM_STR: if (value && !(value_len == 0 && stmt->dbh->oracle_nulls == PDO_NULL_EMPTY_STRING)) { ZVAL_STRINGL(dest, value, value_len, !caller_frees); @@ -666,7 +666,7 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ ; } } - + if (caller_frees && value) { efree(value); } @@ -705,7 +705,7 @@ static int do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, if (!stmt->columns && !pdo_stmt_describe_columns(stmt TSRMLS_CC)) { return 0; } - + if (!dispatch_param_event(stmt, PDO_PARAM_EVT_FETCH_POST TSRMLS_CC)) { return 0; } @@ -751,7 +751,7 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ stmt->fetch.cls.ce = ZEND_STANDARD_CLASS_DEF_PTR; ce = ZEND_STANDARD_CLASS_DEF_PTR; } - + if (ce->constructor) { fci->function_table = &ce->function_table; fci->function_name = NULL; @@ -780,7 +780,7 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * { char *is_callable_error = NULL; - if (zend_fcall_info_init(callable, 0, fci, fcc, NULL, &is_callable_error TSRMLS_CC) == FAILURE) { + if (zend_fcall_info_init(callable, 0, fci, fcc, NULL, &is_callable_error TSRMLS_CC) == FAILURE) { if (is_callable_error) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", is_callable_error TSRMLS_CC); efree(is_callable_error); @@ -793,10 +793,10 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * /* Possible E_STRICT error message */ efree(is_callable_error); } - + fci->param_count = num_args; /* probably less */ fci->params = safe_emalloc(sizeof(zval**), num_args, 0); - + return 1; } /* }}} */ @@ -909,7 +909,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, } else if (flags == PDO_FETCH_GROUP && colno) { fetch_value(stmt, return_value, 0, NULL TSRMLS_CC); } else { - fetch_value(stmt, return_value, colno, NULL TSRMLS_CC); + fetch_value(stmt, return_value, colno, NULL TSRMLS_CC); } if (!return_all) { return 1; @@ -976,7 +976,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, } } break; - + case PDO_FETCH_INTO: if (!stmt->fetch.into) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch-into object specified." TSRMLS_CC); @@ -1006,13 +1006,13 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, } } break; - + default: /* shouldn't happen */ return 0; } - + if (return_all && how != PDO_FETCH_KEY_PAIR) { INIT_PZVAL(&grp_val); if (flags == PDO_FETCH_GROUP && how == PDO_FETCH_COLUMN && stmt->fetch.column > 0) { @@ -1037,7 +1037,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, case PDO_FETCH_ASSOC: add_assoc_zval(return_value, stmt->columns[i].name, val); break; - + case PDO_FETCH_KEY_PAIR: { zval *tmp; @@ -1144,12 +1144,12 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, } } break; - + case PDO_FETCH_FUNC: stmt->fetch.func.values[idx] = val; stmt->fetch.cls.fci.params[idx] = &stmt->fetch.func.values[idx]; break; - + default: zval_ptr_dtor(&val); pdo_raise_impl_error(stmt->dbh, stmt, "22003", "mode is out of range" TSRMLS_CC); @@ -1157,7 +1157,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, break; } } - + switch (how) { case PDO_FETCH_CLASS: if (ce->constructor && !(flags & (PDO_FETCH_PROPS_LATE | PDO_FETCH_SERIALIZE))) { @@ -1199,7 +1199,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, zval_ptr_dtor(&stmt->fetch.func.values[idx]); } break; - + default: break; } @@ -1236,7 +1236,7 @@ static int pdo_stmt_verify_mode(pdo_stmt_t *stmt, long mode, int fetch_all TSRML pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "invalid fetch mode" TSRMLS_CC); return 0; } - + if (mode == PDO_FETCH_USE_DEFAULT) { flags = stmt->default_fetch_type & PDO_FETCH_FLAGS; mode = stmt->default_fetch_type & ~PDO_FETCH_FLAGS; @@ -1256,7 +1256,7 @@ static int pdo_stmt_verify_mode(pdo_stmt_t *stmt, long mode, int fetch_all TSRML 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" TSRMLS_CC); @@ -1333,7 +1333,7 @@ static PHP_METHOD(PDOStatement, fetchObject) old_ce = stmt->fetch.cls.ce; old_ctor_args = stmt->fetch.cls.ctor_args; old_arg_count = stmt->fetch.cls.fci.param_count; - + do_fetch_opt_finish(stmt, 0 TSRMLS_CC); if (ctor_args) { @@ -1405,7 +1405,7 @@ static PHP_METHOD(PDOStatement, fetchAll) zend_class_entry *old_ce; zval *old_ctor_args, *ctor_args = NULL; int error = 0, flags, old_arg_count; - PHP_STMT_GET_OBJ; + PHP_STMT_GET_OBJ; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lzz", &how, &arg2, &ctor_args)) { RETURN_FALSE; @@ -1474,7 +1474,7 @@ static PHP_METHOD(PDOStatement, fetchAll) break; } break; - + case PDO_FETCH_COLUMN: switch(ZEND_NUM_ARGS()) { case 0: @@ -1499,7 +1499,7 @@ static PHP_METHOD(PDOStatement, fetchAll) } flags = how & PDO_FETCH_FLAGS; - + if ((how & ~PDO_FETCH_FLAGS) == PDO_FETCH_USE_DEFAULT) { flags |= stmt->default_fetch_type & PDO_FETCH_FLAGS; how |= stmt->default_fetch_type & ~PDO_FETCH_FLAGS; @@ -1508,7 +1508,7 @@ static PHP_METHOD(PDOStatement, fetchAll) if (!error) { PDO_STMT_CLEAR_ERR(); MAKE_STD_ZVAL(data); - if ( (how & PDO_FETCH_GROUP) || how == PDO_FETCH_KEY_PAIR || + if ( (how & PDO_FETCH_GROUP) || how == PDO_FETCH_KEY_PAIR || (how == PDO_FETCH_USE_DEFAULT && stmt->default_fetch_type == PDO_FETCH_KEY_PAIR) ) { array_init(return_value); @@ -1537,13 +1537,13 @@ static PHP_METHOD(PDOStatement, fetchAll) } FREE_ZVAL(data); } - + do_fetch_opt_finish(stmt, 0 TSRMLS_CC); stmt->fetch.cls.ce = old_ce; stmt->fetch.cls.ctor_args = old_ctor_args; stmt->fetch.cls.fci.param_count = old_arg_count; - + if (error) { PDO_HANDLE_STMT_ERR(); if (error != 2) { @@ -1569,14 +1569,14 @@ static int register_bound_param(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, "lz|llz!", ¶m.paramno, ¶m.parameter, ¶m_type, ¶m.max_value_len, ¶m.driver_params)) { if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|llz!", ¶m.name, - ¶m.namelen, ¶m.parameter, ¶m_type, ¶m.max_value_len, + ¶m.namelen, ¶m.parameter, ¶m_type, ¶m.max_value_len, ¶m.driver_params)) { return 0; - } + } } - + param.param_type = (int) param_type; - + if (param.paramno > 0) { --param.paramno; /* make it zero-based internally */ } else if (!param.name) { @@ -1604,7 +1604,7 @@ static PHP_METHOD(PDOStatement, bindValue) PHP_STMT_GET_OBJ; param.paramno = -1; - + if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz/|l", ¶m.paramno, ¶m.parameter, ¶m_type)) { if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|l", ¶m.name, @@ -1614,14 +1614,14 @@ static PHP_METHOD(PDOStatement, bindValue) } param.param_type = (int) param_type; - + if (param.paramno > 0) { --param.paramno; /* make it zero-based internally */ } else if (!param.name) { pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "Columns/Parameters are 1-based" TSRMLS_CC); RETURN_FALSE; } - + Z_ADDREF_P(param.parameter); if (!really_register_bound_param(¶m, stmt, TRUE TSRMLS_CC)) { if (param.parameter) { @@ -1758,7 +1758,7 @@ static int generic_stmt_attr_get(pdo_stmt_t *stmt, zval *return_value, long attr } return 0; } - + static PHP_METHOD(PDOStatement, getAttribute) { long attr; @@ -1859,7 +1859,7 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in zval ***args; zend_class_entry **cep; int retval; - + do_fetch_opt_finish(stmt, 1 TSRMLS_CC); switch (stmt->default_fetch_type) { @@ -1872,7 +1872,7 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in default: ; } - + stmt->default_fetch_type = PDO_FETCH_BOTH; if (argc == 0) { @@ -1882,7 +1882,7 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in args = safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval*), 0); retval = zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args); - + if (SUCCESS == retval) { if (Z_TYPE_PP(args[skip]) != IS_LONG) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "mode must be an integer" TSRMLS_CC); @@ -1890,11 +1890,11 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in } else { mode = Z_LVAL_PP(args[skip]); flags = mode & PDO_FETCH_FLAGS; - + retval = pdo_stmt_verify_mode(stmt, mode, 0 TSRMLS_CC); } } - + if (FAILURE == retval) { PDO_STMT_CLEAR_ERR(); efree(args); @@ -1978,7 +1978,7 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in do_fetch_class_prepare(stmt TSRMLS_CC); } } - + break; case PDO_FETCH_INTO: @@ -1989,13 +1989,13 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in } else { retval = SUCCESS; } - + if (SUCCESS == retval) { #ifdef ilia_0 /* we'll only need this when we have persistent statements, if ever */ if (stmt->dbh->is_persistent) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release"); } -#endif +#endif MAKE_STD_ZVAL(stmt->fetch.into); Z_TYPE_P(stmt->fetch.into) = IS_OBJECT; @@ -2003,9 +2003,9 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in Z_OBJ_HT_P(stmt->fetch.into) = Z_OBJ_HT_PP(args[skip+1]); zend_objects_store_add_ref(stmt->fetch.into TSRMLS_CC); } - + break; - + default: pdo_raise_impl_error(stmt->dbh, stmt, "22003", "Invalid fetch mode specified" TSRMLS_CC); } @@ -2024,10 +2024,10 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in PDO_STMT_CLEAR_ERR(); efree(args); - + return retval; } - + static PHP_METHOD(PDOStatement, setFetchMode) { PHP_STMT_GET_OBJ; @@ -2048,7 +2048,7 @@ static int pdo_stmt_do_next_rowset(pdo_stmt_t *stmt TSRMLS_DC) if (stmt->columns) { int i; struct pdo_column_data *cols = stmt->columns; - + for (i = 0; i < stmt->column_count; i++) { efree(cols[i].name); } @@ -2078,7 +2078,7 @@ static PHP_METHOD(PDOStatement, nextRowset) } PDO_STMT_CLEAR_ERR(); - + if (!pdo_stmt_do_next_rowset(stmt TSRMLS_CC)) { PDO_HANDLE_STMT_ERR(); RETURN_FALSE; @@ -2106,7 +2106,7 @@ static PHP_METHOD(PDOStatement, closeCursor) if (!pdo_stmt_do_next_rowset(stmt TSRMLS_CC)) { break; } - + } while (1); stmt->executed = 0; RETURN_TRUE; @@ -2135,14 +2135,14 @@ static PHP_METHOD(PDOStatement, debugDumpParams) if (out == NULL) { RETURN_FALSE; } - + php_stream_printf(out TSRMLS_CC, "SQL: [%d] %.*s\n", stmt->query_stringlen, stmt->query_stringlen, stmt->query_string); php_stream_printf(out TSRMLS_CC, "Params: %d\n", stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0); - + if (stmt->bound_params) { zend_hash_internal_pointer_reset_ex(stmt->bound_params, &pos); while (SUCCESS == zend_hash_get_current_data_ex(stmt->bound_params, @@ -2163,7 +2163,7 @@ static PHP_METHOD(PDOStatement, debugDumpParams) param->paramno, param->namelen, param->namelen, param->name ? param->name : "", param->is_param, param->param_type); - + zend_hash_move_forward_ex(stmt->bound_params, &pos); } } @@ -2241,47 +2241,51 @@ static void dbstmt_prop_delete(zval *object, zval *member, const zend_literal *k } static union _zend_function *dbstmt_method_get( -#if PHP_API_VERSION >= 20041225 zval **object_pp, -#else - zval *object, -#endif char *method_name, int method_len, const zend_literal *key TSRMLS_DC) { zend_function *fbc = NULL; char *lc_method_name; -#if PHP_API_VERSION >= 20041225 zval *object = *object_pp; -#endif + zend_function *fbc_fallback = NULL; lc_method_name = emalloc(method_len + 1); zend_str_tolower_copy(lc_method_name, method_name, method_len); - if (zend_hash_find(&Z_OBJCE_P(object)->function_table, lc_method_name, + if (zend_hash_find(&Z_OBJCE_P(object)->function_table, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { + + /* Prepare fallback by running standard method for functions. + * If the function does not find a method to instanciate it will return this fallback method. */ + fbc_fallback = std_object_handlers.get_method(object_pp, method_name, method_len, key TSRMLS_CC); + pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(object TSRMLS_CC); /* instance not created by PDO object */ if (!stmt->dbh) { + fbc = fbc_fallback; goto out; } /* not a pre-defined method, nor a user-defined method; check * the driver specific methods */ if (!stmt->dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_STMT]) { - if (!pdo_hash_methods(stmt->dbh, + if (!pdo_hash_methods(stmt->dbh, PDO_DBH_DRIVER_METHOD_KIND_STMT TSRMLS_CC) || !stmt->dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_STMT]) { + + fbc = fbc_fallback; goto out; } } if (zend_hash_find(stmt->dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_STMT], lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { - fbc = NULL; + + fbc = fbc_fallback; goto out; } /* got it */ } - + out: efree(lc_method_name); return fbc; @@ -2305,15 +2309,15 @@ static zend_object_value dbstmt_clone_obj(zval *zobject TSRMLS_DC) stmt->refcount = 1; old_stmt = (pdo_stmt_t *)zend_object_store_get_object(zobject TSRMLS_CC); - + retval.handle = zend_objects_store_put(stmt, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbstmt_free_storage, (zend_objects_store_clone_t)dbstmt_clone_obj TSRMLS_CC); retval.handlers = Z_OBJ_HT_P(zobject); zend_objects_clone_members((zend_object *)stmt, retval, (zend_object *)old_stmt, handle TSRMLS_CC); - + zend_objects_store_add_ref(&old_stmt->database_object_handle TSRMLS_CC); stmt->database_object_handle = old_stmt->database_object_handle; - + return retval; } @@ -2328,7 +2332,7 @@ void pdo_stmt_init(TSRMLS_D) pdo_dbstmt_ce = zend_register_internal_class(&ce TSRMLS_CC); pdo_dbstmt_ce->get_iterator = pdo_stmt_iter_get; pdo_dbstmt_ce->create_object = pdo_dbstmt_new; - zend_class_implements(pdo_dbstmt_ce TSRMLS_CC, 1, zend_ce_traversable); + zend_class_implements(pdo_dbstmt_ce TSRMLS_CC, 1, zend_ce_traversable); zend_declare_property_null(pdo_dbstmt_ce, "queryString", sizeof("queryString")-1, ZEND_ACC_PUBLIC TSRMLS_CC); memcpy(&pdo_dbstmt_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); @@ -2388,7 +2392,7 @@ static void free_statement(pdo_stmt_t *stmt TSRMLS_DC) FREE_ZVAL(stmt->fetch.into); stmt->fetch.into = NULL; } - + do_fetch_opt_finish(stmt, 1 TSRMLS_CC); zend_objects_store_del_ref(&stmt->database_object_handle TSRMLS_CC); @@ -2450,7 +2454,7 @@ static void pdo_stmt_iter_dtor(zend_object_iterator *iter TSRMLS_DC) if (--I->stmt->refcount == 0) { free_statement(I->stmt TSRMLS_CC); } - + if (I->fetch_ahead) { zval_ptr_dtor(&I->fetch_ahead); } @@ -2594,7 +2598,7 @@ static zval *row_prop_read(zval *object, zval *member, int type, const zend_lite Z_SET_REFCOUNT_P(return_value, 0); Z_UNSET_ISREF_P(return_value); - + return return_value; } @@ -2660,7 +2664,7 @@ static HashTable *row_get_properties(zval *object TSRMLS_DC) if (stmt == NULL) { return NULL; } - + if (!stmt->std.properties) { rebuild_object_properties(&stmt->std); } @@ -2676,11 +2680,7 @@ static HashTable *row_get_properties(zval *object TSRMLS_DC) } static union _zend_function *row_method_get( -#if PHP_API_VERSION >= 20041225 zval **object_pp, -#else - zval *object, -#endif char *method_name, int method_len, const zend_literal *key TSRMLS_DC) { zend_function *fbc; @@ -2693,7 +2693,7 @@ static union _zend_function *row_method_get( efree(lc_method_name); return NULL; } - + efree(lc_method_name); return fbc; } @@ -2767,7 +2767,7 @@ void pdo_row_free_storage(pdo_stmt_t *stmt TSRMLS_DC) { if (stmt) { ZVAL_NULL(&stmt->lazy_object_ref); - + if (--stmt->refcount == 0) { free_statement(stmt TSRMLS_CC); } 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-- + +--FILE-- +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