]> granicus.if.org Git - php/commitdiff
Fixed bug #45805 (Crach on throwing exception from error handler)
authorDmitry Stogov <dmitry@php.net>
Wed, 13 Aug 2008 07:19:43 +0000 (07:19 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 13 Aug 2008 07:19:43 +0000 (07:19 +0000)
NEWS
Zend/tests/bug45805.phpt [new file with mode: 0755]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index c29169a5cc18de1f92e52c9ffe019517f7f9adcb..09a81219bff1a5c16ec3c0d89de5302c31e4115b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ PHP                                                                        NEWS
 - Fixed a crash on invalid method in ReflectionParameter constructor.
   (Christian Seiler)
 
+- Fixed bug #45805 (Crach on throwing exception from error handler). (Dmitry)
 - Fixed bug #45765 (ReflectionObject with default parameters of self::xxx cause
   an error). (Felipe)
 - Fixed bug #45705 (rfc822_parse_adrlist() modifies passed address parameter).
diff --git a/Zend/tests/bug45805.phpt b/Zend/tests/bug45805.phpt
new file mode 100755 (executable)
index 0000000..ae8424c
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+Bug #45805 (Crach on throwing exception from error handler)
+--FILE--
+<?php
+class PHPUnit_Util_ErrorHandler
+{
+    public static function handleError($errno, $errstr, $errfile, $errline)
+    {
+        throw new RuntimeException;
+    }
+}
+
+class A {
+    public function getX() {
+        return NULL;
+    }
+}
+
+class B {
+    public function foo() {
+        $obj    = new A;
+        $source = &$obj->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
index 7083bb43fe044cca1e010d0a57e56b2fc0e5101b..4fa0941b8ac9842e9b11fc08762022adb44bc609 100644 (file)
@@ -1482,6 +1482,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 (EG(exception)) {
+                       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);
index 6488e85db89c3b489b8e84da08471c5aa1dcd2fe..b48dfcc45c0faf6a24f373c4a8e4d5fb75d4596f 100644 (file)
@@ -12385,6 +12385,10 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        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 (EG(exception)) {
+                       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);
@@ -14393,6 +14397,10 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        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 (EG(exception)) {
+
+                       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);
@@ -24506,6 +24514,10 @@ static int ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        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 (EG(exception)) {
+                       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);
@@ -26504,6 +26516,10 @@ static int ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        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 (EG(exception)) {
+
+                       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);