Skip to content

Commit 2d5f104

Browse files
GH-16504: avoid seg fault when creating new lazy class instance fails
1 parent 55266d4 commit 2d5f104

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
GH-16504: Segmentation fault when failing to clone
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public $a = FOO;
8+
}
9+
10+
$reflection = new ReflectionClass(C::class);
11+
12+
echo "Proxy:\n";
13+
$proxy = $reflection->newLazyProxy(function () {});
14+
try {
15+
clone $proxy;
16+
} catch ( Error $e ) {
17+
echo $e;
18+
}
19+
20+
echo "\n\nGhost:\n";
21+
$ghost = $reflection->newLazyGhost(function () {});
22+
try {
23+
clone $ghost;
24+
} catch ( Error $e ) {
25+
echo $e;
26+
}
27+
28+
?>
29+
--EXPECTF--
30+
Proxy:
31+
Error: Undefined constant "FOO" in %s:%d
32+
Stack trace:
33+
#0 {main}
34+
35+
Next Error: Undefined constant "FOO" in %s:%d
36+
Stack trace:
37+
#0 {main}
38+
39+
Ghost:
40+
Error: Undefined constant "FOO" in %s:%d
41+
Stack trace:
42+
#0 {main}
43+
44+
Next Error: Undefined constant "FOO" in %s:%d
45+
Stack trace:
46+
#0 {main}

Zend/zend_lazy_objects.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,12 @@ zend_object *zend_lazy_object_clone(zend_object *old_obj)
712712
/* Clone handler must always return an object. It is discarded later due
713713
* to the exception. */
714714
zval zv;
715-
object_init_ex(&zv, old_obj->ce);
715+
if (object_init_ex(&zv, old_obj->ce) == FAILURE) {
716+
// Since the return is just going to be discarded, and we couldn't
717+
// create a new instance of the cloned class, just return the
718+
// current instance
719+
return old_obj;
720+
}
716721
GC_ADD_FLAGS(Z_OBJ(zv), IS_OBJ_DESTRUCTOR_CALLED);
717722
return Z_OBJ(zv);
718723
}

0 commit comments

Comments
 (0)