Commit graph

11 commits

Author SHA1 Message Date
Tim Düsterhus
f61ae0001c
Zend: constify various parameters in zend_object_handlers and zend_lazy_objects (#19019) 2025-07-03 16:32:10 +02:00
Ilija Tovilo
d5bdf8f508
Fix segfault when evaluating const expr default value of child prop with added hooks
Introduced by GH-17870. Not adding a NEWS entry since this is fixed in
the same version.

Fixes oss-fuzz #403816122
Closes GH-18098
2025-03-23 16:35:04 +01:00
Ilija Tovilo
376e90fbf2
Fix circumvented added hooks in JIT
The following code poses a problem in the JIT:

```php
class A {
    public $prop = 1;
}

class B extends A {
    public $prop = 1 {
        get => parent::$prop::get() * 2;
    }
}

function test(A $a) {
    var_dump($a->prop);
}

test(new B);
```

The JIT would assume A::$prop in test() could be accessed directly
through OBJ_PROP_NUM(). However, since child classes can add new hooks
to existing properties, this assumption no longer holds.

To avoid introducing more JIT checks, a hooked property that overrides a
unhooked property now results in a separate zval slot that is used
instead of the parent slot. This causes the JIT to pick the slow path
due to an IS_UNDEF value in the parent slot.

zend_class_entry.properties_info_table poses a problem in that
zend_get_property_info_for_slot() and friends will be called using the
child slot, which does not store its property info, since the parent
slot already does. In this case, zend_get_property_info_for_slot() now
provides a fallback that will iterate all property infos to find the
correct one.

This also uncovered a bug (see Zend/tests/property_hooks/dump.phpt)
where the default value of a parent property would accidentally be
inherited by the child property.

Fixes GH-17376
Closes GH-17870
2025-02-26 21:26:00 +01:00
Arnaud Le Blanc
64081d1380
Lazy objects: Update class constants earlier
If a lazy object is created for a class whose constants can not be updated, then
we have created an instance of a non-instantiable class. This breaks the
expectations of clone.

Here I ensure that a class has its constants updated before creating a lazy
instance of it.

Fixes OSS-Fuzz #71407
Closes GH-15856
2024-10-22 12:19:31 +02:00
Arnaud Le Blanc
c9dfb77446
Deny resetting an object as lazy during property iteration
Supporting object reset while its properties are being iterated would increase
complexity for little benefit. Furthermore it may not be possible to ensure a
consistent behavior between ghosts and proxies (wrt to iteration position).

Iteration is detected by checking if the object's properties ht has iterators.
This requires refactoring the hooked get_iterator() implementation to ensure
that it creates a properties ht iterator immediately.

Closes GH-15960
2024-10-03 15:12:21 +02:00
Arnaud Le Blanc
52fec6958c
Do not null out obj->properties when resetting object
Engine expects the properties ht to be separated, assigned a new ht, or resized,
but never to be nulled.
2024-10-03 15:12:21 +02:00
Arnaud Le Blanc
ab72fbadd9
Fix use-after-free during lazy object initialization (#16004) 2024-10-02 12:15:36 +02:00
DanielEScherzer
ea297654f4
Zend/*: fix a bunch of typos (GH-16017)
* Zend/*: fix a bunch of typos

* Zend/tests/try/try_catch_finally_005.phpt: update string length
2024-09-24 10:55:21 +02:00
Arnaud Le Blanc
cc065bae3f
Fix zend_lazy_object_get_properties for object with prop ht, when init fails (#15825)
zend_lazy_object_get_properties() is used by zend_std_get_properties_ex() to fetch the properties of lazy objects. It initializes the object and returns its properties.

When initialization fails we return an empty ht because most callers do not check for NULL. We rely on the exception thrown during initialization. We also assign that empty ht to zend_object.properties for the same reasons.

We asserted that zend_object.properties was either NULL or &zend_empty_array, but there are other cases in which a uninitialized lazy object may have a properties ht.

Here I remove the assertion, and return the existing properties ht if there is one. Otherwise I return zend_new_array(0) instead of &zend_emtpy_array as not all callers expect an immutable array (e.g. FE_FETCH does not).
2024-09-23 13:47:56 +02:00
Arnaud Le Blanc
c65e042c0b
Fix zend_get_property_info_for_slot() for lazy objects (#15855)
zend_get_property_info_for_slot(obj, slot) assumes that 'slot' belongs to 'obj', but that may not be the case for lazy proxies.

Fortunately, the property info is often already available in path when it is needed.

For other cases, I make zend_get_property_info_for_slot() aware of lazy objects, and add zend_get_property_info_for_slot_self() for cases where the 'slot' is known to belong to the object itself.

Fixes oss-fuzz #71446
2024-09-16 16:58:12 +02:00
Arnaud Le Blanc
58aa6fc830
Lazy objects
RFC: https://wiki.php.net/rfc/lazy-objects

Closes GH-15019
2024-08-30 17:30:03 +02:00