Skip to content

Commit b271f7e

Browse files
deepclone_hydrate: direct slot write for declared props (readonly, internal)
1 parent 44fb537 commit b271f7e

1 file changed

Lines changed: 19 additions & 6 deletions

File tree

deepclone.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,13 +2639,26 @@ PHP_FUNCTION(deepclone_hydrate)
26392639
Z_TRY_ADDREF_P(prop_val);
26402640
zend_hash_update(obj->properties, prop_name, prop_val);
26412641
} else {
2642-
zend_std_write_property(obj, prop_name, prop_val, NULL);
2643-
if (UNEXPECTED(EG(exception))) {
2644-
EG(fake_scope) = old_scope;
2645-
if (created) {
2646-
zval_ptr_dtor(&obj_zval);
2642+
/* Try direct property slot write first — this handles
2643+
* readonly properties and avoids hook/coercion overhead.
2644+
* Falls back to zend_std_write_property for dynamic
2645+
* properties or properties not found in this scope. */
2646+
zend_property_info *pi = scope_ce
2647+
? zend_hash_find_ptr(&scope_ce->properties_info, prop_name)
2648+
: NULL;
2649+
if (pi && !(pi->flags & ZEND_ACC_STATIC) && pi->offset >= 0) {
2650+
zval *slot = OBJ_PROP(obj, pi->offset);
2651+
zval_ptr_dtor(slot);
2652+
ZVAL_COPY(slot, prop_val);
2653+
} else {
2654+
zend_std_write_property(obj, prop_name, prop_val, NULL);
2655+
if (UNEXPECTED(EG(exception))) {
2656+
EG(fake_scope) = old_scope;
2657+
if (created) {
2658+
zval_ptr_dtor(&obj_zval);
2659+
}
2660+
return;
26472661
}
2648-
return;
26492662
}
26502663
}
26512664
} ZEND_HASH_FOREACH_END();

0 commit comments

Comments
 (0)