Commit: e6bde1f8f6d8b5d32e608926dd2af2e0f82a5de5 Author: Xinchen Hui <larue...@php.net> Tue, 22 Jan 2013 16:58:40 +0800 Parents: 51e5022364228fb55753902ea3ee63c27661e02c Branches: PHP-5.5
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e6bde1f8f6d8b5d32e608926dd2af2e0f82a5de5 Log: Fix test related to change for #bug64007 and also fix in newInstanceArgs Bugs: https://bugs.php.net/64007 Changed paths: M ext/pdo/pdo_stmt.c M ext/pdo/tests/pdo_036.phpt M ext/reflection/php_reflection.c M ext/reflection/tests/bug64007.phpt Diff: diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index a469d09..5dc445f 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -2733,6 +2733,7 @@ static union _zend_function *row_get_ctor(zval *object TSRMLS_DC) ctor.function_name = "__construct"; ctor.scope = pdo_row_ce; ctor.handler = ZEND_FN(dbstmt_constructor); + ctor.fn_flags = ZEND_ACC_PUBLIC; return (union _zend_function*)&ctor; } diff --git a/ext/pdo/tests/pdo_036.phpt b/ext/pdo/tests/pdo_036.phpt index 94006c9..55c8876 100644 --- a/ext/pdo/tests/pdo_036.phpt +++ b/ext/pdo/tests/pdo_036.phpt @@ -5,19 +5,19 @@ Testing PDORow and PDOStatement instances with Reflection --FILE-- <?php -$instance = new reflectionclass('pdorow'); +$instance = new reflectionclass('pdostatement'); $x = $instance->newInstance(); var_dump($x); -$instance = new reflectionclass('pdostatement'); +$instance = new reflectionclass('pdorow'); $x = $instance->newInstance(); var_dump($x); ?> --EXPECTF-- -object(PDORow)#%d (0) { -} object(PDOStatement)#%d (1) { [%u|b%"queryString"]=> NULL } + +Fatal error: PDORow::__construct(): You should not create a PDOStatement manually in %spdo_036.php on line %d diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 5c844b8..15befa2 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4212,7 +4212,7 @@ ZEND_METHOD(reflection_class, newInstance) zend_fcall_info fci; zend_fcall_info_cache fcc; - if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) { + if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name); zval_dtor(return_value); RETURN_NULL(); @@ -4237,7 +4237,7 @@ ZEND_METHOD(reflection_class, newInstance) fci.no_separation = 1; fcc.initialized = 1; - fcc.function_handler = ce->constructor; + fcc.function_handler = constructor; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(return_value); fcc.object_ptr = return_value; @@ -4289,9 +4289,10 @@ ZEND_METHOD(reflection_class, newInstanceArgs) { zval *retval_ptr = NULL; reflection_object *intern; - zend_class_entry *ce; + zend_class_entry *ce, *old_scope; int argc = 0; HashTable *args; + zend_function *constructor; METHOD_NOTSTATIC(reflection_class_ptr); @@ -4300,19 +4301,28 @@ ZEND_METHOD(reflection_class, newInstanceArgs) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) { return; } + if (ZEND_NUM_ARGS() > 0) { argc = args->nNumOfElements; } + object_init_ex(return_value, ce); + + old_scope = EG(scope); + EG(scope) = ce; + constructor = Z_OBJ_HT_P(return_value)->get_constructor(return_value TSRMLS_CC); + EG(scope) = old_scope; + /* Run the constructor if there is one */ - if (ce->constructor) { + if (constructor) { zval ***params = NULL; zend_fcall_info fci; zend_fcall_info_cache fcc; - if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) { + if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name); - return; + zval_dtor(return_value); + RETURN_NULL(); } if (argc) { @@ -4321,8 +4331,6 @@ ZEND_METHOD(reflection_class, newInstanceArgs) params -= argc; } - object_init_ex(return_value, ce); - fci.size = sizeof(fci); fci.function_table = EG(function_table); fci.function_name = NULL; @@ -4334,7 +4342,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs) fci.no_separation = 1; fcc.initialized = 1; - fcc.function_handler = ce->constructor; + fcc.function_handler = constructor; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(return_value); fcc.object_ptr = return_value; @@ -4347,6 +4355,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs) zval_ptr_dtor(&retval_ptr); } php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name); + zval_dtor(return_value); RETURN_NULL(); } if (retval_ptr) { @@ -4355,9 +4364,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs) if (params) { efree(params); } - } else if (!ZEND_NUM_ARGS() || !argc) { - object_init_ex(return_value, ce); - } else { + } else if (argc) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name); } } diff --git a/ext/reflection/tests/bug64007.phpt b/ext/reflection/tests/bug64007.phpt index 34aac7a..32ec6a5 100644 --- a/ext/reflection/tests/bug64007.phpt +++ b/ext/reflection/tests/bug64007.phpt @@ -3,8 +3,17 @@ Bug #64007 (There is an ability to create instance of Generator by hand) --FILE-- <?php $reflection = new ReflectionClass('Generator'); +try { + $generator = $reflection->newInstanceWithoutConstructor(); + var_dump($generator); +} catch (Exception $e) { + var_dump($e->getMessage()); +} + $generator = $reflection->newInstance(); var_dump($generator); ?> --EXPECTF-- +string(97) "Class Generator is an internal class that cannot be instantiated without invoking its constructor" + Catchable fatal error: The "Generator" class is reserved for internal use and cannot be manually instantiated in %sbug64007.php on line %d -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php