From: Nikita Popov Date: Fri, 10 Jul 2020 12:36:50 +0000 (+0200) Subject: Fixed bug #79818 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6556846754b6b513d7ce74d2ebd2f21a61252074;p=php Fixed bug #79818 Only destroy the variable directly before reassigning it. The value could be read in the meantime. --- diff --git a/Zend/tests/bug79818.phpt b/Zend/tests/bug79818.phpt new file mode 100644 index 0000000000..f3c0a69825 --- /dev/null +++ b/Zend/tests/bug79818.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #79818: BIND_STATIC frees old variable value too early +--FILE-- + +--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 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b4067f7645..a0cb936c13 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 14a955f17d..35deba24ba 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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); }