1
0
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:
  Mark object non-lazy before deleting info in zend_lazy_object_realize()
This commit is contained in:
Arnaud Le Blanc
2026-02-03 11:49:48 +01:00
4 changed files with 78 additions and 2 deletions

2
NEWS
View File

@@ -9,6 +9,8 @@ PHP NEWS
(arshidkv12)
. Fix deprecation now showing when accessing null key of an array with JIT.
(alexandre-daubois)
. Fixed bug GH-20657 (Assertion failure in zend_lazy_object_get_info triggered
by setRawValueWithoutLazyInitialization() and newLazyGhost()). (Arnaud)
- DOM:
. Fixed bug GH-21077 (Accessing Dom\Node::baseURI can throw TypeError).

View File

@@ -0,0 +1,32 @@
--TEST--
GH-20657: GC during zend_lazy_object_realize()
--CREDITS--
vi3tL0u1s
--FILE--
<?php
class C {
public $a;
}
$reflector = new ReflectionClass(C::class);
for ($i = 0; $i < 10000; $i++) {
$obj = $reflector->newLazyGhost(function ($obj) {});
// Add to roots
$obj2 = $obj;
unset($obj2);
// Initialize all props to mark object non-lazy. Also create a cycle.
$reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $obj);
}
var_dump($obj);
?>
--EXPECTF--
object(C)#%d (1) {
["a"]=>
*RECURSION*
}

View File

@@ -0,0 +1,43 @@
--TEST--
GH-20657 002: GC during zend_lazy_object_realize() - reset as lazy during realize()
--FILE--
<?php
class C {
public $a;
}
class D {
public $self;
public function __construct() {
$this->self = $this;
}
public function __destruct() {
global $obj, $reflector;
$reflector->resetAsLazyGhost($obj, function () {});
}
}
new D();
$reflector = new ReflectionClass(C::class);
for ($i = 0; $i < 10000; $i++) {
$obj = $reflector->newLazyGhost(function ($obj) {});
// Add to roots
$obj2 = $obj;
unset($obj2);
// Initialize all props to mark object non-lazy. Also create a cycle.
$reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $obj);
}
var_dump($obj);
?>
--EXPECTF--
object(C)#%d (1) {
["a"]=>
*RECURSION*
}

View File

@@ -678,8 +678,6 @@ void zend_lazy_object_realize(zend_object *obj)
ZEND_ASSERT(zend_object_is_lazy(obj));
ZEND_ASSERT(!zend_lazy_object_initialized(obj));
zend_lazy_object_del_info(obj);
#if ZEND_DEBUG
for (int i = 0; i < obj->ce->default_properties_count; i++) {
ZEND_ASSERT(!(Z_PROP_FLAG_P(&obj->properties_table[i]) & IS_PROP_LAZY));
@@ -687,6 +685,7 @@ void zend_lazy_object_realize(zend_object *obj)
#endif
OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY);
zend_lazy_object_del_info(obj);
}
ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object)