Skip to content

Commit 15443f8

Browse files
committed
Fixed bug #80186
Early exit in FE_RESET if get_properties() returns empty array, as we cannot add HT iterators to zend_empty_array.
1 parent 58af1e1 commit 15443f8

File tree

4 files changed

+127
-35
lines changed

4 files changed

+127
-35
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ PHP NEWS
88
. Fixed bug #79423 (copy command is limited to size of file it can copy).
99
(cmb)
1010
. Fixed bug #80126 (Covariant return types failing compilation). (Nikita)
11+
. Fixed bug #80186 (Segfault when iterating over FFI object). (Nikita)
1112

1213
- Calendar:
1314
. Fixed bug #80185 (jdtounix() fails after 2037). (cmb)

Zend/zend_vm_def.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6317,20 +6317,26 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
63176317
ZEND_VM_NEXT_OPCODE();
63186318
} else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
63196319
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
6320-
result = EX_VAR(opline->result.var);
6321-
ZVAL_COPY_VALUE(result, array_ptr);
6322-
if (OP1_TYPE != IS_TMP_VAR) {
6323-
Z_ADDREF_P(array_ptr);
6324-
}
6320+
HashTable *properties;
63256321
if (Z_OBJ_P(array_ptr)->properties
63266322
&& UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
63276323
if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
63286324
GC_DELREF(Z_OBJ_P(array_ptr)->properties);
63296325
}
63306326
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
63316327
}
6332-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
63336328

6329+
properties = Z_OBJPROP_P(array_ptr);
6330+
if (zend_hash_num_elements(properties) == 0) {
6331+
ZEND_VM_C_GOTO(fe_reset_r_empty);
6332+
}
6333+
6334+
result = EX_VAR(opline->result.var);
6335+
ZVAL_COPY_VALUE(result, array_ptr);
6336+
if (OP1_TYPE != IS_TMP_VAR) {
6337+
Z_ADDREF_P(array_ptr);
6338+
}
6339+
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
63346340
FREE_OP1_IF_VAR();
63356341
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
63366342
} else {
@@ -6347,6 +6353,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
63476353
}
63486354
} else {
63496355
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
6356+
ZEND_VM_C_LABEL(fe_reset_r_empty):
63506357
ZVAL_UNDEF(EX_VAR(opline->result.var));
63516358
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
63526359
FREE_OP1();
@@ -6397,6 +6404,7 @@ ZEND_VM_COLD_CONST_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
63976404
ZEND_VM_NEXT_OPCODE();
63986405
} else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
63996406
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
6407+
HashTable *properties;
64006408
if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
64016409
if (array_ptr == array_ref) {
64026410
ZVAL_NEW_REF(array_ref, array_ref);
@@ -6415,8 +6423,14 @@ ZEND_VM_COLD_CONST_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
64156423
}
64166424
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
64176425
}
6418-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
64196426

6427+
properties = Z_OBJPROP_P(array_ptr);
6428+
if (zend_hash_num_elements(properties) == 0) {
6429+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
6430+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6431+
}
6432+
6433+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
64206434
FREE_OP1_VAR_PTR();
64216435
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
64226436
} else {

Zend/zend_vm_execute.h

Lines changed: 90 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4140,19 +4140,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
41404140
ZEND_VM_NEXT_OPCODE();
41414141
} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
41424142
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
4143-
result = EX_VAR(opline->result.var);
4144-
ZVAL_COPY_VALUE(result, array_ptr);
4145-
if (IS_CONST != IS_TMP_VAR) {
4146-
Z_ADDREF_P(array_ptr);
4147-
}
4143+
HashTable *properties;
41484144
if (Z_OBJ_P(array_ptr)->properties
41494145
&& UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
41504146
if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
41514147
GC_DELREF(Z_OBJ_P(array_ptr)->properties);
41524148
}
41534149
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
41544150
}
4155-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
4151+
4152+
properties = Z_OBJPROP_P(array_ptr);
4153+
if (zend_hash_num_elements(properties) == 0) {
4154+
goto fe_reset_r_empty;
4155+
}
4156+
4157+
result = EX_VAR(opline->result.var);
4158+
ZVAL_COPY_VALUE(result, array_ptr);
4159+
if (IS_CONST != IS_TMP_VAR) {
4160+
Z_ADDREF_P(array_ptr);
4161+
}
4162+
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
41564163

