From: Nikita Popov Date: Tue, 13 Aug 2019 18:23:56 +0000 (+0200) Subject: Fixed bug #78410 X-Git-Tag: php-7.4.0beta4~18 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d891b5f458a253befaa56d325ae90518536fc2f0;p=php Fixed bug #78410 --- diff --git a/NEWS b/NEWS index aac83845b5..64f8a51e2a 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,10 @@ PHP NEWS . Fixed bug #78391 (Assertion failure in openssl_random_pseudo_bytes). (Nikita) +- Reflection: + . Fixed bug #78410 (Cannot "manually" unserialize class that is final and + extends an internal one). (Nikita) + 08 Aug 2019, PHP 7.4.0beta2 - Core: diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 4011d8954e..61f09ca643 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4589,7 +4589,7 @@ ZEND_METHOD(reflection_class, isInstance) } /* }}} */ -/* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...) +/* {{{ proto public object ReflectionClass::newInstance(mixed* args, ...) Returns an instance of this class */ ZEND_METHOD(reflection_class, newInstance) { @@ -4663,7 +4663,7 @@ ZEND_METHOD(reflection_class, newInstance) } /* }}} */ -/* {{{ proto public stdclass ReflectionClass::newInstanceWithoutConstructor() +/* {{{ proto public object ReflectionClass::newInstanceWithoutConstructor() Returns an instance of this class without invoking its constructor */ ZEND_METHOD(reflection_class, newInstanceWithoutConstructor) { @@ -4672,7 +4672,8 @@ ZEND_METHOD(reflection_class, newInstanceWithoutConstructor) GET_REFLECTION_OBJECT_PTR(ce); - if (ce->create_object != NULL && ce->ce_flags & ZEND_ACC_FINAL) { + if (ce->type == ZEND_INTERNAL_CLASS + && ce->create_object != NULL && (ce->ce_flags & ZEND_ACC_FINAL)) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s is an internal class marked as final that cannot be instantiated without invoking its constructor", ZSTR_VAL(ce->name)); return; } @@ -4681,7 +4682,7 @@ ZEND_METHOD(reflection_class, newInstanceWithoutConstructor) } /* }}} */ -/* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args]) +/* {{{ proto public object ReflectionClass::newInstanceArgs([array args]) Returns an instance of this class */ ZEND_METHOD(reflection_class, newInstanceArgs) { diff --git a/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt index 334efc3a50..59337f09e8 100644 --- a/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt +++ b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt @@ -22,7 +22,19 @@ $class = new ReflectionClass('DateTime'); var_dump($class->newInstanceWithoutConstructor()); $class = new ReflectionClass('Generator'); +try { + var_dump($class->newInstanceWithoutConstructor()); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} + +final class Bar extends ArrayObject { +} + +$class = new ReflectionClass('Bar'); var_dump($class->newInstanceWithoutConstructor()); + +?> --EXPECTF-- object(Foo)#%d (0) { } @@ -30,9 +42,9 @@ object(stdClass)#%d (0) { } object(DateTime)#%d (0) { } - -Fatal error: Uncaught ReflectionException: Class Generator is an internal class marked as final that cannot be instantiated without invoking its constructor in %sReflectionClass_newInstanceWithoutConstructor.php:%d -Stack trace: -#0 %sReflectionClass_newInstanceWithoutConstructor.php(%d): ReflectionClass->newInstanceWithoutConstructor() -#1 {main} - thrown in %sReflectionClass_newInstanceWithoutConstructor.php on line %d +Class Generator is an internal class marked as final that cannot be instantiated without invoking its constructor +object(Bar)#%d (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } +}