Skip to content

Commit 8c6a7c3

Browse files
not-implementednikic
authored andcommitted
Fix #63206: Fully support error/exception_handler stacking, even with null or inside the handler
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.
1 parent 56cdbe6 commit 8c6a7c3

File tree

5 files changed

+90
-5
lines changed

5 files changed

+90
-5
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 7.3.16
44

5+
- Core:
6+
. Fixed bug #63206 (restore_error_handler does not restore previous errors
7+
mask). (Mark Plomer)
8+
59
- COM:
610
. Fixed bug #66322 (COMPersistHelper::SaveToFile can save to wrong location).
711
(cmb)

Zend/tests/bug63206.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Bug #63206 Fully support error_handler stacking, even inside the error_handler
3+
--FILE--
4+
<?php
5+
6+
set_error_handler(function() {
7+
echo 'First handler' . PHP_EOL;
8+
});
9+
10+
set_error_handler(function() {
11+
echo 'Second handler' . PHP_EOL;
12+
13+
set_error_handler(function() {
14+
echo 'Internal handler' . PHP_EOL;
15+
});
16+
17+
$triggerInternalNotice++; // warnings while handling the error should go into internal handler
18+
19+
restore_error_handler();
20+
});
21+
22+
$triggerNotice1++;
23+
$triggerNotice2++;
24+
?>
25+
--EXPECTF--
26+
Second handler
27+
Internal handler
28+
Second handler
29+
Internal handler

Zend/tests/bug63206_1.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Bug #63206 Fully support error_handler stacking, even with null
3+
--FILE--
4+
<?php
5+
6+
set_error_handler(function() {
7+
echo 'First handler' . PHP_EOL;
8+
});
9+
10+
set_error_handler(function() {
11+
echo 'Second handler' . PHP_EOL;
12+
});
13+
14+
set_error_handler(null);
15+
16+
set_error_handler(function() {
17+
echo 'Fourth handler' . PHP_EOL;
18+
});
19+
20+
restore_error_handler();
21+
restore_error_handler();
22+
23+
$triggerNotice++;
24+
?>
25+
--EXPECTF--
26+
Second handler

Zend/tests/bug63206_2.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Bug #63206 Fully support exception_handler stacking, even with null
3+
--FILE--
4+
<?php
5+
6+
set_exception_handler(function() {
7+
echo 'First handler' . PHP_EOL;
8+
});
9+
10+
set_exception_handler(function() {
11+
echo 'Second handler' . PHP_EOL;
12+
});
13+
14+
set_exception_handler(null);
15+
16+
set_exception_handler(function() {
17+
echo 'Fourth handler' . PHP_EOL;
18+
});
19+
20+
restore_exception_handler();
21+
restore_exception_handler();
22+
23+
throw new Exception();
24+
?>
25+
--EXPECTF--
26+
Second handler

Zend/zend_builtin_functions.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,11 +1665,11 @@ ZEND_FUNCTION(set_error_handler)
16651665

16661666
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
16671667
ZVAL_COPY(return_value, &EG(user_error_handler));
1668-
1669-
zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
1670-
zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
16711668
}
16721669

1670+
zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
1671+
zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
1672+
16731673
if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
16741674
ZVAL_UNDEF(&EG(user_error_handler));
16751675
return;
@@ -1732,10 +1732,10 @@ ZEND_FUNCTION(set_exception_handler)
17321732

17331733
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
17341734
ZVAL_COPY(return_value, &EG(user_exception_handler));
1735-
1736-
zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
17371735
}
17381736

1737+
zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
1738+
17391739
if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
17401740
ZVAL_UNDEF(&EG(user_exception_handler));
17411741
return;

0 commit comments

Comments
 (0)