From: Dmitry Stogov Date: Wed, 13 Aug 2008 07:22:40 +0000 (+0000) Subject: Fixed bug #45805 (Crach on throwing exception from error handler) X-Git-Tag: BEFORE_HEAD_NS_CHANGE~742 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f83076cf4bd63472fb361525476f76342bbc488d;p=php Fixed bug #45805 (Crach on throwing exception from error handler) --- diff --git a/Zend/tests/bug45805.phpt b/Zend/tests/bug45805.phpt new file mode 100755 index 0000000000..ae8424c04f --- /dev/null +++ b/Zend/tests/bug45805.phpt @@ -0,0 +1,46 @@ +--TEST-- +Bug #45805 (Crach on throwing exception from error handler) +--FILE-- +getX(); + } + + public function bar() { + $m = new ReflectionMethod('B', 'foo'); + $m->invoke($this); + } +} + +set_error_handler( + array('PHPUnit_Util_ErrorHandler', 'handleError'), E_ALL | E_STRICT +); + +$o = new B; +$o->bar(); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'RuntimeException' in %sbug45805.php:%d +Stack trace: +#0 %sbug45805.php(%d): PHPUnit_Util_ErrorHandler::handleError(2048, 'Only variables ...', '%s', %d, Array) +#1 [internal function]: B->foo() +#2 %sbug45805.php(%d): ReflectionMethod->invoke(Object(B)) +#3 %sbug45805.php(%d): B->bar() +#4 {main} + thrown in %sbug45805.php on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0f3372717c..cef9d961ab 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1664,6 +1664,10 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */ } zend_error(E_STRICT, "Only variables should be assigned by reference"); + if (UNEXPECTED(EG(exception) != NULL)) { + FREE_OP2_VAR_PTR(); + ZEND_VM_NEXT_OPCODE(); + } ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN); } else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { PZVAL_LOCK(*value_ptr_ptr); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d6fad02ef3..e8649a43c9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -14442,6 +14442,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */ } zend_error(E_STRICT, "Only variables should be assigned by reference"); + if (UNEXPECTED(EG(exception) != NULL)) { + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + ZEND_VM_NEXT_OPCODE(); + } return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { PZVAL_LOCK(*value_ptr_ptr); @@ -16952,6 +16956,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */ } zend_error(E_STRICT, "Only variables should be assigned by reference"); + if (UNEXPECTED(EG(exception) != NULL)) { + + ZEND_VM_NEXT_OPCODE(); + } return ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { PZVAL_LOCK(*value_ptr_ptr); @@ -28641,6 +28649,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */ } zend_error(E_STRICT, "Only variables should be assigned by reference"); + if (UNEXPECTED(EG(exception) != NULL)) { + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + ZEND_VM_NEXT_OPCODE(); + } return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { PZVAL_LOCK(*value_ptr_ptr); @@ -30916,6 +30928,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */ } zend_error(E_STRICT, "Only variables should be assigned by reference"); + if (UNEXPECTED(EG(exception) != NULL)) { + + ZEND_VM_NEXT_OPCODE(); + } return ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { PZVAL_LOCK(*value_ptr_ptr);