From b529d02d248587d298487d3d46120be7ebd59480 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 26 Jan 2021 19:23:13 +0300 Subject: Allow observer handlers disabling optimization in RETURN opcode handler, that may cause loss value of returned local variable. --- Zend/zend_compile.h | 3 +++ Zend/zend_vm_def.h | 2 +- Zend/zend_vm_execute.h | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b4af5d9e3f..a4cb6fca74 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -531,6 +531,9 @@ struct _zend_execute_data { #define ZEND_CALL_DYNAMIC (1 << 25) #define ZEND_CALL_MAY_HAVE_UNDEF (1 << 26) #define ZEND_CALL_HAS_EXTRA_NAMED_PARAMS (1 << 27) +#define ZEND_CALL_OBSERVED (1 << 28) /* "fcall_begin" observer handler may set this flag */ + /* to prevent optimization in RETURN handler and */ + /* keep all local variables for "fcall_end" handler */ #define ZEND_CALL_SEND_ARG_BY_REF (1u << 31) #define ZEND_CALL_NESTED_FUNCTION (ZEND_CALL_FUNCTION | ZEND_CALL_NESTED) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 693578675f..75062824f2 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4269,7 +4269,7 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER)) do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 731c4af769..9d7eae0311 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4047,7 +4047,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_ do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -4124,7 +4124,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_OBSER do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -18568,7 +18568,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -21140,7 +21140,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -37678,7 +37678,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -54770,7 +54770,7 @@ zend_leave_helper_SPEC_LABEL: do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -54848,7 +54848,7 @@ zend_leave_helper_SPEC_LABEL: do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -56385,7 +56385,7 @@ zend_leave_helper_SPEC_LABEL: do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -56686,7 +56686,7 @@ zend_leave_helper_SPEC_LABEL: do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { @@ -57803,7 +57803,7 @@ zend_leave_helper_SPEC_LABEL: do { if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); if (GC_MAY_LEAK(ref)) { -- cgit v1.2.1