summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorByron Jones <bjones@mozilla.com>2012-04-10 15:09:28 +0200
committerByron Jones <bjones@mozilla.com>2012-04-10 15:09:28 +0200
commitb8b57b2c41fd39d4c4791699759d2b68a3a2215a (patch)
tree0a9e52a85cb315bf02a4ffcc45b12a2d5989a1ed /Bugzilla
parent71f822cd35dbd13a11e5bf0563f046010f587923 (diff)
downloadbugzilla-b8b57b2c41fd39d4c4791699759d2b68a3a2215a.tar.gz
bugzilla-b8b57b2c41fd39d4c4791699759d2b68a3a2215a.tar.xz
Bug 739153: fix infinite recursion in error handler
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Arecibo.pm91
-rw-r--r--Bugzilla/Error.pm5
2 files changed, 69 insertions, 27 deletions
diff --git a/Bugzilla/Arecibo.pm b/Bugzilla/Arecibo.pm
index 54458cca2..92c99c399 100644
--- a/Bugzilla/Arecibo.pm
+++ b/Bugzilla/Arecibo.pm
@@ -228,39 +228,76 @@ sub _in_eval {
return $in_eval;
}
-BEGIN {
- require CGI::Carp;
- CGI::Carp::set_die_handler(sub {
- return if _in_eval();
- my $message = shift;
- my $is_compilation_failure = $message =~ /\bcompilation (aborted|failed)\b/i;
- if (!$is_compilation_failure) {
- eval { Bugzilla::Error::ThrowTemplateError($message) };
- }
- if ($is_compilation_failure || $@) {
- print "Content-type: text/html\n\n";
- my $uid = arecibo_generate_id();
- my $notified = arecibo_handle_error('error', $message, $uid);
- my $maintainer = html_quote(Bugzilla->params->{'maintainer'});
- $message = html_quote($message);
- $uid = html_quote($uid);
+sub _arecibo_die_handler {
+ my $message = shift;
+ $message =~ s/^undef error - //;
+
+ # avoid recursion, and check for CGI::Carp::die failures
+ my $in_cgi_carp_die = 0;
+ for (my $stack = 1; my $sub = (caller($stack))[3]; $stack++) {
+ return if $sub =~ /:_arecibo_die_handler$/;
+ $in_cgi_carp_die = 1 if $sub =~ /CGI::Carp::die$/;
+ }
+
+ return if _in_eval();
+
+ # mod_perl overrides exit to call die with this string
+ exit if $message =~ /\bModPerl::Util::exit\b/;
+
+ my $nested_error = '';
+ my $is_compilation_failure = $message =~ /\bcompilation (aborted|failed)\b/i;
+
+ # if we are called via CGI::Carp::die chances are something is seriously
+ # wrong, so skip trying to use ThrowTemplateError
+ if (!$in_cgi_carp_die && !$is_compilation_failure) {
+ eval { Bugzilla::Error::ThrowTemplateError($message) };
+ $nested_error = $@ if $@;
+ }
+
+ # right now it's hard to determine if we've already returned a content-type
+ # header, it's better to return two than none
+ print "Content-type: text/html\n\n";
+
+ if ($is_compilation_failure ||
+ $in_cgi_carp_die ||
+ ($nested_error && $nested_error !~ /\bModPerl::Util::exit\b/)
+ ) {
+ $nested_error = html_quote($nested_error);
+ my $uid = arecibo_generate_id();
+ my $notified = arecibo_handle_error('error', $message, $uid);
+ my $maintainer = html_quote(Bugzilla->params->{'maintainer'});
+ $message =~ s/ at \S+ line \d+\.\s*$//;
+ $message = html_quote($message);
+ $uid = html_quote($uid);
+ print qq(
+ <h1>Bugzilla has suffered an internal error</h1>
+ <pre>$message</pre>
+ <hr>
+ <pre>$nested_error</pre>
+ );
+ if ($notified) {
print qq(
- <h1>Bugzilla has suffered an internal error</h1>
- <pre>$message</pre>
+ The <a href="mailto:$maintainer">Bugzilla maintainers</a> have
+ been notified of this error [#$uid].
);
- if ($notified) {
- print qq(
- The <a href="mailto:$maintainer">Bugzilla maintainers</a> have
- been notified of this error [#$uid].
- );
- };
- exit;
- }
- });
+ };
+ }
+ exit;
+}
+
+sub install_arecibo_handler {
+ require CGI::Carp;
+ CGI::Carp::set_die_handler(\&_arecibo_die_handler);
$main::SIG{__WARN__} = sub {
return if _in_eval();
arecibo_handle_error('warning', shift);
};
}
+BEGIN {
+ if ($ENV{SCRIPT_NAME} || $ENV{MOD_PERL}) {
+ install_arecibo_handler();
+ }
+}
+
1;
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm
index c2fcfdd55..df03dfd6d 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -192,11 +192,16 @@ sub ThrowTemplateError {
die("error: template error: $template_err");
}
+ # mod_perl overrides exit to call die with this string
+ # we never want to display this to the user
+ exit if $template_err =~ /\bModPerl::Util::exit\b/;
+
$vars->{'template_error_msg'} = $template_err;
$vars->{'error'} = "template_error";
$vars->{'uid'} = arecibo_generate_id();
arecibo_handle_error('error', $template_err, $vars->{'uid'});
+ $vars->{'template_error_msg'} =~ s/ at \S+ line \d+\.\s*$//;
my $template = Bugzilla->template;