Skip to content

Commit fde4546

Browse files
committed
zend_objects: Disallow clone_with by reference
1 parent 6d9c0c6 commit fde4546

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

Zend/tests/clone/clone_with_013.phpt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
Clone with references
3+
--FILE--
4+
<?php
5+
6+
$x = new stdClass();
7+
8+
$ref = 'reference';
9+
$with = ['x' => &$ref];
10+
11+
try {
12+
var_dump(clone($x, $with));
13+
} catch (Throwable $e) {
14+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
15+
}
16+
17+
unset($ref);
18+
19+
try {
20+
var_dump(clone($x, $with));
21+
} catch (Throwable $e) {
22+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
23+
}
24+
25+
?>
26+
--EXPECTF--
27+
Error: Cannot assign by reference when cloning with updated properties
28+
object(stdClass)#%d (1) {
29+
["x"]=>
30+
string(9) "reference"
31+
}

Zend/zend_objects.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,15 @@ ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *old_object, const
294294
EG(fake_scope) = scope;
295295

296296
ZEND_HASH_FOREACH_KEY_VAL(properties, zend_ulong num_key, zend_string *key, zval *val) {
297+
if (UNEXPECTED(Z_ISREF_P(val))) {
298+
if (Z_REFCOUNT_P(val) == 1) {
299+
val = Z_REFVAL_P(val);
300+
} else {
301+
zend_throw_error(NULL, "Cannot assign by reference when cloning with updated properties");
302+
break;
303+
}
304+
}
305+
297306
if (UNEXPECTED(key == NULL)) {
298307
key = zend_long_to_str(num_key);
299308
new_object->handlers->write_property(new_object, key, val, NULL);

0 commit comments

Comments
 (0)