]> granicus.if.org Git - php/commitdiff
Fixed bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in _get_zval_pt...
authorXinchen Hui <laruence@gmail.com>
Fri, 17 Aug 2018 04:19:31 +0000 (12:19 +0800)
committerXinchen Hui <laruence@gmail.com>
Fri, 17 Aug 2018 04:19:31 +0000 (12:19 +0800)
NEWS
Zend/tests/bug76752.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_handlers.h
Zend/zend_vm_opcodes.c

diff --git a/NEWS b/NEWS
index 889697dc27db7236925103252b0fb13eeddb0d64..a89679f73c03fd013bf4c49cd49ddd41d5a68fa6 100644 (file)
--- 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 (file)
index 0000000..dcdfeeb
--- /dev/null
@@ -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"
index 527aa3807415d4ec96ea0763de819324d76ec465..14dc9e676361286e179b20e3f78eb72ec7b27732 100644 (file)
@@ -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)) {
index 85c6c3a49b8d94026ac7d56f01160d4ce6116cff..523e0985f9eb53312cadf0aaa3d30c9676fa701a 100644 (file)
@@ -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,
index 28322c5e02fe92fb54784cc36db70d9aa03e61a5..9e9a360601699a302f38377c07b8b18c817976da 100644 (file)
        _(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) \
index 73a2c164eab2c577cf28243fc182017c84a0c085..c272f7314a603a68091beecf698879ef3a0b97ef 100644 (file)
@@ -394,7 +394,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
        0x00000707,
        0x04046751,
        0x00040301,
-       0x00002003,
+       0x00002007,
        0x00000707,
        0x03000000,
        0x03000303,