41574164
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
41584165
} else {
@@ -4168,6 +4175,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
41684175
}
41694176
} else {
41704177
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
4178+
fe_reset_r_empty:
41714179
ZVAL_UNDEF(EX_VAR(opline->result.var));
41724180
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
41734181

@@ -4218,6 +4226,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
42184226
ZEND_VM_NEXT_OPCODE();
42194227
} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
42204228
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
4229+
HashTable *properties;
42214230
if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
42224231
if (array_ptr == array_ref) {
42234232
ZVAL_NEW_REF(array_ref, array_ref);
@@ -4236,7 +4245,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
42364245
}
42374246
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
42384247
}
4239-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
4248+
4249+
properties = Z_OBJPROP_P(array_ptr);
4250+
if (zend_hash_num_elements(properties) == 0) {
4251+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
4252+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
4253+
}
4254+
4255+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
42404256

42414257
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
42424258
} else {
@@ -18192,19 +18208,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
1819218208
ZEND_VM_NEXT_OPCODE();
1819318209
} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
1819418210
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
18195-
result = EX_VAR(opline->result.var);
18196-
ZVAL_COPY_VALUE(result, array_ptr);
18197-
if (IS_TMP_VAR != IS_TMP_VAR) {
18198-
Z_ADDREF_P(array_ptr);
18199-
}
18211+
HashTable *properties;
1820018212
if (Z_OBJ_P(array_ptr)->properties
1820118213
&& UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
1820218214
if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
1820318215
GC_DELREF(Z_OBJ_P(array_ptr)->properties);
1820418216
}
1820518217
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
1820618218
}
18207-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
18219+
18220+
properties = Z_OBJPROP_P(array_ptr);
18221+
if (zend_hash_num_elements(properties) == 0) {
18222+
goto fe_reset_r_empty;
18223+
}
18224+
18225+
result = EX_VAR(opline->result.var);
18226+
ZVAL_COPY_VALUE(result, array_ptr);
18227+
if (IS_TMP_VAR != IS_TMP_VAR) {
18228+
Z_ADDREF_P(array_ptr);
18229+
}
18230+
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
1820818231

1820918232
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1821018233
} else {
@@ -18221,6 +18244,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
1822118244
}
1822218245
} else {
1822318246
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
18247+
fe_reset_r_empty:
1822418248
ZVAL_UNDEF(EX_VAR(opline->result.var));
1822518249
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
1822618250
zval_ptr_dtor_nogc(free_op1);
@@ -18271,6 +18295,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z
1827118295
ZEND_VM_NEXT_OPCODE();
1827218296
} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
1827318297
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
18298+
HashTable *properties;
1827418299
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
1827518300
if (array_ptr == array_ref) {
1827618301
ZVAL_NEW_REF(array_ref, array_ref);
@@ -18289,7 +18314,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z
1828918314
}
1829018315
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
1829118316
}
18292-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
18317+
18318+
properties = Z_OBJPROP_P(array_ptr);
18319+
if (zend_hash_num_elements(properties) == 0) {
18320+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
18321+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
18322+
}
18323+
18324+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
1829318325

1829418326
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1829518327
} else {
@@ -21282,20 +21314,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
2128221314
ZEND_VM_NEXT_OPCODE();
2128321315
} else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
2128421316
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
21285-
result = EX_VAR(opline->result.var);
21286-
ZVAL_COPY_VALUE(result, array_ptr);
21287-
if (IS_VAR != IS_TMP_VAR) {
21288-
Z_ADDREF_P(array_ptr);
21289-
}
21317+
HashTable *properties;
2129021318
if (Z_OBJ_P(array_ptr)->properties
2129121319
&& UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
2129221320
if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
2129321321
GC_DELREF(Z_OBJ_P(array_ptr)->properties);
2129421322
}
2129521323
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
2129621324
}
21297-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
2129821325

