mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Fix ReflectionProperty::isInitialized() for hooked props
In zend_std_has_property with ZEND_PROPERTY_EXISTS, we'd just return true when no get hook was present. However, this function is supposed to return false for uninitialized properties. PROPERTY_EXISTS is somewhat of a misnomer. Virtual properties continue to always return true, given there's no backing value to check. Fixes GH-15694 Closes GH-15822
This commit is contained in:
parent
bdcb2185aa
commit
025ed70ce3
2
NEWS
2
NEWS
@ -49,6 +49,8 @@ PHP NEWS
|
|||||||
- Reflection:
|
- Reflection:
|
||||||
. Fixed bug GH-15718 (Segfault on ReflectionProperty::get{Hook,Hooks}() on
|
. Fixed bug GH-15718 (Segfault on ReflectionProperty::get{Hook,Hooks}() on
|
||||||
dynamic properties). (DanielEScherzer)
|
dynamic properties). (DanielEScherzer)
|
||||||
|
. Fixed bug GH-15694 (ReflectionProperty::isInitialized() is incorrect for
|
||||||
|
hooked properties). (ilutov)
|
||||||
|
|
||||||
- SOAP:
|
- SOAP:
|
||||||
. Fixed bug #61525 (SOAP functions require at least one space after HTTP
|
. Fixed bug #61525 (SOAP functions require at least one space after HTTP
|
||||||
|
@ -2208,6 +2208,15 @@ found:
|
|||||||
}
|
}
|
||||||
} else if (IS_HOOKED_PROPERTY_OFFSET(property_offset)) {
|
} else if (IS_HOOKED_PROPERTY_OFFSET(property_offset)) {
|
||||||
zend_function *get = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
|
zend_function *get = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
|
||||||
|
|
||||||
|
if (has_set_exists == ZEND_PROPERTY_EXISTS) {
|
||||||
|
if (prop_info->flags & ZEND_ACC_VIRTUAL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
property_offset = prop_info->offset;
|
||||||
|
goto try_again;
|
||||||
|
}
|
||||||
|
|
||||||
if (!get) {
|
if (!get) {
|
||||||
if (prop_info->flags & ZEND_ACC_VIRTUAL) {
|
if (prop_info->flags & ZEND_ACC_VIRTUAL) {
|
||||||
zend_throw_error(NULL, "Property %s::$%s is write-only",
|
zend_throw_error(NULL, "Property %s::$%s is write-only",
|
||||||
@ -2219,19 +2228,12 @@ found:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_set_exists == ZEND_PROPERTY_EXISTS) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
zval rv;
|
zval rv;
|
||||||
if (!zend_call_get_hook(prop_info, name, get, zobj, &rv)) {
|
if (!zend_call_get_hook(prop_info, name, get, zobj, &rv)) {
|
||||||
if (EG(exception)) {
|
if (EG(exception)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
property_offset = prop_info->offset;
|
property_offset = prop_info->offset;
|
||||||
if (!ZEND_TYPE_IS_SET(prop_info->type)) {
|
|
||||||
prop_info = NULL;
|
|
||||||
}
|
|
||||||
goto try_again;
|
goto try_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
--TEST--
|
||||||
|
ReflectionProperty::isInitialized() on hooked properties
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
// Plain
|
||||||
|
public $p1;
|
||||||
|
public string $p2;
|
||||||
|
// Virtual
|
||||||
|
public $v1 { get => throw new Exception(); }
|
||||||
|
public $v2 { set { throw new Exception(); } }
|
||||||
|
// Backed
|
||||||
|
public $b1 { get => throw new Exception($this->b1); }
|
||||||
|
public string $b2 { get => throw new Exception($this->b2); }
|
||||||
|
public $b3 { set => throw new Exception(); }
|
||||||
|
public string $b4 { set => throw new Exception(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
$test = new Test();
|
||||||
|
$rc = new ReflectionClass(Test::class);
|
||||||
|
foreach ($rc->getProperties() as $rp) {
|
||||||
|
echo $rp->getName(), "\n";
|
||||||
|
var_dump($rp->isInitialized($test));
|
||||||
|
try {
|
||||||
|
$rp->setRawValue($test, 42);
|
||||||
|
} catch (Error $e) {}
|
||||||
|
var_dump($rp->isInitialized($test));
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
p1
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
p2
|
||||||
|
bool(false)
|
||||||
|
bool(true)
|
||||||
|
v1
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
v2
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
b1
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
b2
|
||||||
|
bool(false)
|
||||||
|
bool(true)
|
||||||
|
b3
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
b4
|
||||||
|
bool(false)
|
||||||
|
bool(true)
|
Loading…
Reference in New Issue
Block a user