]> granicus.if.org Git - php/commitdiff
Fixed bug #79818
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 10 Jul 2020 12:36:50 +0000 (14:36 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 10 Jul 2020 12:36:50 +0000 (14:36 +0200)
Only destroy the variable directly before reassigning it. The
value could be read in the meantime.

Zend/tests/bug79818.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug79818.phpt b/Zend/tests/bug79818.phpt
new file mode 100644 (file)
index 0000000..f3c0a69
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Bug #79818: BIND_STATIC frees old variable value too early
+--FILE--
+<?php
+function test($a) {
+    static $a = UNDEFINED;
+}
+test(new stdClass);
+?>
+--EXPECTF--
+Fatal error: Uncaught Error: Undefined constant 'UNDEFINED' in %s:%d
+Stack trace:
+#0 %s(%d): test(Object(stdClass))
+#1 {main}
+  thrown in %s on line %d
index b4067f7645b763b450d96b30e962cc3de14b221c..a0cb936c1329c68f68eddadc43f3788aa16e8f53 100644 (file)
@@ -8231,7 +8231,6 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
        zval *variable_ptr;
 
        variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
-       i_zval_ptr_dtor(variable_ptr);
 
        ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
        if (!ht) {
@@ -8252,10 +8251,11 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
                if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                        SAVE_OPLINE();
                        if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
-                               ZVAL_NULL(variable_ptr);
                                HANDLE_EXCEPTION();
                        }
                }
+
+               i_zval_ptr_dtor(variable_ptr);
                if (UNEXPECTED(!Z_ISREF_P(value))) {
                        zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
                        GC_SET_REFCOUNT(ref, 2);
@@ -8270,6 +8270,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
                        ZVAL_REF(variable_ptr, Z_REF_P(value));
                }
        } else {
+               i_zval_ptr_dtor(variable_ptr);
                ZVAL_COPY(variable_ptr, value);
        }
 
index 14a955f17dd138d488ca90c698d77995a12032ff..35deba24ba486f41cb262212ca0d0a7d80591ae0 100644 (file)
@@ -45225,7 +45225,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
        zval *variable_ptr;
 
        variable_ptr = EX_VAR(opline->op1.var);
-       i_zval_ptr_dtor(variable_ptr);
 
        ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
        if (!ht) {
@@ -45246,10 +45245,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
                if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                        SAVE_OPLINE();
                        if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
-                               ZVAL_NULL(variable_ptr);
                                HANDLE_EXCEPTION();
                        }
                }
+
+               i_zval_ptr_dtor(variable_ptr);
                if (UNEXPECTED(!Z_ISREF_P(value))) {
                        zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
                        GC_SET_REFCOUNT(ref, 2);
@@ -45264,6 +45264,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
                        ZVAL_REF(variable_ptr, Z_REF_P(value));
                }
        } else {
+               i_zval_ptr_dtor(variable_ptr);
                ZVAL_COPY(variable_ptr, value);
        }