Merge branch 'PHP-8.4'

* PHP-8.4:
  Lazy objects: Update class constants earlier
This commit is contained in:
Arnaud Le Blanc 2024-10-22 12:20:18 +02:00
commit 96ac2c425f
No known key found for this signature in database
GPG Key ID: 0098C05DD15ABC13
4 changed files with 31 additions and 65 deletions

View File

@ -1,27 +0,0 @@
--TEST--
Lazy objects: Class constants are updated before initialization
--FILE--
<?php
class C {
public stdClass $a = FOO;
}
$reflector = new ReflectionClass(C::class);
$c = $reflector->newLazyGhost(function () { });
function f() {
define('FOO', new stdClass);
}
f();
try {
var_dump($c->a);
} catch (\Error $e) {
printf("%s: %s\n", $e::class, $e->getMessage());
}
--EXPECTF--
object(stdClass)#%d (0) {
}

View File

@ -1,26 +0,0 @@
--TEST--
Lazy objects: Class constants are updated before initialization: update constant failure
--FILE--
<?php
class C {
public C $a = FOO;
}
$reflector = new ReflectionClass(C::class);
$c = $reflector->newLazyGhost(function () { });
function f() {
define('FOO', new stdClass);
}
f();
try {
var_dump($c->a);
} catch (\Error $e) {
printf("%s: %s\n", $e::class, $e->getMessage());
}
--EXPECT--
TypeError: Cannot assign stdClass to property C::$a of type C

View File

@ -0,0 +1,22 @@
--TEST--
oss-fuzz #71407
--FILE--
<?php
class C {
public $x=x;
}
$reflector = new ReflectionClass(C::class);
try {
$obj = $reflector->newLazyGhost(function() {});
clone $obj;
} catch (Error $e) {
printf("%s: %s\n", $e::class, $e->getMessage());
}
?>
--EXPECT--
Error: Undefined constant "x"

View File

@ -259,6 +259,13 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj,
return NULL;
}
if (UNEXPECTED(!(reflection_ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
if (UNEXPECTED(zend_update_class_constants(reflection_ce) != SUCCESS)) {
ZEND_ASSERT(EG(exception));
return NULL;
}
}
obj = zend_objects_new(reflection_ce);
for (int i = 0; i < obj->ce->default_properties_count; i++) {
@ -373,12 +380,7 @@ ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj)
zend_class_entry *ce = obj->ce;
if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
ZEND_ASSERT(EG(exception));
return NULL;
}
}
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED);
zval *default_properties_table = CE_DEFAULT_PROPERTIES_TABLE(ce);
zval *properties_table = obj->properties_table;
@ -568,12 +570,7 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj)
zend_class_entry *ce = obj->ce;
if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
ZEND_ASSERT(EG(exception));
return NULL;
}
}
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED);
if (zend_object_is_lazy_proxy(obj)) {
return zend_lazy_object_init_proxy(obj);