Skip to content

Commit 301b556

Browse files
committed
Fix phpGH-10571: Assertion `zval_get_type(&(*(zptr))) == 6 && "Concat should return string"' failed
1 parent 1fc2ddc commit 301b556

File tree

5 files changed

+187
-0
lines changed

5 files changed

+187
-0
lines changed

Zend/tests/gh10571_1.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
GH-10571: Assertion `zval_get_type(&(*(zptr))) == 6 && "Concat should return string"' failed - OP
3+
--FILE--
4+
<?php
5+
class A
6+
{
7+
public string $prop = "";
8+
}
9+
10+
class B
11+
{
12+
public function __toString()
13+
{
14+
global $a;
15+
$a = "";
16+
return "";
17+
}
18+
}
19+
20+
$a = new A();
21+
$a->prop .= new B();
22+
var_dump($a);
23+
?>
24+
--EXPECT--
25+
string(0) ""

Zend/tests/gh10571_2.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
GH-10571: Assertion `zval_get_type(&(*(zptr))) == 6 && "Concat should return string"' failed - DIM OP
3+
--FILE--
4+
<?php
5+
class A
6+
{
7+
public array $prop = ["a"];
8+
}
9+
10+
class B
11+
{
12+
public function __toString()
13+
{
14+
global $a;
15+
$a = "";
16+
return "";
17+
}
18+
}
19+
20+
$a = new A();
21+
$a->prop[0] .= new B();
22+
var_dump($a);
23+
?>
24+
--EXPECT--
25+
string(0) ""

Zend/tests/gh10571_3.phpt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
GH-10571: Assertion `zval_get_type(&(*(zptr))) == 6 && "Concat should return string"' failed - DIM OP resize
3+
--FILE--
4+
<?php
5+
class A
6+
{
7+
public array $prop = ["a"];
8+
}
9+
10+
class B
11+
{
12+
public function __toString()
13+
{
14+
global $a;
15+
// Force a resize, but it will work on a copy instead
16+
for ($i = 0; $i < 1000; $i++) {
17+
$a->prop[] = $i;
18+
}
19+
return "";
20+
}
21+
}
22+
23+
$a = new A();
24+
$a->prop[0] .= new B();
25+
var_dump(count($a->prop));
26+
var_dump($a->prop[0]);
27+
?>
28+
--EXPECT--
29+
int(1001)
30+
string(1) "a"

Zend/zend_vm_def.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,10 @@ ZEND_VM_C_LABEL(assign_op_object):
10591059
zval *orig_zptr = zptr;
10601060
zend_reference *ref;
10611061

1062+
if (OP1_TYPE == IS_CV) {
1063+
GC_ADDREF(zobj);
1064+
}
1065+
10621066
do {
10631067
if (UNEXPECTED(Z_ISREF_P(zptr))) {
10641068
ref = Z_REF_P(zptr);
@@ -1085,6 +1089,10 @@ ZEND_VM_C_LABEL(assign_op_object):
10851089
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
10861090
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
10871091
}
1092+
1093+
if (OP1_TYPE == IS_CV) {
1094+
GC_DTOR(zobj);
1095+
}
10881096
}
10891097
} else {
10901098
zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
@@ -1183,6 +1191,8 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
11831191

11841192
value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
11851193

1194+
GC_ADDREF(ht);
1195+
11861196
do {
11871197
if (OP2_TYPE != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
11881198
zend_reference *ref = Z_REF_P(var_ptr);
@@ -1198,6 +1208,7 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
11981208
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
11991209
ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
12001210
}
1211+
GC_DTOR_NO_REF(ht);
12011212
FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
12021213
} else {
12031214
if (EXPECTED(Z_ISREF_P(container))) {

0 commit comments

Comments
 (0)