[freeside-commits] freeside/rt/lib/RT Action.pm, 1.3, 1.4 Condition.pm, 1.3, 1.4 Config.pm, 1.8, 1.9 CustomField.pm, 1.3, 1.4 Date.pm, 1.5, 1.6 Principal_Overlay.pm, 1.3, 1.4 Record.pm, 1.10, 1.11 SearchBuilder.pm, 1.9, 1.10 System.pm, 1.3, 1.4 Test.pm, 1.3, 1.4 Ticket_Overlay.pm, 1.19, 1.20 Tickets_Overlay.pm, 1.13, 1.14 User_Overlay.pm, 1.7, 1.8 Users_Overlay.pm, 1.6, 1.7

Ivan,,, ivan at wavetail.420.am
Mon Apr 18 16:49:56 PDT 2011


Update of /home/cvs/cvsroot/freeside/rt/lib/RT
In directory wavetail.420.am:/tmp/cvs-serv2120/lib/RT

Modified Files:
	Action.pm Condition.pm Config.pm CustomField.pm Date.pm 
	Principal_Overlay.pm Record.pm SearchBuilder.pm System.pm 
	Test.pm Ticket_Overlay.pm Tickets_Overlay.pm User_Overlay.pm 
	Users_Overlay.pm 
Log Message:
commiting rt 3.8.10 to HEAD

Index: SearchBuilder.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/SearchBuilder.pm,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -w -d -r1.9 -r1.10
--- SearchBuilder.pm	17 Feb 2011 00:52:25 -0000	1.9
+++ SearchBuilder.pm	18 Apr 2011 23:49:54 -0000	1.10
@@ -85,6 +85,17 @@
     $self->SUPER::_Init( 'Handle' => $RT::Handle);
 }
 
+sub OrderByCols {
+    my $self = shift;
+    my @sort;
+    for my $s (@_) {
+        next if defined $s->{FIELD} and $s->{FIELD} =~ /\W/;
+        $s->{FIELD} = $s->{FUNCTION} if $s->{FUNCTION};
+        push @sort, $s;
+    }
+    return $self->SUPER::OrderByCols( @sort );
+}
+
 =head2 LimitToEnabled
 
 Only find items that haven't been disabled
@@ -274,14 +285,47 @@
 making sure that by default lots of things don't do extra work trying to 
 match lower(colname) agaist lc($val);
 
+We also force VALUE to C<NULL> when the OPERATOR is C<IS> or C<IS NOT>.
+This ensures that we don't pass invalid SQL to the database or allow SQL
+injection attacks when we pass through user specified values.
+
 =cut
 
 sub Limit {
     my $self = shift;
-    my %args = ( CASESENSITIVE => 1,
-                 @_ );
+    my %ARGS = (
+        CASESENSITIVE => 1,
+        OPERATOR => '=',
+        @_,
+    );
 
-    return $self->SUPER::Limit(%args);
+    # We use the same regex here that DBIx::SearchBuilder uses to exclude
+    # values from quoting
+    if ( $ARGS{'OPERATOR'} =~ /IS/i ) {
+        # Don't pass anything but NULL for IS and IS NOT
+        $ARGS{'VALUE'} = 'NULL';
+    }
+
+    if ($ARGS{FUNCTION}) {
+        ($ARGS{ALIAS}, $ARGS{FIELD}) = split /\./, delete $ARGS{FUNCTION}, 2;
+        $self->SUPER::Limit(%ARGS);
+    } elsif ($ARGS{FIELD} =~ /\W/
+          or $ARGS{OPERATOR} !~ /^(=|<|>|!=|<>|<=|>=
+                                  |(NOT\s*)?LIKE
+                                  |(NOT\s*)?(STARTS|ENDS)WITH
+                                  |(NOT\s*)?MATCHES
+                                  |IS(\s*NOT)?
+                                  |IN)$/ix) {
+        $RT::Logger->crit("Possible SQL injection attack: $ARGS{FIELD} $ARGS{OPERATOR}");
+        $self->SUPER::Limit(
+            %ARGS,
+            FIELD    => 'id',
+            OPERATOR => '<',
+            VALUE    => '0',
+        );
+    } else {
+        $self->SUPER::Limit(%ARGS);
+    }
 }
 
 =head2 ItemsOrderBy
