Skip to content

Commit 304141e

Browse files
committed
Avoid non-object in FE_FREE
Even if the properties HT is empty, make sure we still leave an object in the FE_RESET result, so our type inference results stay correct.
1 parent 34179ba commit 304141e

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

Zend/zend_vm_def.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6327,15 +6327,18 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
63276327
}
63286328

63296329
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-
63346330
result = EX_VAR(opline->result.var);
63356331
ZVAL_COPY_VALUE(result, array_ptr);
63366332
if (OP1_TYPE != IS_TMP_VAR) {
63376333
Z_ADDREF_P(array_ptr);
63386334
}
6335+
6336+
if (zend_hash_num_elements(properties) == 0) {
6337+
Z_FE_ITER_P(result) = (uint32_t) -1;
6338+
FREE_OP1_IF_VAR();
6339+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
6340+
}
6341+
63396342
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
63406343
FREE_OP1_IF_VAR();
63416344
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -6353,7 +6356,6 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
63536356
}
63546357
} else {
63556358
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
6356-
ZEND_VM_C_LABEL(fe_reset_r_empty):
63576359
ZVAL_UNDEF(EX_VAR(opline->result.var));
63586360
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
63596361
FREE_OP1();
@@ -6427,6 +6429,7 @@ ZEND_VM_COLD_CONST_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
64276429
properties = Z_OBJPROP_P(array_ptr);
64286430
if (zend_hash_num_elements(properties) == 0) {
64296431
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
6432+
FREE_OP1_VAR_PTR();
64306433
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
64316434
}
64326435

Zend/zend_vm_execute.h

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4150,15 +4150,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
41504150
}
41514151

41524152
properties = Z_OBJPROP_P(array_ptr);
4153-
if (zend_hash_num_elements(properties) == 0) {
4154-
goto fe_reset_r_empty;
4155-
}
4156-
41574153
result = EX_VAR(opline->result.var);
41584154
ZVAL_COPY_VALUE(result, array_ptr);
41594155
if (IS_CONST != IS_TMP_VAR) {
41604156
Z_ADDREF_P(array_ptr);
41614157
}
4158+
4159+
if (zend_hash_num_elements(properties) == 0) {
4160+
Z_FE_ITER_P(result) = (uint32_t) -1;
4161+
4162+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
4163+
}
4164+
41624165
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
41634166

41644167
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -4175,7 +4178,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
41754178
}
41764179
} else {
41774180
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
4178-
fe_reset_r_empty:
41794181
ZVAL_UNDEF(EX_VAR(opline->result.var));
41804182
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
41814183

@@ -4249,6 +4251,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
42494251
properties = Z_OBJPROP_P(array_ptr);
42504252
if (zend_hash_num_elements(properties) == 0) {
42514253
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
4254+
42524255
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
42534256
}
42544257

@@ -18218,15 +18221,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
1821818221
}
1821918222

1822018223
properties = Z_OBJPROP_P(array_ptr);
18221-
if (zend_hash_num_elements(properties) == 0) {
18222-
goto fe_reset_r_empty;
18223-
}
18224-
1822518224
result = EX_VAR(opline->result.var);
1822618225
ZVAL_COPY_VALUE(result, array_ptr);
1822718226
if (IS_TMP_VAR != IS_TMP_VAR) {
1822818227
Z_ADDREF_P(array_ptr);
1822918228
}
18229+
18230+
if (zend_hash_num_elements(properties) == 0) {
18231+
Z_FE_ITER_P(result) = (uint32_t) -1;
18232+
18233+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
18234+
}
18235+
1823018236
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
1823118237

1823218238
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -18244,7 +18250,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
1824418250
}
1824518251
} else {
1824618252
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
18247-
fe_reset_r_empty:
1824818253
ZVAL_UNDEF(EX_VAR(opline->result.var));
1824918254
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
1825018255
zval_ptr_dtor_nogc(free_op1);
@@ -18318,6 +18323,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z
1831818323
properties = Z_OBJPROP_P(array_ptr);
1831918324
if (zend_hash_num_elements(properties) == 0) {
1832018325
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
18326+
1832118327
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
1832218328
}
1832318329

@@ -21324,15 +21330,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
2132421330
}
2132521331

2132621332
properties = Z_OBJPROP_P(array_ptr);
21327-
if (zend_hash_num_elements(properties) == 0) {
21328-
goto fe_reset_r_empty;
21329-
}
21330-
2133121333
result = EX_VAR(opline->result.var);
2133221334
ZVAL_COPY_VALUE(result, array_ptr);
2133321335
if (IS_VAR != IS_TMP_VAR) {
2133421336
Z_ADDREF_P(array_ptr);
2133521337
}
21338+
21339+
if (zend_hash_num_elements(properties) == 0) {
21340+
Z_FE_ITER_P(result) = (uint32_t) -1;
21341+
zval_ptr_dtor_nogc(free_op1);
21342+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
21343+
}
21344+
2133621345
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
2133721346
zval_ptr_dtor_nogc(free_op1);
2133821347
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -21350,7 +21359,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
2135021359
}
2135121360
} else {
2135221361
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
21353-
fe_reset_r_empty:
2135421362
ZVAL_UNDEF(EX_VAR(opline->result.var));
2135521363
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
2135621364
zval_ptr_dtor_nogc(free_op1);
@@ -21424,6 +21432,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
2142421432
properties = Z_OBJPROP_P(array_ptr);
2142521433
if (zend_hash_num_elements(properties) == 0) {
2142621434
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
21435+
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
2142721436
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
2142821437
}
2142921438

@@ -37848,15 +37857,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
3784837857
}
3784937858

3785037859
properties = Z_OBJPROP_P(array_ptr);
37851-
if (zend_hash_num_elements(properties) == 0) {
37852-
goto fe_reset_r_empty;
37853-
}
37854-
3785537860
result = EX_VAR(opline->result.var);
3785637861
ZVAL_COPY_VALUE(result, array_ptr);
3785737862
if (IS_CV != IS_TMP_VAR) {
3785837863
Z_ADDREF_P(array_ptr);
3785937864
}
37865+
37866+
if (zend_hash_num_elements(properties) == 0) {
37867+
Z_FE_ITER_P(result) = (uint32_t) -1;
37868+
37869+
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
37870+
}
37871+
3786037872
Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
3786137873

3786237874
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -37873,7 +37885,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
3787337885
}
3787437886
} else {
3787537887
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
37876-
fe_reset_r_empty:
3787737888
ZVAL_UNDEF(EX_VAR(opline->result.var));
3787837889
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
3787937890

@@ -37947,6 +37958,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
3794737958
properties = Z_OBJPROP_P(array_ptr);
3794837959
if (zend_hash_num_elements(properties) == 0) {
3794937960
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
37961+
3795037962
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
3795137963
}
3795237964

0 commit comments

Comments
 (0)