From ffb848b275a085917413c171a79cbfdb1d0159d2 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 21 Dec 2012 01:56:37 +0100 Subject: [PATCH] Fix bug #63822: Crash when using closures with ArrayAccess op_array->T was used after the closure's op_array was already freed. This just swaps the freeing order. --- NEWS | 3 +++ Zend/zend_vm_def.h | 8 +++----- Zend/zend_vm_execute.h | 8 +++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index d63858df017..019513a1174 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 201?, PHP 5.5.0 Alpha 3 +- General improvements: + . Fixed bug #63822 (Crash when using closures with ArrayAccess). + (Nikita Popov) 18 Dec 2012, PHP 5.5.0 Alpha 2 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c933a48248d..2c17182b9f0 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1843,7 +1843,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) { - zend_bool nested; + zend_bool nested = EX(nested); zend_op_array *op_array = EX(op_array); EG(current_execute_data) = EX(prev_execute_data); @@ -1852,14 +1852,12 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) i_free_compiled_variables(execute_data); } + zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC); + if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) { zval_ptr_dtor((zval**)&op_array->prototype); } - nested = EX(nested); - - zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC); - if (nested) { execute_data = EG(current_execute_data); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index dab0df35409..c51df01c2d3 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -383,7 +383,7 @@ ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC) static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { - zend_bool nested; + zend_bool nested = EX(nested); zend_op_array *op_array = EX(op_array); EG(current_execute_data) = EX(prev_execute_data); @@ -392,14 +392,12 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) i_free_compiled_variables(execute_data); } + zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC); + if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) { zval_ptr_dtor((zval**)&op_array->prototype); } - nested = EX(nested); - - zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC); - if (nested) { execute_data = EG(current_execute_data); }