summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_execute.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_execute.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_execute.h')
-rw-r--r--Zend/zend_vm_execute.h118
1 files changed, 90 insertions, 28 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d4a1c7b441..770f9667c9 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4140,11 +4140,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != 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 (IS_CONST != 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))) {
@@ -4152,7 +4148,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
}
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) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CONST != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -4168,6 +4175,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
}
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+fe_reset_r_empty:
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
@@ -4218,6 +4226,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashTable *properties;
if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
if (array_ptr == array_ref) {
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_
}
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);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -18192,11 +18208,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != 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 (IS_TMP_VAR != 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))) {
@@ -18204,7 +18216,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
}
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) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_TMP_VAR != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -18221,6 +18244,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
}
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+fe_reset_r_empty:
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
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
ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashTable *properties;
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
if (array_ptr == array_ref) {
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
}
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);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -21282,11 +21314,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != 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 (IS_VAR != 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))) {
@@ -21294,8 +21322,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
}
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) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_VAR != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -21312,6 +21350,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
}
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+fe_reset_r_empty:
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
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
ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashTable *properties;
if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
if (array_ptr == array_ref) {
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
}
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);
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -37792,11 +37838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != 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 (IS_CV != 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))) {
@@ -37804,7 +37846,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
}
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) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CV != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
@@ -37820,6 +37873,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
}
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+fe_reset_r_empty:
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
@@ -37870,6 +37924,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashTable *properties;
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
if (array_ptr == array_ref) {
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
}
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);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {