summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--ext/reflection/php_reflection.c9
-rw-r--r--ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt24
3 files changed, 27 insertions, 10 deletions
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) {
+ }
+}