21326+
properties = Z_OBJPROP_P(array_ptr);
21327+
if (zend_hash_num_elements(properties) == 0) {
21328+
goto fe_reset_r_empty;
21329+
}
21330+
21331+
result = EX_VAR(opline->result.var);
21332+
ZVAL_COPY_VALUE(result, array_ptr);
21333+
if (IS_VAR != IS_TMP_VAR) {
21334+
Z_ADDREF_P(array_ptr);
21335+
}
21336+
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
2129921337
zval_ptr_dtor_nogc(free_op1);
2130021338
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2130121339
} else {
@@ -21312,6 +21350,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
2131221350
}
2131321351
} else {
2131421352
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
21353+
fe_reset_r_empty:
2131521354
ZVAL_UNDEF(EX_VAR(opline->result.var));
2131621355
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
2131721356
zval_ptr_dtor_nogc(free_op1);
@@ -21362,6 +21401,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
2136221401
ZEND_VM_NEXT_OPCODE();
2136321402
} else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
2136421403
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
21404+
HashTable *properties;
2136521405
if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
2136621406
if (array_ptr == array_ref) {
2136721407
ZVAL_NEW_REF(array_ref, array_ref);
@@ -21380,8 +21420,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
2138021420
}
2138121421
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
2138221422
}
21383-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
2138421423

21424+
properties = Z_OBJPROP_P(array_ptr);
21425+
if (zend_hash_num_elements(properties) == 0) {
21426+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
21427+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
21428+
}
21429+
21430+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
2138521431
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
2138621432
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2138721433
} else {
@@ -37792,19 +37838,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
3779237838
ZEND_VM_NEXT_OPCODE();
3779337839
} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
3779437840
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
37795-
result = EX_VAR(opline->result.var);
37796-
ZVAL_COPY_VALUE(result, array_ptr);
37797-
if (IS_CV != IS_TMP_VAR) {
37798-
Z_ADDREF_P(array_ptr);
37799-
}
37841+
HashTable *properties;
3780037842
if (Z_OBJ_P(array_ptr)->properties
3780137843
&& UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
3780237844
if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
3780337845
GC_DELREF(Z_OBJ_P(array_ptr)->properties);
3780437846
}
3780537847
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
3780637848
}
37807-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
37849+
37850+
properties = Z_OBJPROP_P(array_ptr);
37851+
if (zend_hash_num_elements(properties) == 0) {
37852+
goto fe_reset_r_empty;
37853+
}
37854+
37855+
result = EX_VAR(opline->result.var);
37856+
ZVAL_COPY_VALUE(result, array_ptr);
37857+
if (IS_CV != IS_TMP_VAR) {
37858+
Z_ADDREF_P(array_ptr);
37859+
}
37860+
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
3780837861

3780937862
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3781037863
} else {
@@ -37820,6 +37873,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
3782037873
}
3782137874
} else {
3782237875
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
37876+
fe_reset_r_empty:
3782337877
ZVAL_UNDEF(EX_VAR(opline->result.var));
3782437878
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
3782537879

@@ -37870,6 +37924,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
3787037924
ZEND_VM_NEXT_OPCODE();
3787137925
} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
3787237926
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
37927+
HashTable *properties;
3787337928
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
3787437929
if (array_ptr == array_ref) {
3787537930
ZVAL_NEW_REF(array_ref, array_ref);
@@ -37888,7 +37943,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
3788837943
}
3788937944
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
3789037945
}
37891-
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
37946+
37947+
properties = Z_OBJPROP_P(array_ptr);
37948+
if (zend_hash_num_elements(properties) == 0) {
37949+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
37950+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
37951+
}
37952+
37953+
Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
3789237954

3789337955
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
3789437956
} else {

ext/ffi/tests/bug80186.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Bug #80186 (Segfault when iterating over FFI object)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('ffi')) die('skip ffi extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
$ffi = FFI::cdef('typedef int dummy;');
10+
foreach ($ffi as $_) { }
11+
foreach ($ffi as &$_) { }
12+
?>
13+
===DONE===
14+
--EXPECT--
15+
===DONE===

0 commit comments

Comments
 (0)