@@ -345,9 +389,6 @@
     return $self->SUPER::_DoCount(@_);
 }
 
-eval "require RT::SearchBuilder_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/SearchBuilder_Vendor.pm});
-eval "require RT::SearchBuilder_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/SearchBuilder_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;

Index: User_Overlay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/User_Overlay.pm,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -w -d -r1.7 -r1.8
--- User_Overlay.pm	17 Feb 2011 00:52:25 -0000	1.7
+++ User_Overlay.pm	18 Apr 2011 23:49:54 -0000	1.8
@@ -1807,7 +1807,7 @@
 
 }
 
-=head2 _CleanupInvalidDelegations { InsideTransaction => undef }
+=head2 CleanupInvalidDelegations { InsideTransaction => undef }
 
 Revokes all ACE entries delegated by this user which are inconsistent
 with their current delegation rights.  Does not perform permission
@@ -1821,12 +1821,15 @@
 
 =cut
 
-# XXX Currently there is a _CleanupInvalidDelegations method in both
+# XXX Currently there is a CleanupInvalidDelegations method in both
 # RT::User and RT::Group.  If the recursive cleanup call for groups is
 # ever unrolled and merged, this code will probably want to be
 # factored out into RT::Principal.
 
-sub _CleanupInvalidDelegations {
+# backcompat for 3.8.8 and before
+*_CleanupInvalidDelegations = \&CleanupInvalidDelegations;
+
+sub CleanupInvalidDelegations {
     my $self = shift;
     my %args = ( InsideTransaction => undef,
           @_ );

Index: Principal_Overlay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Principal_Overlay.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -d -r1.3 -r1.4
--- Principal_Overlay.pm	17 Feb 2011 00:52:25 -0000	1.3
+++ Principal_Overlay.pm	18 Apr 2011 23:49:54 -0000	1.4
@@ -220,9 +220,9 @@
 
 # }}}
 
-# {{{ sub _CleanupInvalidDelegations
+# {{{ sub CleanupInvalidDelegations
 
-=head2 sub _CleanupInvalidDelegations { InsideTransaction => undef }
+=head2 sub CleanupInvalidDelegations { InsideTransaction => undef }
 
 Revokes all ACE entries delegated by this principal which are
 inconsistent with this principal's current delegation rights.  Does
@@ -244,15 +244,19 @@
 # This is currently just a stub for the methods of the same name in
 # RT::User and RT::Group.
 
-sub _CleanupInvalidDelegations {
+# backcompat for 3.8.8 and before
+*_CleanupInvalidDelegations = \&CleanupInvalidDelegations;
+
+sub CleanupInvalidDelegations {
     my $self = shift;
     unless ( $self->Id ) {
 	$RT::Logger->warning("Principal not loaded.");
 	return (undef);
     }
-    return ($self->Object->_CleanupInvalidDelegations(@_));
+    return ($self->Object->CleanupInvalidDelegations(@_));
 }
 
+
 # }}}
 
 # {{{ sub HasRight

Index: Action.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Action.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -d -r1.3 -r1.4
--- Action.pm	17 Feb 2011 00:52:25 -0000	1.3
+++ Action.pm	18 Apr 2011 23:49:54 -0000	1.4
@@ -230,9 +230,6 @@
 
 # }}}
 
-eval "require RT::Action_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action_Vendor.pm});
-eval "require RT::Action_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;

Index: Date.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Date.pm,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -d -r1.5 -r1.6
--- Date.pm	15 Apr 2011 04:01:16 -0000	1.5
+++ Date.pm	18 Apr 2011 23:49:54 -0000	1.6
@@ -1099,9 +1099,6 @@
 }
 
 
-eval "require RT::Date_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Date_Vendor.pm});
-eval "require RT::Date_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Date_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;

Index: Record.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Record.pm,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -w -d -r1.10 -r1.11
--- Record.pm	17 Feb 2011 03:47:50 -0000	1.10
+++ Record.pm	18 Apr 2011 23:49:54 -0000	1.11
@@ -1988,9 +1988,6 @@
     return RT->Config->Get('WebPath'). "/index.html?q=";
 }
 
-eval "require RT::Record_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Record_Vendor.pm});
-eval "require RT::Record_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Record_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;

Index: Ticket_Overlay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Ticket_Overlay.pm,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -w -d -r1.19 -r1.20
--- Ticket_Overlay.pm	22 Feb 2011 00:25:15 -0000	1.19
+++ Ticket_Overlay.pm	18 Apr 2011 23:49:54 -0000	1.20
@@ -1014,15 +1014,14 @@
 
     $self->OwnerGroup->_AddMember( PrincipalId => $Owner->PrincipalId );
 
-    my $watcher;
-    foreach $watcher ( @{ $args{'Cc'} } ) {
+    foreach my $watcher ( @{ $args{'Cc'} } ) {
         $self->_AddWatcher( Type => 'Cc', Email => $watcher, Silent => 1 );
     }
-    foreach $watcher ( @{ $args{'AdminCc'} } ) {
+    foreach my $watcher ( @{ $args{'AdminCc'} } ) {
         $self->_AddWatcher( Type => 'AdminCc', Email => $watcher,
             Silent => 1 );
     }
-    foreach $watcher ( @{ $args{'Requestor'} } ) {
+    foreach my $watcher ( @{ $args{'Requestor'} } ) {
         $self->_AddWatcher( Type => 'Requestor', Email => $watcher,
             Silent => 1 );
     }

Index: Test.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Test.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -d -r1.3 -r1.4
--- Test.pm	17 Feb 2011 00:52:25 -0000	1.3
+++ Test.pm	18 Apr 2011 23:49:54 -0000	1.4
@@ -75,7 +75,7 @@
    };
 
 
-our @EXPORT = qw(is_empty);
+our @EXPORT = qw(is_empty parse_mail);
 our ($port, $dbname);
 our @SERVERS;
 
@@ -217,7 +217,7 @@
     $tmp{'config'}{'RT'} = File::Spec->catfile(
         "$tmp{'directory'}", 'RT_SiteConfig.pm'
     );
-    open my $config, '>', $tmp{'config'}{'RT'}
+    open( my $config, '>', $tmp{'config'}{'RT'} )
         or die "Couldn't open $tmp{'config'}{'RT'}: $!";
 
     print $config qq{
@@ -246,7 +246,7 @@
 Set( \$MailCommand, sub {
     my \$MIME = shift;
 
-    open my \$handle, '>>', '$mail_catcher'
+    open( my \$handle, '>>', '$mail_catcher' )
         or die "Unable to open '$mail_catcher' for appending: \$!";
 
     \$MIME->print(\$handle);
@@ -272,7 +272,7 @@
     $tmp{'log'}{'RT'} = File::Spec->catfile(
         "$tmp{'directory'}", 'rt.debug.log'
     );
-    open my $fh, '>', $tmp{'log'}{'RT'}
+    open( my $fh, '>', $tmp{'log'}{'RT'} )
         or die "Couldn't open $tmp{'config'}{'RT'}: $!";
     # make world writable so apache under different user
     # can write into it
@@ -303,7 +303,7 @@
                 SCALAR => '$',
             );
             my $sigil = $sigils{$type} || $sigils{'SCALAR'};
-            open my $fh, '>>', $tmp{'config'}{'RT'}
+            open( my $fh, '>>', $tmp{'config'}{'RT'} )
                 or die "Couldn't open config file: $!";
             require Data::Dumper;
             my $dump = Data::Dumper::Dumper([@_[2 .. $#_]]);
@@ -774,7 +774,7 @@
     my $baseurl = shift;
     my $queue   = shift || 'general';
     my $action  = shift || 'correspond';
-    Test::More::ok(open(my $mail, "|$RT::BinPath/rt-mailgate --url $baseurl --queue $queue --action $action"), "Opened the mailgate - $!");
+    Test::More::ok(open(my $mail, '|-', "$RT::BinPath/rt-mailgate --url $baseurl --queue $queue --action $action"), "Opened the mailgate - $!");
     return $mail;
 }
 
@@ -1072,7 +1072,7 @@
     my %info = $self->apache_server_info( variant => $variant );
 
     Test::More::diag(do {
-        open my $fh, '<', $tmp{'config'}{'RT'};
+        open( my $fh, '<', $tmp{'config'}{'RT'} ) or die $!;
         local $/;
         <$fh>
     });
@@ -1118,7 +1118,7 @@
         }
         Test::More::BAIL_OUT("Couldn't start apache server, no pid file")
             unless -e $opt{'pid_file'};
-        open my $pid_fh, '<', $opt{'pid_file'}
+        open( my $pid_fh, '<', $opt{'pid_file'} )
             or Test::More::BAIL_OUT("Couldn't open pid file: $!");
         my $pid = <$pid_fh>;
         chomp $pid;
@@ -1230,7 +1230,7 @@
 
     Test::More::diag "reading content of '$path'" if $ENV{'TEST_VERBOSE'};
 
-    open my $fh, "<:raw", $path
+    open( my $fh, "<:raw", $path )
         or do {
             warn "couldn't open file '$path': $!" unless $args{noexist};
             return ''
@@ -1289,7 +1289,7 @@
         ($out_fh, $out_conf) = tempfile();
     } else {
         $out_conf = $args{'out'};
-        open $out_fh, '>', $out_conf
+        open( $out_fh, '>', $out_conf )
             or die "couldn't open '$out_conf': $!";
     }
     print $out_fh $text;
@@ -1298,6 +1298,14 @@
     return ($out_fh, $out_conf);
 }
 
+sub parse_mail {
+    my $mail = shift;
+    require RT::EmailParser;
+    my $parser = RT::EmailParser->new;
+    $parser->ParseMIMEEntityFromScalar( $mail );
+    return $parser->Entity;
+}
+
 END {
     my $Test = RT::Test->builder;
     return if $Test->{Original_Pid} != $$;

Index: Users_Overlay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Users_Overlay.pm,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -w -d -r1.6 -r1.7
--- Users_Overlay.pm	17 Feb 2011 00:52:25 -0000	1.6
+++ Users_Overlay.pm	18 Apr 2011 23:49:54 -0000	1.7
@@ -406,6 +406,12 @@
     );
 
     my @objects = $self->_GetEquivObjects( %args );
+
+    # RT::Principal->RolesWithRight only expects EquivObjects, so we need to
+    # fill it.  At the very least it needs $args{Object}, which
+    # _GetEquivObjects above does for us.
+    unshift @{$args{'EquivObjects'}}, @objects;
+
     my @roles = RT::Principal->RolesWithRight( %args );
     unless ( @roles ) {
         $self->_AddSubClause( "WhichRole", "(main.id = 0)" );

Index: Condition.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Condition.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -d -r1.3 -r1.4
--- Condition.pm	17 Feb 2011 00:52:25 -0000	1.3
+++ Condition.pm	18 Apr 2011 23:49:54 -0000	1.4
@@ -238,9 +238,6 @@
 
 # }}}
 
-eval "require RT::Condition_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition_Vendor.pm});
-eval "require RT::Condition_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;

Index: System.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/System.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -d -r1.3 -r1.4
--- System.pm	17 Feb 2011 00:52:25 -0000	1.3
+++ System.pm	18 Apr 2011 23:49:54 -0000	1.4
@@ -211,9 +211,6 @@
     }
 }
 
-eval "require RT::System_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/System_Vendor.pm});
-eval "require RT::System_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/System_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;

Index: Config.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Config.pm,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -w -d -r1.8 -r1.9
--- Config.pm	17 Feb 2011 00:52:25 -0000	1.8
+++ Config.pm	18 Apr 2011 23:49:54 -0000	1.9
@@ -908,10 +908,11 @@
 sub Sections {
     my $self = shift;
     my %seen;
-    return sort
+    my @sections = sort
         grep !$seen{$_}++,
         map $_->{'Section'} || 'General',
         values %META;
+    return @sections;
 }
 
 sub Options {
@@ -940,14 +941,6 @@
     return @res;
 }
 
-eval "require RT::Config_Vendor";
-if ($@ && $@ !~ qr{^Can't locate RT/Config_Vendor.pm}) {
-    die $@;
-};
-
-eval "require RT::Config_Local";
-if ($@ && $@ !~ qr{^Can't locate RT/Config_Local.pm}) {
-    die $@;
-};
+RT::Base->_ImportOverlays();
 
 1;

Index: Tickets_Overlay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/Tickets_Overlay.pm,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -w -d -r1.13 -r1.14
--- Tickets_Overlay.pm	15 Apr 2011 04:01:17 -0000	1.13
+++ Tickets_Overlay.pm	18 Apr 2011 23:49:54 -0000	1.14
@@ -150,6 +150,13 @@
     Tagnum           => [ 'FREESIDEFIELD', 'cust_tag' ],
 );
 
+our %SEARCHABLE_SUBFIELDS = (
+    User => [qw(
+        EmailAddress Name RealName Nickname Organization Address1 Address2
+        WorkPhone HomePhone MobilePhone PagerPhone id
+    )],
+);
+
 # Mapping of Field Type to Function
 our %dispatch = (
     ENUM            => \&_EnumLimit,
@@ -837,6 +844,13 @@
     my $type = $meta->[1] || '';
     my $class = $meta->[2] || 'Ticket';
 
+    # Bail if the subfield is not allowed
+    if (    $rest{SUBKEY}
+        and not grep { $_ eq $rest{SUBKEY} } @{$SEARCHABLE_SUBFIELDS{'User'}})
+    {
+        die "Invalid watcher subfield: '$rest{SUBKEY}'";
+    }
+
     # Owner was ENUM field, so "Owner = 'xxx'" allowed user to
     # search by id and Name at the same time, this is workaround
     # to preserve backward compatibility
@@ -1235,7 +1249,7 @@
 sub _CustomFieldDecipher {
     my ($self, $string) = @_;
 
-    my ($queue, $field, $column) = ($string =~ /^(?:(.+?)\.)?{(.+)}(?:\.(.+))?$/);
+    my ($queue, $field, $column) = ($string =~ /^(?:(.+?)\.)?{(.+)}(?:\.(Content|LargeContent))?$/);
     $field ||= ($string =~ /^{(.*?)}$/)[0] || $string;
 
     my $cf;
@@ -1767,9 +1781,20 @@
            foreach my $uid ( $self->CurrentUser->Id, $RT::Nobody->Id ) {
                if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) {
                    my $f = ($row->{'ALIAS'} || 'main') .'.Owner';
-                   push @res, { %$row, ALIAS => '', FIELD => "CASE WHEN $f=$uid THEN 1 ELSE 0 END", ORDER => $order } ;
+                   push @res, {
+                       %$row,
+                       FIELD => undef,
+                       ALIAS => '',
+                       FUNCTION => "CASE WHEN $f=$uid THEN 1 ELSE 0 END",
+                       ORDER => $order
+                   };
                } else {
-                   push @res, { %$row, FIELD => "Owner=$uid", ORDER => $order } ;
+                   push @res, {
+                       %$row,
+                       FIELD => undef,
+                       FUNCTION => "Owner=$uid",
+                       ORDER => $order
+                   };
                }
            }
 
@@ -3300,9 +3325,9 @@
 sub DescribeRestrictions {
     my $self = shift;
 
-    my ( $row, %listing );
+    my %listing;
 
-    foreach $row ( keys %{ $self->{'TicketRestrictions'} } ) {
+    foreach my $row ( keys %{ $self->{'TicketRestrictions'} } ) {
         $listing{$row} = $self->{'TicketRestrictions'}{$row}{'DESCRIPTION'};
     }
     return (%listing);
@@ -3377,9 +3402,8 @@
 sub _RestrictionsToClauses {
     my $self = shift;
 
-    my $row;
     my %clause;
-    foreach $row ( keys %{ $self->{'TicketRestrictions'} } ) {
+    foreach my $row ( keys %{ $self->{'TicketRestrictions'} } ) {
         my $restriction = $self->{'TicketRestrictions'}{$row};
 
         # We need to reimplement the subclause aggregation that SearchBuilder does.

Index: CustomField.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/rt/lib/RT/CustomField.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -d -r1.3 -r1.4
--- CustomField.pm	17 Feb 2011 00:52:25 -0000	1.3
+++ CustomField.pm	18 Apr 2011 23:49:54 -0000	1.4
@@ -388,24 +388,7 @@
  }
 };
 
-
-        eval "require RT::CustomField_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/CustomField_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::CustomField_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/CustomField_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::CustomField_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/CustomField_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 



More information about the freeside-commits mailing list