diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index e74b7fcb27a7..e560077502ef 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6762,8 +6762,7 @@ ZEND_METHOD(ReflectionProperty, isReadable) RETURN_FALSE; } - if (prop->flags & ZEND_ACC_VIRTUAL) { - ZEND_ASSERT(prop->hooks); + if ((prop->flags & ZEND_ACC_VIRTUAL) && prop->hooks) { if (!prop->hooks[ZEND_PROPERTY_HOOK_GET]) { RETURN_FALSE; } @@ -6854,25 +6853,30 @@ ZEND_METHOD(ReflectionProperty, isWritable) RETURN_FALSE; } - if (prop->flags & ZEND_ACC_VIRTUAL) { - ZEND_ASSERT(prop->hooks); + if ((prop->flags & ZEND_ACC_VIRTUAL) && prop->hooks) { if (!prop->hooks[ZEND_PROPERTY_HOOK_SET]) { RETURN_FALSE; } - } else if (obj && (prop->flags & ZEND_ACC_READONLY)) { + } else if (prop->flags & ZEND_ACC_VIRTUAL) { + if (prop->flags & ZEND_ACC_READONLY) { + RETURN_FALSE; + } + } else if ((prop->flags & ZEND_ACC_READONLY)) { + if (obj) { retry:; - zval *prop_val = OBJ_PROP(obj, prop->offset); - if (Z_TYPE_P(prop_val) == IS_UNDEF - && zend_lazy_object_must_init(obj) - && (Z_PROP_FLAG_P(prop_val) & IS_PROP_LAZY)) { - obj = zend_lazy_object_init(obj); - if (!obj) { - RETURN_THROWS(); + zval *prop_val = OBJ_PROP(obj, prop->offset); + if (Z_TYPE_P(prop_val) == IS_UNDEF + && zend_lazy_object_must_init(obj) + && (Z_PROP_FLAG_P(prop_val) & IS_PROP_LAZY)) { + obj = zend_lazy_object_init(obj); + if (!obj) { + RETURN_THROWS(); + } + goto retry; + } + if (Z_TYPE_P(prop_val) != IS_UNDEF && !(Z_PROP_FLAG_P(prop_val) & IS_PROP_REINITABLE)) { + RETURN_FALSE; } - goto retry; - } - if (Z_TYPE_P(prop_val) != IS_UNDEF && !(Z_PROP_FLAG_P(prop_val) & IS_PROP_REINITABLE)) { - RETURN_FALSE; } } diff --git a/ext/reflection/tests/gh21768.phpt b/ext/reflection/tests/gh21768.phpt new file mode 100644 index 000000000000..422239120dbe --- /dev/null +++ b/ext/reflection/tests/gh21768.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21768: Assertion failure in ReflectionProperty::is{Readable,Writable}() on internal virtual properties +--EXTENSIONS-- +dom +--FILE-- +getProperties() as $rp) { + if (!$rp->isVirtual()) + continue; + if (!$rp->isReadable(null)) + die("$rp should be readable"); + if (!$rp->isWritable(null)) + die("$rp should be writable"); +} +echo "done\n"; + +?> +--EXPECT-- +done