]> granicus.if.org Git - php/commitdiff
Fixed bug #78410
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 13 Aug 2019 18:23:56 +0000 (20:23 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 13 Aug 2019 18:23:56 +0000 (20:23 +0200)
NEWS
ext/reflection/php_reflection.c
ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt

diff --git a/NEWS b/NEWS
index aac83845b56a68e1a43063ef9dace0762b8d8d60..64f8a51e2ac075ee8602b4197db7166a24fd7ab8 100644 (file)
--- 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:
index 4011d8954e2cfdee3d74cae54b3ac34ae432f6ed..61f09ca643be8c5baba1e3eec7f03b235fd64ac4 100644 (file)
@@ -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)
 {
index 334efc3a5051a18cf0b1fa84cb062e75fc8e2754..59337f09e8b42f273df068fb8bd3a0e3568dad73 100644 (file)
@@ -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) {
+  }
+}