mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Real instance of lazy proxy may have less magic methods
This commit is contained in:
2
NEWS
2
NEWS
@@ -11,6 +11,8 @@ PHP NEWS
|
||||
(alexandre-daubois)
|
||||
. Fixed bug GH-20657 (Assertion failure in zend_lazy_object_get_info triggered
|
||||
by setRawValueWithoutLazyInitialization() and newLazyGhost()). (Arnaud)
|
||||
. Fixed bug GH-20504 (Assertion failure in zend_get_property_guard when
|
||||
accessing properties on Reflection LazyProxy via isset()). (Arnaud)
|
||||
|
||||
- DOM:
|
||||
. Fixed bug GH-21077 (Accessing Dom\Node::baseURI can throw TypeError).
|
||||
|
||||
24
Zend/tests/lazy_objects/gh20504-001.phpt
Normal file
24
Zend/tests/lazy_objects/gh20504-001.phpt
Normal file
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - isset
|
||||
--CREDITS--
|
||||
vi3tL0u1s
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class RealInstance {
|
||||
public $_;
|
||||
}
|
||||
class Proxy extends RealInstance {
|
||||
public function __isset($name) {
|
||||
return isset($this->$name['']);
|
||||
}
|
||||
}
|
||||
$rc = new ReflectionClass(Proxy::class);
|
||||
$obj = $rc->newLazyProxy(function () {
|
||||
return new RealInstance;
|
||||
});
|
||||
var_dump(isset($obj->name['']));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
23
Zend/tests/lazy_objects/gh20504-002.phpt
Normal file
23
Zend/tests/lazy_objects/gh20504-002.phpt
Normal file
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - get
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class RealInstance {
|
||||
public $_;
|
||||
}
|
||||
class Proxy extends RealInstance {
|
||||
public function __get($name) {
|
||||
return $this->$name;
|
||||
}
|
||||
}
|
||||
$rc = new ReflectionClass(Proxy::class);
|
||||
$obj = $rc->newLazyProxy(function () {
|
||||
return new RealInstance;
|
||||
});
|
||||
var_dump($obj->name);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Undefined property: RealInstance::$name in %s on line %d
|
||||
NULL
|
||||
33
Zend/tests/lazy_objects/gh20504-003.phpt
Normal file
33
Zend/tests/lazy_objects/gh20504-003.phpt
Normal file
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - set
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[AllowDynamicProperties]
|
||||
class RealInstance {
|
||||
public $_;
|
||||
}
|
||||
class Proxy extends RealInstance {
|
||||
public function __set($name, $value) {
|
||||
$this->$name = $value;
|
||||
}
|
||||
}
|
||||
$rc = new ReflectionClass(Proxy::class);
|
||||
$obj = $rc->newLazyProxy(function () {
|
||||
return new RealInstance;
|
||||
});
|
||||
$obj->name = 0;
|
||||
|
||||
var_dump($obj);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
lazy proxy object(Proxy)#%d (1) {
|
||||
["instance"]=>
|
||||
object(RealInstance)#%d (2) {
|
||||
["_"]=>
|
||||
NULL
|
||||
["name"]=>
|
||||
int(0)
|
||||
}
|
||||
}
|
||||
28
Zend/tests/lazy_objects/gh20504-004.phpt
Normal file
28
Zend/tests/lazy_objects/gh20504-004.phpt
Normal file
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - proxy defines __isset(), both have guards
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class RealInstance {
|
||||
public $_;
|
||||
public function __get($name) {
|
||||
printf("%s::%s\n", static::class, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
class Proxy extends RealInstance {
|
||||
public function __isset($name) {
|
||||
printf("%s::%s\n", static::class, __FUNCTION__);
|
||||
return isset($this->$name['']);
|
||||
}
|
||||
}
|
||||
$rc = new ReflectionClass(Proxy::class);
|
||||
$obj = $rc->newLazyProxy(function () {
|
||||
return new RealInstance;
|
||||
});
|
||||
var_dump(isset($obj->name['']));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Proxy::__isset
|
||||
Proxy::__get
|
||||
bool(false)
|
||||
30
Zend/tests/lazy_objects/gh20504-005.phpt
Normal file
30
Zend/tests/lazy_objects/gh20504-005.phpt
Normal file
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - unset
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class RealInstance {
|
||||
public $_;
|
||||
}
|
||||
class Proxy extends RealInstance {
|
||||
public function __unset($name) {
|
||||
unset($this->$name);
|
||||
}
|
||||
}
|
||||
$rc = new ReflectionClass(Proxy::class);
|
||||
$obj = $rc->newLazyProxy(function () {
|
||||
return new RealInstance;
|
||||
});
|
||||
unset($obj->name);
|
||||
|
||||
var_dump($obj);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
lazy proxy object(Proxy)#%d (1) {
|
||||
["instance"]=>
|
||||
object(RealInstance)#%d (1) {
|
||||
["_"]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
@@ -960,25 +960,27 @@ call_getter:
|
||||
uninit_error:
|
||||
if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
|
||||
if (!prop_info || (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY)) {
|
||||
zobj = zend_lazy_object_init(zobj);
|
||||
if (!zobj) {
|
||||
zend_object *instance = zend_lazy_object_init(zobj);
|
||||
if (!instance) {
|
||||
retval = &EG(uninitialized_zval);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(guard)) {
|
||||
if (UNEXPECTED(guard && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS))) {
|
||||
/* Find which guard was used on zobj, so we can set the same
|
||||
* guard on instance. */
|
||||
uint32_t guard_type = (type == BP_VAR_IS) && zobj->ce->__isset
|
||||
? IN_ISSET : IN_GET;
|
||||
guard = zend_get_property_guard(zobj, name);
|
||||
guard = zend_get_property_guard(instance, name);
|
||||
if (!((*guard) & guard_type)) {
|
||||
(*guard) |= guard_type;
|
||||
retval = zend_std_read_property(zobj, name, type, cache_slot, rv);
|
||||
retval = zend_std_read_property(instance, name, type, cache_slot, rv);
|
||||
(*guard) &= ~guard_type;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
return zend_std_read_property(zobj, name, type, cache_slot, rv);
|
||||
return zend_std_read_property(instance, name, type, cache_slot, rv);
|
||||
}
|
||||
}
|
||||
if (type != BP_VAR_IS) {
|
||||
@@ -1017,7 +1019,7 @@ static zval *forward_write_to_lazy_object(zend_object *zobj,
|
||||
return &EG(error_zval);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(guarded)) {
|
||||
if (UNEXPECTED(guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS))) {
|
||||
uint32_t *guard = zend_get_property_guard(instance, name);
|
||||
if (!((*guard) & IN_SET)) {
|
||||
(*guard) |= IN_SET;
|
||||
@@ -1601,7 +1603,7 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
|
||||
return;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(guard)) {
|
||||
if (UNEXPECTED(guard && zobj->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
|
||||
guard = zend_get_property_guard(zobj, name);
|
||||
if (!((*guard) & IN_UNSET)) {
|
||||
(*guard) |= IN_UNSET;
|
||||
|
||||
Reference in New Issue
Block a user