From 21fe9daf1cdc86cbd8800515166e19b2f8879b71 Mon Sep 17 00:00:00 2001 From: Kaiwang Chen Date: Wed, 11 Sep 2013 13:09:41 +0800 Subject: Simulate a complete custom exception handler by redirecting uncaught events. --- index.php | 12 ++++++++++++ system/core/CodeIgniter.php | 1 + system/core/Common.php | 29 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/index.php b/index.php index 3040ef080..a38ea991c 100755 --- a/index.php +++ b/index.php @@ -195,6 +195,18 @@ switch (ENVIRONMENT) exit(3); // EXIT_* constants not yet defined; 3 is EXIT_CONFIG. } +/* + *--------------------------------------------------------------- + * WORKING DIRECTORY FOR SHUTDOWN HANDLER + *--------------------------------------------------------------- + * + * CI assumes the directory containing index.php, while shutdown + * handlers execute in process's initial working directory. To make + * logging work, we need to change directory in the shutdown handler. + * + */ + define('CIPATH', getcwd()); + /* * ------------------------------------------------------------------- * Now that we know the path, set the main path constants diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index c962fda20..67c94cfd1 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -73,6 +73,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ------------------------------------------------------ */ set_error_handler('_exception_handler'); + register_shutdown_function('_shutdown_handler'); if ( ! is_php('5.4')) { diff --git a/system/core/Common.php b/system/core/Common.php index 7f296b133..0353a9d10 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -577,6 +577,35 @@ if ( ! function_exists('_exception_handler')) } } +// ------------------------------------------------------------------------ + +if ( ! function_exists('_shutdown_handler')) +{ + /** + * Shutdown Handler + * + * This is the shutdown handler that is declared at the top + * of CodeIgniter.php. The main reason we use this is to simulate + * a complete custom exception handler. + * + * E_STRICT is purposivly neglected because such events may have + * been caught. Duplication or none? None is preferred for now. + * + * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a + * @return void + */ + function _shutdown_handler() + { + $last_error = function_exists('error_get_last') ? error_get_last() : NULL; + if (isset($last_error) && + ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) + { + chdir(CIPATH); + _exception_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); + } + } +} + // -------------------------------------------------------------------- if ( ! function_exists('remove_invisible_characters')) -- cgit v1.2.3-24-g4f1b From 5f0ee055ddf0624017bfcd1748445d8854c0b5ea Mon Sep 17 00:00:00 2001 From: Kaiwang Chen Date: Thu, 12 Sep 2013 11:54:44 +0800 Subject: Remove unnecessary chdir() in the shutdown handler. --- index.php | 12 ------------ system/core/Common.php | 1 - 2 files changed, 13 deletions(-) diff --git a/index.php b/index.php index a38ea991c..3040ef080 100755 --- a/index.php +++ b/index.php @@ -195,18 +195,6 @@ switch (ENVIRONMENT) exit(3); // EXIT_* constants not yet defined; 3 is EXIT_CONFIG. } -/* - *--------------------------------------------------------------- - * WORKING DIRECTORY FOR SHUTDOWN HANDLER - *--------------------------------------------------------------- - * - * CI assumes the directory containing index.php, while shutdown - * handlers execute in process's initial working directory. To make - * logging work, we need to change directory in the shutdown handler. - * - */ - define('CIPATH', getcwd()); - /* * ------------------------------------------------------------------- * Now that we know the path, set the main path constants diff --git a/system/core/Common.php b/system/core/Common.php index 0353a9d10..edfad99c5 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -600,7 +600,6 @@ if ( ! function_exists('_shutdown_handler')) if (isset($last_error) && ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) { - chdir(CIPATH); _exception_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); } } -- cgit v1.2.3-24-g4f1b From 488ef2119e75ce6c299a193aed035218256eebd3 Mon Sep 17 00:00:00 2001 From: Kaiwang Chen Date: Thu, 12 Sep 2013 11:55:45 +0800 Subject: Add changelog entry for #2633. --- user_guide_src/source/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 3e36d88f5..a681cf3cf 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -436,6 +436,7 @@ Release Date: Not Released - Added support for HTTP-Only cookies with new config option *cookie_httponly* (default FALSE). - Renamed method ``_call_hook()`` to ``call_hook()`` in the :doc:`Hooks Library `. - ``$config['time_reference']`` now supports all timezone strings supported by PHP. + - Made the exception handler complete by registering a shutdown handler to redirect critical events to it. Bug fixes for 3.0 -- cgit v1.2.3-24-g4f1b From 8ce3134e739c688f2a3ade0d8c792d05d7879a78 Mon Sep 17 00:00:00 2001 From: Kaiwang Chen Date: Thu, 12 Sep 2013 22:55:58 +0800 Subject: Make the changelog entry for #2633 more descriptive. --- user_guide_src/source/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index a681cf3cf..c99afc112 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -436,7 +436,7 @@ Release Date: Not Released - Added support for HTTP-Only cookies with new config option *cookie_httponly* (default FALSE). - Renamed method ``_call_hook()`` to ``call_hook()`` in the :doc:`Hooks Library `. - ``$config['time_reference']`` now supports all timezone strings supported by PHP. - - Made the exception handler complete by registering a shutdown handler to redirect critical events to it. + - Made the exception handler complete by registering a shutdown handler to redirect critical events such as PHP parse errors to it, so that they can be displayed and logged without the help of the standard PHP error handler. Bug fixes for 3.0 -- cgit v1.2.3-24-g4f1b