|
|
4c79b5 |
|
|
|
4c79b5 |
# Mantis - a php based bugtracking system
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org
|
|
|
4c79b5 |
# Copyright (C) 2002 - 2007 Mantis Team - mantisbt-dev@lists.sourceforge.net
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# Mantis is free software: you can redistribute it and/or modify
|
|
|
4c79b5 |
# it under the terms of the GNU General Public License as published by
|
|
|
4c79b5 |
# the Free Software Foundation, either version 2 of the License, or
|
|
|
4c79b5 |
# (at your option) any later version.
|
|
|
4c79b5 |
#
|
|
|
4c79b5 |
# Mantis is distributed in the hope that it will be useful,
|
|
|
4c79b5 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
4c79b5 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
4c79b5 |
# GNU General Public License for more details.
|
|
|
4c79b5 |
#
|
|
|
4c79b5 |
# You should have received a copy of the GNU General Public License
|
|
|
4c79b5 |
# along with Mantis. If not, see <http://www.gnu.org/licenses/>.
|
|
|
4c79b5 |
|
|
|
4c79b5 |
#------------------------------
|
|
|
4c79b5 |
# $Revision: 2643 $
|
|
|
4c79b5 |
# $Author: al $
|
|
|
4c79b5 |
# $Date: 2009-06-18 19:06:27 -0400 (Thu, 18 Jun 2009) $
|
|
|
4c79b5 |
#------------------------------
|
|
|
4c79b5 |
|
|
|
4c79b5 |
### Error API ###
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# set up error_handler() as the new default error handling function
|
|
|
4c79b5 |
set_error_handler( 'error_handler' );
|
|
|
4c79b5 |
|
|
|
4c79b5 |
#########################################
|
|
|
4c79b5 |
# SECURITY NOTE: these globals are initialized here to prevent them
|
|
|
4c79b5 |
# being spoofed if register_globals is turned on
|
|
|
4c79b5 |
#
|
|
|
4c79b5 |
$g_error_parameters = array();
|
|
|
4c79b5 |
$g_error_handled = false;
|
|
|
4c79b5 |
$g_error_proceed_url = null;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Default error handler
|
|
|
4c79b5 |
#
|
|
|
4c79b5 |
# This handler will not receive E_ERROR, E_PARSE, E_CORE_*, or E_COMPILE_*
|
|
|
4c79b5 |
# errors.
|
|
|
4c79b5 |
#
|
|
|
4c79b5 |
# E_USER_* are triggered by us and will contain an error constant in $p_error
|
|
|
4c79b5 |
# The others, being system errors, will come with a string in $p_error
|
|
|
4c79b5 |
#
|
|
|
4c79b5 |
function error_handler( $p_type, $p_error, $p_file, $p_line, $p_context ) {
|
|
|
4c79b5 |
global $g_error_parameters, $g_error_handled, $g_error_proceed_url;
|
|
|
4c79b5 |
global $g_lang_overrides;
|
|
|
4c79b5 |
global $g_error_send_page_header;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# check if errors were disabled with @ somewhere in this call chain
|
|
|
4c79b5 |
# also suppress php 5 strict warnings
|
|
|
4c79b5 |
if ( 0 == error_reporting() || 2048 == $p_type ) {
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$t_lang_pushed = false;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# flush any language overrides to return to user's natural default
|
|
|
4c79b5 |
if ( function_exists( 'db_is_connected' ) ) {
|
|
|
4c79b5 |
if ( db_is_connected() ) {
|
|
|
4c79b5 |
lang_push( lang_get_default() );
|
|
|
4c79b5 |
$t_lang_pushed = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$t_short_file = basename( $p_file );
|
|
|
4c79b5 |
$t_method_array = config_get( 'display_errors' );
|
|
|
4c79b5 |
if ( isset( $t_method_array[$p_type] ) ) {
|
|
|
4c79b5 |
$t_method = $t_method_array[$p_type];
|
|
|
4c79b5 |
} else {
|
|
|
4c79b5 |
$t_method = 'none';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# build an appropriate error string
|
|
|
4c79b5 |
switch ( $p_type ) {
|
|
|
4c79b5 |
case E_WARNING:
|
|
|
4c79b5 |
$t_error_type = 'SYSTEM WARNING';
|
|
|
4c79b5 |
$t_error_description = $p_error;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
case E_NOTICE:
|
|
|
4c79b5 |
$t_error_type = 'SYSTEM NOTICE';
|
|
|
4c79b5 |
$t_error_description = $p_error;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
case E_USER_ERROR:
|
|
|
4c79b5 |
$t_error_type = "APPLICATION ERROR #$p_error";
|
|
|
4c79b5 |
$t_error_description = error_string( $p_error );
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
case E_USER_WARNING:
|
|
|
4c79b5 |
$t_error_type = "APPLICATION WARNING #$p_error";
|
|
|
4c79b5 |
$t_error_description = error_string( $p_error );
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
case E_USER_NOTICE:
|
|
|
4c79b5 |
# used for debugging
|
|
|
4c79b5 |
$t_error_type = 'DEBUG';
|
|
|
4c79b5 |
$t_error_description = $p_error;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
#shouldn't happen, just display the error just in case
|
|
|
4c79b5 |
$t_error_type = '';
|
|
|
4c79b5 |
$t_error_description = $p_error;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$t_error_description = nl2br( $t_error_description );
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ( 'halt' == $t_method ) {
|
|
|
4c79b5 |
$t_old_contents = ob_get_contents();
|
|
|
4c79b5 |
# ob_end_clean() still seems to call the output handler which
|
|
|
4c79b5 |
# outputs the headers indicating compression. If we had
|
|
|
4c79b5 |
# PHP > 4.2.0 we could use ob_clean() instead but as it is
|
|
|
4c79b5 |
# we need to disable compression.
|
|
|
4c79b5 |
compress_disable();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ( ob_get_length() ) {
|
|
|
4c79b5 |
ob_end_clean();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# don't send the page header information if it has already been sent
|
|
|
4c79b5 |
if ( $g_error_send_page_header ) {
|
|
|
4c79b5 |
html_page_top1();
|
|
|
4c79b5 |
if ( $p_error != ERROR_DB_QUERY_FAILED ) {
|
|
|
4c79b5 |
html_page_top2();
|
|
|
4c79b5 |
} else {
|
|
|
4c79b5 |
html_page_top2a();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT "$t_error_type";
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT " $t_error_description ";
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ( null === $g_error_proceed_url ) {
|
|
|
4c79b5 |
PRINT lang_get( 'error_no_proceed' );
|
|
|
4c79b5 |
} else {
|
|
|
4c79b5 |
PRINT "" . lang_get( 'proceed' ) . '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ( ON == config_get( 'show_detailed_errors' ) ) {
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
error_print_details( $p_file, $p_line, $p_context );
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
error_print_stack_trace();
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ( $g_error_handled && !is_blank( $t_old_contents ) ) {
|
|
|
4c79b5 |
PRINT 'Previous non-fatal errors occurred. Page contents follow. ';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
PRINT $t_old_contents;
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ( $p_error != ERROR_DB_QUERY_FAILED ) {
|
|
|
4c79b5 |
html_page_bottom1();
|
|
|
4c79b5 |
} else {
|
|
|
4c79b5 |
html_body_end();
|
|
|
4c79b5 |
html_end();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
exit();
|
|
|
4c79b5 |
} else if ( 'inline' == $t_method ) {
|
|
|
4c79b5 |
PRINT "$t_error_type: $t_error_description ";
|
|
|
4c79b5 |
} else {
|
|
|
4c79b5 |
# do nothing
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ( $t_lang_pushed ) {
|
|
|
4c79b5 |
lang_pop();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$g_error_parameters = array();
|
|
|
4c79b5 |
$g_error_handled = true;
|
|
|
4c79b5 |
$g_error_proceed_url = null;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Print out the error details including context
|
|
|
4c79b5 |
function error_print_details( $p_file, $p_line, $p_context ) {
|
|
|
4c79b5 |
?>
|
|
|
4c79b5 |
<center>
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
Full path:
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
Line:
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
</center>
|
|
|
4c79b5 |
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Print out the variable context given
|
|
|
4c79b5 |
function error_print_context( $p_context ) {
|
|
|
4c79b5 |
if( !is_array( $p_context ) ) {
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# print normal variables
|
|
|
4c79b5 |
foreach ( $p_context as $t_var => $t_val ) {
|
|
|
4c79b5 |
if ( !is_array( $t_val ) && !is_object( $t_val ) ) {
|
|
|
4c79b5 |
$t_val = string_html_entities( (string)$t_val );
|
|
|
4c79b5 |
$t_type = gettype( $t_val );
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# Mask Passwords
|
|
|
4c79b5 |
if ( strpos( $t_var, 'password' ) !== false ) {
|
|
|
4c79b5 |
$t_val = '**********';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT "$t_var$t_val$t_type\n";
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# print arrays
|
|
|
4c79b5 |
foreach ( $p_context as $t_var => $t_val ) {
|
|
|
4c79b5 |
if ( is_array( $t_val ) && ( $t_var != 'GLOBALS' ) ) {
|
|
|
4c79b5 |
PRINT " $t_var";
|
|
|
4c79b5 |
PRINT "";
|
|
|
4c79b5 |
error_print_context( $t_val );
|
|
|
4c79b5 |
PRINT "";
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Print out a stack trace if PHP provides the facility or xdebug is present
|
|
|
4c79b5 |
function error_print_stack_trace() {
|
|
|
4c79b5 |
if ( extension_loaded( 'xdebug' ) ) { #check for xdebug presence
|
|
|
4c79b5 |
$t_stack = xdebug_get_function_stack();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# reverse the array in a separate line of code so the
|
|
|
4c79b5 |
# array_reverse() call doesn't appear in the stack
|
|
|
4c79b5 |
$t_stack = array_reverse( $t_stack );
|
|
|
4c79b5 |
array_shift( $t_stack ); #remove the call to this function from the stack trace
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '<center>';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ( $t_stack as $t_frame ) {
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
PRINT '' . string_html_entities( $t_frame['file'] ) . '' . $t_frame['line'] . '' . ( isset( $t_frame['function'] ) ? $t_frame['function'] : '???' ) . '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$t_args = array();
|
|
|
4c79b5 |
if ( isset( $t_frame['params'] ) ) {
|
|
|
4c79b5 |
foreach( $t_frame['params'] as $t_value ) {
|
|
|
4c79b5 |
$t_args[] = error_build_parameter_string( $t_value );
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '( ' . string_html_entities( implode( $t_args, ', ' ) ) . ' )';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
PRINT '</center>';
|
|
|
4c79b5 |
} else {
|
|
|
4c79b5 |
$t_stack = debug_backtrace();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
array_shift( $t_stack ); #remove the call to this function from the stack trace
|
|
|
4c79b5 |
array_shift( $t_stack ); #remove the call to the error handler from the stack trace
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '<center>';
|
|
|
4c79b5 |
PRINT 'FilenameLineFunctionArgs';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ( $t_stack as $t_frame ) {
|
|
|
4c79b5 |
PRINT '';
|
|
|
4c79b5 |
PRINT '' . string_html_entities( $t_frame['file'] ) . '' . (isset( $t_frame['line'] ) ? $t_frame['line'] : '-') . '' . $t_frame['function'] . '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$t_args = array();
|
|
|
4c79b5 |
if ( isset( $t_frame['args'] ) ) {
|
|
|
4c79b5 |
foreach( $t_frame['args'] as $t_value ) {
|
|
|
4c79b5 |
$t_args[] = error_build_parameter_string( $t_value );
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '( ' . string_html_entities( implode( $t_args, ', ' ) ) . ' )';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
PRINT '</center>';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Build a string describing the parameters to a function
|
|
|
4c79b5 |
function error_build_parameter_string( $p_param ) {
|
|
|
4c79b5 |
if ( is_array( $p_param ) ) {
|
|
|
4c79b5 |
$t_results = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ( $p_param as $t_key => $t_value ) {
|
|
|
4c79b5 |
$t_results[] = '[' . error_build_parameter_string( $t_key ) . ']' .
|
|
|
4c79b5 |
' => ' . error_build_parameter_string( $t_value );
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return '{ ' . implode( $t_results, ', ' ) . ' }';
|
|
|
4c79b5 |
} else if ( is_bool( $p_param ) ) {
|
|
|
4c79b5 |
if ( $p_param ) {
|
|
|
4c79b5 |
return 'true';
|
|
|
4c79b5 |
} else {
|
|
|
4c79b5 |
return 'false';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
} else if ( is_float( $p_param ) || is_int( $p_param ) ) {
|
|
|
4c79b5 |
return $p_param;
|
|
|
4c79b5 |
} else if ( is_null( $p_param ) ) {
|
|
|
4c79b5 |
return 'null';
|
|
|
4c79b5 |
} else if ( is_object( $p_param ) ) {
|
|
|
4c79b5 |
$t_results = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$t_class_name = get_class( $p_param );
|
|
|
4c79b5 |
$t_inst_vars = get_object_vars( $p_param );
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ( $t_inst_vars as $t_name => $t_value ) {
|
|
|
4c79b5 |
$t_results[] = "[$t_name]" .
|
|
|
4c79b5 |
' => ' . error_build_parameter_string( $t_value );
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return 'Object <$t_class_name> ( ' . implode( $t_results, ', ' ) . ' )';
|
|
|
4c79b5 |
} else if ( is_string( $p_param ) ) {
|
|
|
4c79b5 |
return "'$p_param'";
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Return an error string (in the current language) for the given error
|
|
|
4c79b5 |
function error_string( $p_error ) {
|
|
|
4c79b5 |
global $g_error_parameters;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$MANTIS_ERROR = lang_get( 'MANTIS_ERROR' );
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# We pad the parameter array to make sure that we don't get errors if
|
|
|
4c79b5 |
# the caller didn't give enough parameters for the error string
|
|
|
4c79b5 |
$t_padding = array_pad( array(), 10, '' );
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$t_error = $MANTIS_ERROR[$p_error];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return string_html_specialchars( call_user_func_array( 'sprintf', array_merge( array( $t_error ), $g_error_parameters, $t_padding ) ) );
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Check if we have handled an error during this page
|
|
|
4c79b5 |
# Return true if an error has been handled, false otherwise
|
|
|
4c79b5 |
function error_handled() {
|
|
|
4c79b5 |
global $g_error_handled;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return ( true == $g_error_handled );
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Set additional info parameters to be used when displaying the next error
|
|
|
4c79b5 |
# This function takes a variable number of parameters
|
|
|
4c79b5 |
#
|
|
|
4c79b5 |
# When writing internationalized error strings, note that you can change the
|
|
|
4c79b5 |
# order of parameters in the string. See the PHP manual page for the
|
|
|
4c79b5 |
# sprintf() function for more details.
|
|
|
4c79b5 |
function error_parameters() {
|
|
|
4c79b5 |
global $g_error_parameters;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$g_error_parameters = func_get_args();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
# ---------------
|
|
|
4c79b5 |
# Set a url to give to the user to proceed after viewing the error
|
|
|
4c79b5 |
function error_proceed_url( $p_url ) {
|
|
|
4c79b5 |
global $g_error_proceed_url;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$g_error_proceed_url = $p_url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
?>
|