]> granicus.if.org Git - php/commitdiff
Fix #63206: Fully support error/exception_handler stacking, even with null or inside...
authorMark Plomer <mark.plomer@boerse-go.de>
Mon, 24 Feb 2020 20:32:02 +0000 (21:32 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 25 Feb 2020 11:43:42 +0000 (12:43 +0100)
Always push the current user_error/exception_handler to the stack,
even when it is empty, so restore_error_handler() always works as
expected.

The user_error_handler is especially temporarily empty when we are inside
the error handler, which caused inconsistent behaviour before.

NEWS
Zend/tests/bug63206.phpt [new file with mode: 0644]
Zend/tests/bug63206_1.phpt [new file with mode: 0644]
Zend/tests/bug63206_2.phpt [new file with mode: 0644]
Zend/zend_builtin_functions.c

diff --git a/NEWS b/NEWS
index 64682a8d070bd451be562039b7e9bbc5e0ea4bb6..12208cf46ab6d9dd53745a70894c1851bd344cb9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? ????, PHP 7.3.16
 
+- Core:
+  . Fixed bug #63206 (restore_error_handler does not restore previous errors
+    mask). (Mark Plomer)
+
 - COM:
   . Fixed bug #66322 (COMPersistHelper::SaveToFile can save to wrong location).
     (cmb)
diff --git a/Zend/tests/bug63206.phpt b/Zend/tests/bug63206.phpt
new file mode 100644 (file)
index 0000000..dc7bb1f
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+Bug #63206 Fully support error_handler stacking, even inside the error_handler
+--FILE--
+<?php
+
+set_error_handler(function() {
+    echo 'First handler' . PHP_EOL;
+});
+
+set_error_handler(function() {
+    echo 'Second handler' . PHP_EOL;
+
+    set_error_handler(function() {
+        echo 'Internal handler' . PHP_EOL;
+    });
+
+    $triggerInternalNotice++; // warnings while handling the error should go into internal handler
+
+    restore_error_handler();
+});
+
+$triggerNotice1++;
+$triggerNotice2++;
+?>
+--EXPECTF--
+Second handler
+Internal handler
+Second handler
+Internal handler
diff --git a/Zend/tests/bug63206_1.phpt b/Zend/tests/bug63206_1.phpt
new file mode 100644 (file)
index 0000000..f08f913
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Bug #63206 Fully support error_handler stacking, even with null
+--FILE--
+<?php
+
+set_error_handler(function() {
+    echo 'First handler' . PHP_EOL;
+});
+
+set_error_handler(function() {
+    echo 'Second handler' . PHP_EOL;
+});
+
+set_error_handler(null);
+
+set_error_handler(function() {
+    echo 'Fourth handler' . PHP_EOL;
+});
+
+restore_error_handler();
+restore_error_handler();
+
+$triggerNotice++;
+?>
+--EXPECTF--
+Second handler
diff --git a/Zend/tests/bug63206_2.phpt b/Zend/tests/bug63206_2.phpt
new file mode 100644 (file)
index 0000000..7a2bf38
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Bug #63206 Fully support exception_handler stacking, even with null
+--FILE--
+<?php
+
+set_exception_handler(function() {
+    echo 'First handler' . PHP_EOL;
+});
+
+set_exception_handler(function() {
+    echo 'Second handler' . PHP_EOL;
+});
+
+set_exception_handler(null);
+
+set_exception_handler(function() {
+    echo 'Fourth handler' . PHP_EOL;
+});
+
+restore_exception_handler();
+restore_exception_handler();
+
+throw new Exception();
+?>
+--EXPECTF--
+Second handler
index f4c4a4f31d7a9dae6a033ac4864f643a4cc24e00..69fbeec1e1c70dceefa9dbb48c14b3bb76605330 100644 (file)
@@ -1665,11 +1665,11 @@ ZEND_FUNCTION(set_error_handler)
 
        if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
                ZVAL_COPY(return_value, &EG(user_error_handler));
-
-               zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
-               zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
        }
 
+       zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
+       zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
+
        if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
                ZVAL_UNDEF(&EG(user_error_handler));
                return;
@@ -1732,10 +1732,10 @@ ZEND_FUNCTION(set_exception_handler)
 
        if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
                ZVAL_COPY(return_value, &EG(user_exception_handler));
-
-               zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
        }
 
+       zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
+
        if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
                ZVAL_UNDEF(&EG(user_exception_handler));
                return;