summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2018-08-17 12:19:31 +0800
committerXinchen Hui <laruence@gmail.com>2018-08-17 12:19:31 +0800
commitfd463a9a6078074f8f648982b42bdd14423fb614 (patch)
treee31de8063ce519cda772cc314263131705215104
parentae926d89619a034f89bdda5c9f70d8ce59219050 (diff)
downloadphp-git-fd463a9a6078074f8f648982b42bdd14423fb614.tar.gz
Fixed bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in _get_zval_ptr_tmp failed).
-rw-r--r--NEWS4
-rw-r--r--Zend/tests/bug76752.phpt11
-rw-r--r--Zend/zend_vm_def.h8
-rw-r--r--Zend/zend_vm_execute.h152
-rw-r--r--Zend/zend_vm_handlers.h4
-rw-r--r--Zend/zend_vm_opcodes.c2
6 files changed, 76 insertions, 105 deletions
diff --git a/NEWS b/NEWS
index 889697dc27..a89679f73c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.0beta3
+- Core:
+ . Fixed bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in
+ _get_zval_ptr_tmp failed). (Laruence)
+
- Opcache:
. Fixed bug #76747 (Opcache treats path containing "test.pharma.tld" as a phar
file). (Laruence)
diff --git a/Zend/tests/bug76752.phpt b/Zend/tests/bug76752.phpt
new file mode 100644
index 0000000000..dcdfeebeb9
--- /dev/null
+++ b/Zend/tests/bug76752.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in _get_zval_ptr_tmp failed)
+--FILE--
+<?php
+$obj = new stdClass;
+$val = 'foo';
+$obj->prop = &$val;
+var_dump($obj->prop ?? []);
+?>
+--EXPECT--
+string(3) "foo"
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 527aa38074..14dc9e6763 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -6527,7 +6527,7 @@ ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
+ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMPVAR|CV, JMP_ADDR)
{
USE_OPLINE
zend_free_op free_op1;
@@ -6537,8 +6537,8 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR(BP_VAR_IS);
- if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
- if (OP1_TYPE == IS_VAR) {
+ if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ if (OP1_TYPE & IS_VAR) {
ref = value;
}
value = Z_REFVAL_P(value);
@@ -6551,7 +6551,7 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
} else if (OP1_TYPE == IS_CV) {
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
- } else if (OP1_TYPE == IS_VAR && ref) {
+ } else if ((OP1_TYPE & IS_VAR) && ref) {
zend_reference *r = Z_REF_P(ref);
if (UNEXPECTED(GC_DELREF(r) == 0)) {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 85c6c3a49b..523e0985f9 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3545,8 +3545,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON
SAVE_OPLINE();
value = RT_CONSTANT(opline, opline->op1);
- if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) {
- if (IS_CONST == IS_VAR) {
+ if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ if (IS_CONST & IS_VAR) {
ref = value;
}
value = Z_REFVAL_P(value);
@@ -3559,7 +3559,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
} else if (IS_CONST == IS_CV) {
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
- } else if (IS_CONST == IS_VAR && ref) {
+ } else if ((IS_CONST & IS_VAR) && ref) {
zend_reference *r = Z_REF_P(ref);
if (UNEXPECTED(GC_DELREF(r) == 0)) {
@@ -12781,6 +12781,46 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_TMPVAR_
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *value;
+ zval *ref = NULL;
+
+ SAVE_OPLINE();
+ value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+
+ if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ if ((IS_TMP_VAR|IS_VAR) & IS_VAR) {
+ ref = value;
+ }
+ value = Z_REFVAL_P(value);
+ }
+
+ if (Z_TYPE_P(value) > IS_NULL) {
+ zval *result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, value);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+ } else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && ref) {
+ zend_reference *r = Z_REF_P(ref);
+
+ if (UNEXPECTED(GC_DELREF(r) == 0)) {
+ efree_size(r, sizeof(zend_reference));
+ } else if (Z_OPT_REFCOUNTED_P(result)) {
+ Z_ADDREF_P(result);
+ }
+ }
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+ }
+
+ zval_ptr_dtor_nogc(free_op1);
+ ZEND_VM_NEXT_OPCODE();
+}
+
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -18393,46 +18433,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *value;
- zval *ref = NULL;
-
- SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
-
- if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) {
- if (IS_TMP_VAR == IS_VAR) {
- ref = value;
- }
- value = Z_REFVAL_P(value);
- }
-
- if (Z_TYPE_P(value) > IS_NULL) {
- zval *result = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(result, value);
- if (IS_TMP_VAR == IS_CONST) {
- if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
- } else if (IS_TMP_VAR == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
- } else if (IS_TMP_VAR == IS_VAR && ref) {
- zend_reference *r = Z_REF_P(ref);
-
- if (UNEXPECTED(GC_DELREF(r) == 0)) {
- efree_size(r, sizeof(zend_reference));
- } else if (Z_OPT_REFCOUNTED_P(result)) {
- Z_ADDREF_P(result);
- }
- }
- ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
- }
-
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_NEXT_OPCODE();
-}
-
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -21755,46 +21755,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *value;
- zval *ref = NULL;
-
- SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
-
- if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) {
- if (IS_VAR == IS_VAR) {
- ref = value;
- }
- value = Z_REFVAL_P(value);
- }
-
- if (Z_TYPE_P(value) > IS_NULL) {
- zval *result = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(result, value);
- if (IS_VAR == IS_CONST) {
- if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
- } else if (IS_VAR == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
- } else if (IS_VAR == IS_VAR && ref) {
- zend_reference *r = Z_REF_P(ref);
-
- if (UNEXPECTED(GC_DELREF(r) == 0)) {
- efree_size(r, sizeof(zend_reference));
- } else if (Z_OPT_REFCOUNTED_P(result)) {
- Z_ADDREF_P(result);
- }
- }
- ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
- }
-
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_NEXT_OPCODE();
-}
-
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -37965,8 +37925,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_
SAVE_OPLINE();
value = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
- if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(value)) {
- if (IS_CV == IS_VAR) {
+ if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ if (IS_CV & IS_VAR) {
ref = value;
}
value = Z_REFVAL_P(value);
@@ -37979,7 +37939,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
} else if (IS_CV == IS_CV) {
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
- } else if (IS_CV == IS_VAR && ref) {
+ } else if ((IS_CV & IS_VAR) && ref) {
zend_reference *r = Z_REF_P(ref);
if (UNEXPECTED(GC_DELREF(r) == 0)) {
@@ -54125,8 +54085,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
(void*)&&ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ_LABEL,
(void*)&&ZEND_BIND_GLOBAL_SPEC_CV_CONST_LABEL,
(void*)&&ZEND_COALESCE_SPEC_CONST_LABEL,
- (void*)&&ZEND_COALESCE_SPEC_TMP_LABEL,
- (void*)&&ZEND_COALESCE_SPEC_VAR_LABEL,
+ (void*)&&ZEND_COALESCE_SPEC_TMPVAR_LABEL,
+ (void*)&&ZEND_COALESCE_SPEC_TMPVAR_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_COALESCE_SPEC_CV_LABEL,
(void*)&&ZEND_SPACESHIP_SPEC_CONST_CONST_LABEL,
@@ -56879,6 +56839,10 @@ zend_leave_helper_SPEC_LABEL:
VM_TRACE(ZEND_EXIT_SPEC_TMPVAR)
ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
+ HYBRID_CASE(ZEND_COALESCE_SPEC_TMPVAR):
+ VM_TRACE(ZEND_COALESCE_SPEC_TMPVAR)
+ ZEND_COALESCE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ HYBRID_BREAK();
HYBRID_CASE(ZEND_STRLEN_SPEC_TMPVAR):
VM_TRACE(ZEND_STRLEN_SPEC_TMPVAR)
ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -57441,10 +57405,6 @@ zend_leave_helper_SPEC_LABEL:
VM_TRACE(ZEND_JMP_SET_SPEC_TMP)
ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
- HYBRID_CASE(ZEND_COALESCE_SPEC_TMP):
- VM_TRACE(ZEND_COALESCE_SPEC_TMP)
- ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- HYBRID_BREAK();
HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_TMP):
VM_TRACE(ZEND_QM_ASSIGN_SPEC_TMP)
ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -57759,10 +57719,6 @@ zend_leave_helper_SPEC_LABEL:
VM_TRACE(ZEND_JMP_SET_SPEC_VAR)
ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
- HYBRID_CASE(ZEND_COALESCE_SPEC_VAR):
- VM_TRACE(ZEND_COALESCE_SPEC_VAR)
- ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- HYBRID_BREAK();
HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_VAR):
VM_TRACE(ZEND_QM_ASSIGN_SPEC_VAR)
ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -63628,8 +63584,8 @@ void zend_vm_init(void)
ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ_HANDLER,
ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER,
ZEND_COALESCE_SPEC_CONST_HANDLER,
- ZEND_COALESCE_SPEC_TMP_HANDLER,
- ZEND_COALESCE_SPEC_VAR_HANDLER,
+ ZEND_COALESCE_SPEC_TMPVAR_HANDLER,
+ ZEND_COALESCE_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_COALESCE_SPEC_CV_HANDLER,
ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER,
diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h
index 28322c5e02..9e9a360601 100644
--- a/Zend/zend_vm_handlers.h
+++ b/Zend/zend_vm_handlers.h
@@ -1404,8 +1404,8 @@
_(2738, ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ) \
_(2739, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \
_(2740, ZEND_COALESCE_SPEC_CONST) \
- _(2741, ZEND_COALESCE_SPEC_TMP) \
- _(2742, ZEND_COALESCE_SPEC_VAR) \
+ _(2741, ZEND_COALESCE_SPEC_TMPVAR) \
+ _(2742, ZEND_COALESCE_SPEC_TMPVAR) \
_(2744, ZEND_COALESCE_SPEC_CV) \
_(2745, ZEND_SPACESHIP_SPEC_CONST_CONST) \
_(2746, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 73a2c164ea..c272f7314a 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -394,7 +394,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
0x00000707,
0x04046751,
0x00040301,
- 0x00002003,
+ 0x00002007,
0x00000707,
0x03000000,
0x03000303,