Skip to content

Commit b29dc14

Browse files
committed
- Fixed bug #61767 (Shutdown functions not called in certain error situation)
- Fixed bug #60909 (custom error handler throwing Exception + fatal error = no shutdown function)
1 parent 94582f9 commit b29dc14

File tree

7 files changed

+113
-1
lines changed

7 files changed

+113
-1
lines changed

NEWS

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ PHP NEWS
1313
. Fixed bug #62744 (dangling pointers made by zend_disable_class). (Laruence)
1414
. Fixed bug #62716 (munmap() is called with the incorrect length).
1515
(slangley@google.com)
16-
. Fixed bug ##62460 (php binaries installed as binary.dSYM). (Reeze Xia)
16+
. Fixed bug #62460 (php binaries installed as binary.dSYM). (Reeze Xia)
17+
. Fixed bug #61767 (Shutdown functions not called in certain error
18+
situation). (Dmitry)
1719
. Fixed bug #60194 (--with-zend-multibyte and --enable-debug reports LEAK
1820
with run-test.php). (Laruence)
21+
. Fixed bug #60909 (custom error handler throwing Exception + fatal error
22+
= no shutdown function). (Dmitry)
1923

2024
- CURL:
2125
. Fixed bug #62839 (curl_copy_handle segfault with CURLOPT_FILE). (Pierrick)

Zend/tests/bug51394.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,10 @@ function eh()
1313
set_error_handler("eh");
1414
$a = $empty($b);
1515
--EXPECTF--
16+
Warning: Uncaught exception 'Exception' with message 'error!' in %sbug51394.php:4
17+
Stack trace:
18+
#0 %sbug51394.php(9): eh(8, 'Undefined varia...', '%s', 9, Array)
19+
#1 {main}
20+
thrown in %sbug51394.php on line 4
21+
1622
Fatal error: Function name must be a string in %sbug51394.php on line 9

Zend/tests/bug60909_1.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Bug #60909 (custom error handler throwing Exception + fatal error = no shutdown function).
3+
--FILE--
4+
<?php
5+
register_shutdown_function(function(){echo("\n\n!!!shutdown!!!\n\n");});
6+
set_error_handler(function($errno, $errstr, $errfile, $errline){
7+
echo "error($errstr)";
8+
throw new Exception("Foo");
9+
});
10+
11+
require 'notfound.php';
12+
--EXPECTF--
13+
error(require(notfound.php): failed to open stream: No such file or directory)
14+
Warning: Uncaught exception 'Exception' with message 'Foo' in %sbug60909_1.php:5
15+
Stack trace:
16+
#0 %sbug60909_1.php(8): {closure}(2, 'require(notfoun...', '%s', 8, Array)
17+
#1 %sbug60909_1.php(8): require()
18+
#2 {main}
19+
thrown in %sbug60909_1.php on line 5
20+
21+
Fatal error: main(): Failed opening required 'notfound.php' (include_path='%s') in %sbug60909_1.php on line 8
22+
23+
24+
!!!shutdown!!!

Zend/tests/bug60909_2.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug #60909 (custom error handler throwing Exception + fatal error = no shutdown function).
3+
--FILE--
4+
<?php
5+
register_shutdown_function(function(){echo("\n\n!!!shutdown!!!\n\n");});
6+
set_error_handler(function($errno, $errstr, $errfile, $errline){throw new Exception("Foo");});
7+
8+
class Bad {
9+
public function __toString() {
10+
throw new Exception('Oops, I cannot do this');
11+
}
12+
}
13+
14+
$bad = new Bad();
15+
echo "$bad";
16+
--EXPECTF--
17+
Fatal error: Method Bad::__toString() must not throw an exception in %sbug60909_2.php on line 0
18+
19+
20+
!!!shutdown!!!

Zend/tests/bug61767.phpt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Bug #61767 (Shutdown functions not called in certain error situation)
3+
--FILE--
4+
<?php
5+
set_error_handler(function($code, $msg, $file = null, $line = null) {
6+
echo "Error handler called ($msg)\n";
7+
throw new \ErrorException($msg, $code, 0, $file, $line);
8+
});
9+
10+
register_shutdown_function(function(){
11+
echo "Shutting down\n";
12+
print_r(error_get_last());
13+
});
14+
15+
//$undefined = null; // defined variable does not cause problems
16+
$undefined->foo();
17+
--EXPECTF--
18+
Error handler called (Undefined variable: undefined)
19+
20+
Warning: Uncaught exception 'ErrorException' with message 'Undefined variable: undefined' in %sbug61767.php:13
21+
Stack trace:
22+
#0 %sbug61767.php(13): {closure}(8, 'Undefined varia...', '%s', 13, Array)
23+
#1 {main}
24+
thrown in %sbug61767.php on line 13
25+
26+
Fatal error: Call to a member function foo() on a non-object in %sbug61767.php on line 13
27+
Shutting down
28+
Array
29+
(
30+
[type] => 1
31+
[message] => Call to a member function foo() on a non-object
32+
[file] => %sbug61767.php
33+
[line] => 13
34+
)

Zend/zend.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,29 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
997997
zend_stack labels_stack;
998998
TSRMLS_FETCH();
999999

1000+
/* Report about uncaught exception in case of fatal errors */
1001+
if (EG(exception)) {
1002+
switch (type) {
1003+
case E_CORE_ERROR:
1004+
case E_ERROR:
1005+
case E_RECOVERABLE_ERROR:
1006+
case E_PARSE:
1007+
case E_COMPILE_ERROR:
1008+
case E_USER_ERROR:
1009+
if (zend_is_executing(TSRMLS_C)) {
1010+
error_lineno = zend_get_executed_lineno(TSRMLS_C);
1011+
}
1012+
zend_exception_error(EG(exception), E_WARNING TSRMLS_CC);
1013+
EG(exception) = NULL;
1014+
if (zend_is_executing(TSRMLS_C) && EG(opline_ptr)) {
1015+
active_opline->lineno = error_lineno;
1016+
}
1017+
break;
1018+
default:
1019+
break;
1020+
}
1021+
}
1022+
10001023
/* Obtain relevant filename and lineno */
10011024
switch (type) {
10021025
case E_CORE_ERROR:

Zend/zend_object_handlers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,7 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
12721272
if (retval) {
12731273
zval_ptr_dtor(&retval);
12741274
}
1275+
EG(exception) = NULL;
12751276
zend_error(E_ERROR, "Method %s::__toString() must not throw an exception", ce->name);
12761277
return FAILURE;
12771278
}

0 commit comments

Comments
 (0)