summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_def.h
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-10-09 16:56:08 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-10-09 16:56:08 +0200
commit15443f8af4783ce6ea5362ec5a38a62b69ff8447 (patch)
tree68154b052bac804892f581882544635fbc793f74 /Zend/zend_vm_def.h
parent58af1e156e3b3493493fb05a501bc52708badf26 (diff)
downloadphp-git-15443f8af4783ce6ea5362ec5a38a62b69ff8447.tar.gz
Fixed bug #80186
Early exit in FE_RESET if get_properties() returns empty array, as we cannot add HT iterators to zend_empty_array.
Diffstat (limited to 'Zend/zend_vm_def.h')
-rw-r--r--Zend/zend_vm_def.h28
1 files changed, 21 insertions, 7 deletions
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 40b20f0d9c..6305ef8ef4 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -6317,11 +6317,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_NEXT_OPCODE();
} else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
- result = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(result, array_ptr);
- if (OP1_TYPE != IS_TMP_VAR) {
- Z_ADDREF_P(array_ptr);
- }
+ HashTable *properties;
if (Z_OBJ_P(array_ptr)->properties
&& UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
@@ -6329,8 +6325,18 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
}
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
+ properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ ZEND_VM_C_GOTO(fe_reset_r_empty);
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (OP1_TYPE != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
FREE_OP1_IF_VAR();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -6347,6 +6353,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
}
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+ZEND_VM_C_LABEL(fe_reset_r_empty):
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
FREE_OP1();
@@ -6397,6 +6404,7 @@ ZEND_VM_COLD_CONST_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_NEXT_OPCODE();
} else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashTable *properties;
if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
if (array_ptr == array_ref) {
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)
}
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
+ properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
FREE_OP1_VAR_PTR();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {