]> granicus.if.org Git - php/commitdiff
Copy varname before unset
authorNikita Popov <nikic@php.net>
Sun, 13 Apr 2014 13:00:32 +0000 (15:00 +0200)
committerNikita Popov <nikic@php.net>
Sun, 13 Apr 2014 21:07:10 +0000 (23:07 +0200)
Otherwise we get issues when the varname variable coincides with
the variable that is deleted.

Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index dbb89e6e63a030619376bcba83d27c4655f4c14d..3f714703ba716aa1b0cacc6da8d9c1bcad554077 100644 (file)
@@ -4005,6 +4005,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
        zval tmp, *varname;
        HashTable *target_symbol_table;
        zend_free_op free_op1;
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (OP1_TYPE == IS_CV &&
@@ -4023,8 +4024,10 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (OP2_TYPE != IS_UNUSED) {
@@ -4036,10 +4039,10 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (OP1_TYPE != IS_CONST && varname == &tmp) {
+                                       if (OP1_TYPE != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
                                        FREE_OP1();
                                        HANDLE_EXCEPTION();
@@ -4058,10 +4061,10 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (OP1_TYPE != IS_CONST && varname == &tmp) {
+       if (OP1_TYPE != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
        FREE_OP1();
        CHECK_EXCEPTION();
index 643ebd644fda086edc277c166dcf12c5b3c708ed..427ae46b62854d5ab08e59e5d3bfc687ffab6a26 100644 (file)
@@ -4013,6 +4013,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
        zval tmp, *varname;
        HashTable *target_symbol_table;
 
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_CONST == IS_CV &&
@@ -4031,8 +4032,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_CONST != IS_UNUSED) {
@@ -4044,10 +4047,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_CONST != IS_CONST && varname == &tmp) {
+                                       if (IS_CONST != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
 
                                        HANDLE_EXCEPTION();
@@ -4066,10 +4069,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_CONST != IS_CONST && varname == &tmp) {
+       if (IS_CONST != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
 
        CHECK_EXCEPTION();
@@ -5650,6 +5653,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
        zval tmp, *varname;
        HashTable *target_symbol_table;
 
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_CONST == IS_CV &&
@@ -5668,8 +5672,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_VAR != IS_UNUSED) {
@@ -5681,10 +5687,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_CONST != IS_CONST && varname == &tmp) {
+                                       if (IS_CONST != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
 
                                        HANDLE_EXCEPTION();
@@ -5703,10 +5709,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_CONST != IS_CONST && varname == &tmp) {
+       if (IS_CONST != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
 
        CHECK_EXCEPTION();
@@ -6290,6 +6296,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
        zval tmp, *varname;
        HashTable *target_symbol_table;
 
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_CONST == IS_CV &&
@@ -6308,8 +6315,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_UNUSED != IS_UNUSED) {
@@ -6321,10 +6330,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_CONST != IS_CONST && varname == &tmp) {
+                                       if (IS_CONST != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
 
                                        HANDLE_EXCEPTION();
@@ -6343,10 +6352,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_CONST != IS_CONST && varname == &tmp) {
+       if (IS_CONST != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
 
        CHECK_EXCEPTION();
@@ -8944,6 +8953,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
        zval tmp, *varname;
        HashTable *target_symbol_table;
        zend_free_op free_op1;
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_TMP_VAR == IS_CV &&
@@ -8962,8 +8972,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_CONST != IS_UNUSED) {
@@ -8975,10 +8987,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
+                                       if (IS_TMP_VAR != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
                                        zval_dtor(free_op1.var);
                                        HANDLE_EXCEPTION();
@@ -8997,10 +9009,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
+       if (IS_TMP_VAR != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
        zval_dtor(free_op1.var);
        CHECK_EXCEPTION();
@@ -10545,6 +10557,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
        zval tmp, *varname;
        HashTable *target_symbol_table;
        zend_free_op free_op1;
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_TMP_VAR == IS_CV &&
@@ -10563,8 +10576,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_VAR != IS_UNUSED) {
@@ -10576,10 +10591,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
+                                       if (IS_TMP_VAR != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
                                        zval_dtor(free_op1.var);
                                        HANDLE_EXCEPTION();
@@ -10598,10 +10613,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
+       if (IS_TMP_VAR != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
        zval_dtor(free_op1.var);
        CHECK_EXCEPTION();
@@ -11071,6 +11086,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
        zval tmp, *varname;
        HashTable *target_symbol_table;
        zend_free_op free_op1;
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_TMP_VAR == IS_CV &&
@@ -11089,8 +11105,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_UNUSED != IS_UNUSED) {
@@ -11102,10 +11120,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
+                                       if (IS_TMP_VAR != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
                                        zval_dtor(free_op1.var);
                                        HANDLE_EXCEPTION();
@@ -11124,10 +11142,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
+       if (IS_TMP_VAR != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
        zval_dtor(free_op1.var);
        CHECK_EXCEPTION();
@@ -15266,6 +15284,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
        zval tmp, *varname;
        HashTable *target_symbol_table;
        zend_free_op free_op1;
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_VAR == IS_CV &&
@@ -15284,8 +15303,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_CONST != IS_UNUSED) {
@@ -15297,10 +15318,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_VAR != IS_CONST && varname == &tmp) {
+                                       if (IS_VAR != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
                                        zval_ptr_dtor_nogc(free_op1.var);
                                        HANDLE_EXCEPTION();
@@ -15319,10 +15340,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_VAR != IS_CONST && varname == &tmp) {
+       if (IS_VAR != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -19691,6 +19712,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
        zval tmp, *varname;
        HashTable *target_symbol_table;
        zend_free_op free_op1;
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_VAR == IS_CV &&
@@ -19709,8 +19731,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_VAR != IS_UNUSED) {
@@ -19722,10 +19746,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_VAR != IS_CONST && varname == &tmp) {
+                                       if (IS_VAR != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
                                        zval_ptr_dtor_nogc(free_op1.var);
                                        HANDLE_EXCEPTION();
@@ -19744,10 +19768,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_VAR != IS_CONST && varname == &tmp) {
+       if (IS_VAR != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -21114,6 +21138,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
        zval tmp, *varname;
        HashTable *target_symbol_table;
        zend_free_op free_op1;
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_VAR == IS_CV &&
@@ -21132,8 +21157,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_UNUSED != IS_UNUSED) {
@@ -21145,10 +21172,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_VAR != IS_CONST && varname == &tmp) {
+                                       if (IS_VAR != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
                                        zval_ptr_dtor_nogc(free_op1.var);
                                        HANDLE_EXCEPTION();
@@ -21167,10 +21194,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_VAR != IS_CONST && varname == &tmp) {
+       if (IS_VAR != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -32432,6 +32459,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
        zval tmp, *varname;
        HashTable *target_symbol_table;
 
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_CV == IS_CV &&
@@ -32450,8 +32478,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_CONST != IS_UNUSED) {
@@ -32463,10 +32493,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_CV != IS_CONST && varname == &tmp) {
+                                       if (IS_CV != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
 
                                        HANDLE_EXCEPTION();
@@ -32485,10 +32515,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_CV != IS_CONST && varname == &tmp) {
+       if (IS_CV != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
 
        CHECK_EXCEPTION();
@@ -36614,6 +36644,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
        zval tmp, *varname;
        HashTable *target_symbol_table;
 
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_CV == IS_CV &&
@@ -36632,8 +36663,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_VAR != IS_UNUSED) {
@@ -36645,10 +36678,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_CV != IS_CONST && varname == &tmp) {
+                                       if (IS_CV != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
 
                                        HANDLE_EXCEPTION();
@@ -36667,10 +36700,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_CV != IS_CONST && varname == &tmp) {
+       if (IS_CV != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
 
        CHECK_EXCEPTION();
@@ -37919,6 +37952,7 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
        zval tmp, *varname;
        HashTable *target_symbol_table;
 
+       zend_bool tmp_is_dup = 0;
 
        SAVE_OPLINE();
        if (IS_CV == IS_CV &&
@@ -37937,8 +37971,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
                ZVAL_DUP(&tmp, varname);
                convert_to_string(&tmp);
                varname = &tmp;
+               tmp_is_dup = 1;
        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-               if (Z_REFCOUNTED_P(varname)) Z_ADDREF_P(varname);
+               ZVAL_COPY(&tmp, varname);
+               varname = &tmp;
        }
 
        if (IS_UNUSED != IS_UNUSED) {
@@ -37950,10 +37986,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
                        } else {
                                ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC);
                                if (UNEXPECTED(EG(exception) != NULL)) {
-                                       if (IS_CV != IS_CONST && varname == &tmp) {
+                                       if (IS_CV != IS_CONST && tmp_is_dup) {
                                                zval_dtor(&tmp);
                                        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-                                               zval_ptr_dtor(varname);
+                                               zval_ptr_dtor(&tmp);
                                        }
 
                                        HANDLE_EXCEPTION();
@@ -37972,10 +38008,10 @@ static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
                zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
        }
 
-       if (IS_CV != IS_CONST && varname == &tmp) {
+       if (IS_CV != IS_CONST && tmp_is_dup) {
                zval_dtor(&tmp);
        } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
-               zval_ptr_dtor(varname);
+               zval_ptr_dtor(&tmp);
        }
 
        CHECK_EXCEPTION();