summaryrefslogtreecommitdiff
path: root/rt/lib/RT/Interface
diff options
context:
space:
mode:
authorivan <ivan>2011-04-18 23:15:19 +0000
committerivan <ivan>2011-04-18 23:15:19 +0000
commit75162bb14b3e38d66617077843f4dfdcaf09d5c4 (patch)
treed89dd49a476cf2f0859ed6a0adc2992ea6d69d04 /rt/lib/RT/Interface
parentfc6209f398899f0211cfcedeb81a3cd65e04a941 (diff)
import rt 3.8.10
Diffstat (limited to 'rt/lib/RT/Interface')
-rw-r--r--rt/lib/RT/Interface/CLI.pm19
-rwxr-xr-xrt/lib/RT/Interface/Email.pm7
-rwxr-xr-xrt/lib/RT/Interface/Email/Auth/GnuPG.pm9
-rw-r--r--rt/lib/RT/Interface/Email/Auth/MailFrom.pm7
-rw-r--r--rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm7
-rw-r--r--rt/lib/RT/Interface/REST.pm30
-rw-r--r--rt/lib/RT/Interface/Web.pm56
-rw-r--r--rt/lib/RT/Interface/Web/Handler.pm5
-rw-r--r--rt/lib/RT/Interface/Web/Menu/Item.pm3
-rwxr-xr-xrt/lib/RT/Interface/Web/QueryBuilder.pm5
-rwxr-xr-xrt/lib/RT/Interface/Web/QueryBuilder/Tree.pm5
-rwxr-xr-xrt/lib/RT/Interface/Web/Standalone.pm9
12 files changed, 95 insertions, 67 deletions
diff --git a/rt/lib/RT/Interface/CLI.pm b/rt/lib/RT/Interface/CLI.pm
index 00bd1b64e..5e1999816 100644
--- a/rt/lib/RT/Interface/CLI.pm
+++ b/rt/lib/RT/Interface/CLI.pm
@@ -58,7 +58,7 @@ BEGIN {
use vars qw ($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS);
# set the version for version checking
- $VERSION = do { my @r = (q$Revision: 1.1.1.9 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
+ $VERSION = do { my @r = (q$Revision: 1.1.1.10 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
# your exported package globals go here,
# as well as any optionally exported functions
@@ -200,9 +200,9 @@ sub GetMessageContent {
#Load the sourcefile, if it's been handed to us
if ($source) {
- open (SOURCE, "<$source");
- @lines = (<SOURCE>);
- close (SOURCE);
+ open( SOURCE, '<', $source ) or die $!;
+ @lines = (<SOURCE>) or die $!;
+ close (SOURCE) or die $!;
}
elsif ($args{'Content'}) {
@lines = split('\n',$args{'Content'});
@@ -214,7 +214,7 @@ sub GetMessageContent {
for (@lines) {
print $fh $_;
}
- close ($fh);
+ close ($fh) or die $!;
#Edit the file if we need to
if ($edit) {
@@ -226,9 +226,9 @@ sub GetMessageContent {
system ($ENV{'EDITOR'}, $filename);
}
- open (READ, "<$filename");
+ open( READ, '<', $filename ) or die $!;
my @newlines = (<READ>);
- close (READ);
+ close (READ) or die $!;
unlink ($filename) unless (debug());
return(\@newlines);
@@ -256,9 +256,6 @@ sub debug {
# }}}
-eval "require RT::Interface::CLI_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Vendor.pm});
-eval "require RT::Interface::CLI_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Local.pm});
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Email.pm b/rt/lib/RT/Interface/Email.pm
index cda61305b..401e970e8 100755
--- a/rt/lib/RT/Interface/Email.pm
+++ b/rt/lib/RT/Interface/Email.pm
@@ -445,7 +445,7 @@ sub SendEmail {
# don't ignore CHLD signal to get proper exit code
local $SIG{'CHLD'} = 'DEFAULT';
- open my $mail, "|$path $args >/dev/null"
+ open( my $mail, '|-', "$path $args >/dev/null" )
or die "couldn't execute program: $!";
# if something wrong with $mail->print we will get PIPE signal, handle it
@@ -1809,9 +1809,6 @@ sub _RecordSendEmailFailure {
}
}
-eval "require RT::Interface::Email_Vendor";
-die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Email_Vendor.pm} );
-eval "require RT::Interface::Email_Local";
-die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Email_Local.pm} );
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm
index cc15abbd1..6d43b9610 100755
--- a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm
+++ b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm
@@ -250,14 +250,7 @@ sub VerifyDecrypt {
return $status, @res, @nested;
}
-eval "require RT::Interface::Email::Auth::GnuPG_Vendor";
-die $@
- if ( $@
- && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/GnuPG_Vendor.pm} );
-eval "require RT::Interface::Email::Auth::GnuPG_Local";
-die $@
- if ( $@
- && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/GnuPG_Local.pm} );
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
index a90306b67..be2f517e1 100644
--- a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
+++ b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
@@ -48,6 +48,8 @@
package RT::Interface::Email::Auth::MailFrom;
use RT::Interface::Email qw(ParseSenderAddressFromHead CreateUser);
+use strict;
+use warnings;
# This is what the ordinary, non-enhanced gateway does at the moment.
@@ -174,9 +176,6 @@ sub GetCurrentUser {
return ( $CurrentUser, 1 );
}
-eval "require RT::Interface::Email::Auth::MailFrom_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/MailFrom_Vendor.pm});
-eval "require RT::Interface::Email::Auth::MailFrom_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/MailFrom_Local.pm});
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm b/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm
index 6e99fec0b..0470e6340 100644
--- a/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm
+++ b/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm
@@ -47,6 +47,8 @@
# END BPS TAGGED BLOCK }}}
package RT::Interface::Email::Filter::SpamAssassin;
+use strict;
+use warnings;
use Mail::SpamAssassin;
my $spamtest = Mail::SpamAssassin->new();
@@ -90,9 +92,6 @@ the floor; otherwise, it is passed on as normal.
=cut
-eval "require RT::Interface::Email::Filter::SpamAssassin_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Filter/SpamAssassin_Vendor.pm});
-eval "require RT::Interface::Email::Filter::SpamAssassin_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Filter/SpamAssassin_Local.pm});
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/REST.pm b/rt/lib/RT/Interface/REST.pm
index ae1d6ad1e..7f6c9ac54 100644
--- a/rt/lib/RT/Interface/REST.pm
+++ b/rt/lib/RT/Interface/REST.pm
@@ -51,13 +51,14 @@
package RT::Interface::REST;
use strict;
+use warnings;
use RT;
BEGIN {
use base 'Exporter';
use vars qw($VERSION @EXPORT);
- $VERSION = do { my @r = (q$Revision: 1.1.1.9 $ =~ /\d+/g); sprintf "%d."."%02d"x$#r, @r };
+ $VERSION = do { my @r = (q$Revision: 1.1.1.10 $ =~ /\d+/g); sprintf "%d."."%02d"x$#r, @r };
@EXPORT = qw(expand_list form_parse form_compose vpush vsplit);
}
@@ -160,8 +161,8 @@ sub form_parse {
pop @v while (@v && $v[-1] eq '');
# Strip longest common leading indent from text.
- my ($ws, $ls) = ("");
- foreach $ls (map {/^(\s+)/} @v[1..$#v]) {
+ my $ws = ("");
+ foreach my $ls (map {/^(\s+)/} @v[1..$#v]) {
$ws = $ls if (!$ws || length($ls) < length($ws));
}
s/^$ws// foreach @v;
@@ -189,8 +190,7 @@ sub form_parse {
}
push(@forms, [ $c, $o, $k, $e ]) if ($e || $c || @$o);
- my $l;
- foreach $l (keys %$k) {
+ foreach my $l (keys %$k) {
$k->{$l} = vsplit($k->{$l}) if (ref $k->{$l} eq 'ARRAY');
}
@@ -202,7 +202,7 @@ sub form_compose {
my ($forms) = @_;
my (@text, $form);
- foreach $form (@$forms) {
+ foreach my $form (@$forms) {
my ($c, $o, $k, $e) = @$form;
my $text = "";
@@ -216,7 +216,7 @@ sub form_compose {
elsif ($o) {
my (@lines, $key);
- foreach $key (@$o) {
+ foreach my $key (@$o) {
my ($line, $sp, $v);
my @values = (ref $k->{$key} eq 'ARRAY') ?
@{ $k->{$key} } :
@@ -225,7 +225,7 @@ sub form_compose {
$sp = " "x(length("$key: "));
$sp = " "x4 if length($sp) > 16;
- foreach $v (@values) {
+ foreach my $v (@values) {
$v = '' unless defined $v;
if ( $v =~ /\n/) {
$v =~ s/^/$sp/gm;
@@ -293,9 +293,9 @@ sub vpush {
# "Normalise" a hash key that's known to be multi-valued.
sub vsplit {
my ($val) = @_;
- my ($line, $word, @words);
+ my @words;
- foreach $line (map {split /\n/} (ref $val eq 'ARRAY') ? @$val : ($val||''))
+ foreach my $line (map {split /\n/} (ref $val eq 'ARRAY') ? @$val : ($val||''))
{
# XXX: This should become a real parser, ? la Text::ParseWords.
$line =~ s/^\s+//;
@@ -306,15 +306,7 @@ sub vsplit {
return \@words;
}
-eval "require RT::Interface::REST_Vendor";
-if ($@ && $@ !~ qr{^Can't locate RT/Interface/REST_Vendor.pm}) {
- die $@;
-};
-
-eval "require RT::Interface::REST_Local";
-if ($@ && $@ !~ qr{^Can't locate RT/Interface/REST_Local.pm}) {
- die $@;
-};
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm
index ca357a31f..f56abb362 100644
--- a/rt/lib/RT/Interface/Web.pm
+++ b/rt/lib/RT/Interface/Web.pm
@@ -195,6 +195,8 @@ sub HandleRequest {
# Process session-related callbacks before any auth attempts
$HTML::Mason::Commands::m->callback( %$ARGS, CallbackName => 'Session', CallbackPage => '/autohandler' );
+ MaybeRejectPrivateComponentRequest();
+
MaybeShowNoAuthPage($ARGS);
AttemptExternalAuth($ARGS) if RT->Config->Get('WebExternalAuthContinuous') or not _UserLoggedIn();
@@ -412,6 +414,37 @@ sub MaybeShowNoAuthPage {
$m->abort;
}
+=head2 MaybeRejectPrivateComponentRequest
+
+This function will reject calls to private components, like those under
+C</Elements>. If the requested path is a private component then we will
+abort with a C<403> error.
+
+=cut
+
+sub MaybeRejectPrivateComponentRequest {
+ my $m = $HTML::Mason::Commands::m;
+ my $path = $m->request_comp->path;
+
+ # We do not check for dhandler here, because requesting our dhandlers
+ # directly is okay. Mason will invoke the dhandler with a dhandler_arg of
+ # 'dhandler'.
+
+ if ($path =~ m{
+ / # leading slash
+ ( Elements |
+ _elements | # mobile UI
+ Widgets |
+ autohandler | # requesting this directly is suspicious
+ l ) # loc component
+ ( $ | / ) # trailing slash or end of path
+ }xi) {
+ $m->abort(403);
+ }
+
+ return;
+}
+
=head2 ShowRequestedPage \%ARGS
This function, called exclusively by RT's autohandler, dispatches
@@ -796,8 +829,15 @@ sub SendStaticFile {
}
$type ||= "application/octet-stream";
}
+
+ # CGI.pm version 3.51 and 3.52 bang charset=iso-8859-1 onto our JS
+ # since we don't specify a charset
+ if ( $type =~ m{application/javascript} &&
+ $type !~ m{charset=([\w-]+)$} ) {
+ $type .= "; charset=utf-8";
+ }
$HTML::Mason::Commands::r->content_type($type);
- open my $fh, "<$file" or die "couldn't open file: $!";
+ open( my $fh, '<', $file ) or die "couldn't open file: $!";
binmode($fh);
{
local $/ = \16384;
@@ -841,8 +881,13 @@ sub StripContent {
# Check for plaintext sig
return '' if not $html and $content =~ /^(--)?\Q$sig\E$/;
- # Check for html-formatted sig
- RT::Interface::Web::EscapeUTF8( \$sig );
+ # Check for html-formatted sig; we don't use EscapeUTF8 here
+ # because we want to precisely match the escaping that FCKEditor
+ # uses. see also 311223f5, which fixed this for 4.0
+ $sig =~ s/&/&amp;/g;
+ $sig =~ s/</&lt;/g;
+ $sig =~ s/>/&gt;/g;
+
return ''
if $html
and $content =~ m{^(?:<p>)?(--)?\Q$sig\E(?:</p>)?$}s;
@@ -2254,9 +2299,6 @@ sub _parse_saved_search {
return ( _load_container_object( $obj_type, $obj_id ), $search_id );
}
-eval "require RT::Interface::Web_Vendor";
-die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Web_Vendor.pm} );
-eval "require RT::Interface::Web_Local";
-die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Web_Local.pm} );
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Web/Handler.pm b/rt/lib/RT/Interface/Web/Handler.pm
index 772fab0ca..4bb648451 100644
--- a/rt/lib/RT/Interface/Web/Handler.pm
+++ b/rt/lib/RT/Interface/Web/Handler.pm
@@ -260,6 +260,11 @@ sub CleanupRequest {
%RT::Ticket::MERGE_CACHE = ( effective => {}, merged => {} );
+ # RT::System persists between requests, so its attributes cache has to be
+ # cleared manually. Without this, for example, subject tags across multiple
+ # processes will remain cached incorrectly
+ delete $RT::System->{attributes};
+
# Explicitly remove any tmpfiles that GPG opened, and close their
# filehandles.
File::Temp::cleanup;
diff --git a/rt/lib/RT/Interface/Web/Menu/Item.pm b/rt/lib/RT/Interface/Web/Menu/Item.pm
index 5d8e67528..29fb13bcc 100644
--- a/rt/lib/RT/Interface/Web/Menu/Item.pm
+++ b/rt/lib/RT/Interface/Web/Menu/Item.pm
@@ -47,7 +47,8 @@
# END BPS TAGGED BLOCK }}}
package RT::Interface::Web::Menu::Item;
-
+use strict;
+use warnings;
sub new {
my $class = shift;
diff --git a/rt/lib/RT/Interface/Web/QueryBuilder.pm b/rt/lib/RT/Interface/Web/QueryBuilder.pm
index 6e462ec6f..09b95398c 100755
--- a/rt/lib/RT/Interface/Web/QueryBuilder.pm
+++ b/rt/lib/RT/Interface/Web/QueryBuilder.pm
@@ -51,9 +51,6 @@ package RT::Interface::Web::QueryBuilder;
use strict;
use warnings;
-eval "require RT::Interface::Web::QueryBuilder_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Vendor.pm});
-eval "require RT::Interface::Web::QueryBuilder_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Local.pm});
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
index f804e0968..493ab444d 100755
--- a/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
+++ b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
@@ -285,9 +285,6 @@ sub ParseSQL {
return @results;
}
-eval "require RT::Interface::Web::QueryBuilder::Tree_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Vendor.pm});
-eval "require RT::Interface::Web::QueryBuilder::Tree_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Local.pm});
+RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Interface/Web/Standalone.pm b/rt/lib/RT/Interface/Web/Standalone.pm
index 91dbac33b..3157e315e 100755
--- a/rt/lib/RT/Interface/Web/Standalone.pm
+++ b/rt/lib/RT/Interface/Web/Standalone.pm
@@ -77,6 +77,15 @@ sub handle_request {
Module::Refresh->refresh if RT->Config->Get('DevelMode');
RT::ConnectToDatabase() unless RT->InstallMode;
+
+ # Each environment has its own way of handling .. and so on in paths,
+ # so RT consistently forbids such paths.
+ if ( $cgi->path_info =~ m{/\.} ) {
+ $RT::Logger->crit("Invalid request for ".$cgi->path_info." aborting");
+ print STDOUT "HTTP/1.0 400\r\n\r\n";
+ return RT::Interface::Web::Handler->CleanupRequest();
+ }
+
$self->SUPER::handle_request($cgi);
$RT::Logger->crit($@) if $@ && $RT::Logger;
warn $@ if $@ && !$RT::Logger;