[Rt-commit] r6054 - in rt/branches/3.6-RELEASE: . html/Ticket/Elements lib/RT lib/RT/Interface lib/RT/Interface/Email/Auth

ruz at bestpractical.com ruz at bestpractical.com
Tue Sep 26 20:33:00 EDT 2006


Author: ruz
Date: Tue Sep 26 20:32:59 2006
New Revision: 6054

Modified:
   rt/branches/3.6-RELEASE/   (props changed)
   rt/branches/3.6-RELEASE/html/Elements/EditCustomFieldSelect
   rt/branches/3.6-RELEASE/html/Ticket/Elements/EditCustomFields
   rt/branches/3.6-RELEASE/lib/RT/Interface/Email/Auth/MailFrom.pm
   rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm
   rt/branches/3.6-RELEASE/lib/RT/Record.pm
   rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm

Log:
merge 3.4 -> QUEBEC -> CHALDEA -> 3.6

 r3890 at cubic-pc (orig r6053):  ruz | 2006-09-27 04:31:42 +0400
 merge QUEBEC -> CHALDEA
 
  r3883 at cubic-pc (orig r6046):  ruz | 2006-09-27 03:29:31 +0400
   r3671 at cubic-pc (orig r5829):  ruz | 2006-08-31 00:12:48 +0400
   * typo
  
  r3884 at cubic-pc (orig r6047):  ruz | 2006-09-27 03:29:39 +0400
   r3694 at cubic-pc (orig r5849):  ruz | 2006-09-04 20:32:29 +0400
   * drop unused variable
   * init index($i) with 0 to avoid warnings
  
  r3885 at cubic-pc (orig r6048):  ruz | 2006-09-27 03:29:51 +0400
   r3695 at cubic-pc (orig r5850):  ruz | 2006-09-04 20:49:12 +0400
   * drop uninit warning
  
  r3886 at cubic-pc (orig r6049):  ruz | 2006-09-27 04:15:12 +0400
   r3696 at cubic-pc (orig r5856):  ruz | 2006-09-04 23:17:14 +0400
   * split function ProcessObjectCustomFieldUpdates into two
   * call RedoSearch on object's custom fields values collection
     after {Add,Delete}CustomFieldValues operations
  
  r3887 at cubic-pc (orig r6050):  ruz | 2006-09-27 04:15:22 +0400
   r3697 at cubic-pc (orig r5857):  ruz | 2006-09-04 23:30:28 +0400
   * redo search if we have deleted entries in collection
  
  r3888 at cubic-pc (orig r6051):  ruz | 2006-09-27 04:15:29 +0400
   r3698 at cubic-pc (orig r5858):  ruz | 2006-09-05 02:09:30 +0400
   ::OldValue and ::NewValue
   * don't load object if {Old,New}Reference is false value
   ** this is hitting some cache issues and could return "random" result
      which brakes tickets' history.
   
   Thanks to Joshua Speicher.
   
  
  r3889 at cubic-pc (orig r6052):  ruz | 2006-09-27 04:15:58 +0400
   r3759 at cubic-pc (orig r5943):  jesse | 2006-09-15 23:31:25 +0400
    r27507 at pinglin:  jesse | 2006-09-15 20:30:47 +0100
    [mail gateway] Todd Chapman discovered a case where RT's mail gateway would default to the RT::SystemUser if no valid from header were found. This could allow a malicious user to create tickets or reply to tickets, but not to gain access to data.
    
    
   
  
 


Modified: rt/branches/3.6-RELEASE/html/Elements/EditCustomFieldSelect
==============================================================================
--- rt/branches/3.6-RELEASE/html/Elements/EditCustomFieldSelect	(original)
+++ rt/branches/3.6-RELEASE/html/Elements/EditCustomFieldSelect	Tue Sep 26 20:32:59 2006
@@ -106,7 +106,7 @@
 %     }
         <option value="<%$value->Name%>" 
 % if ($Values) {
-            <% $Values->HasEntry($value->Name) && ($$SelectedRef = 1) && 'SELECTED' %>
+            <% ($Values->HasEntry($value->Name)||'') && ($$SelectedRef = 1) && 'SELECTED' %>
 % } elsif ($Default) {
             <% (ref $Default ? (grep {$_ eq $value->Name} @{$Default}) : ($Default eq $value->Name))
                 && ($$SelectedRef = 1) && 'SELECTED' %>

Modified: rt/branches/3.6-RELEASE/html/Ticket/Elements/EditCustomFields
==============================================================================
--- rt/branches/3.6-RELEASE/html/Ticket/Elements/EditCustomFields	(original)
+++ rt/branches/3.6-RELEASE/html/Ticket/Elements/EditCustomFields	Tue Sep 26 20:32:59 2006
@@ -48,8 +48,7 @@
 <td valign="top" width="50%">
 <table>
 
-% my @entry_fields;
-% my $i;
+% my $i = 0;
 % my $cfcount = $CustomFields->Count;
 %  $cfcount++ if ($cfcount % 2) ; # if we have an odd number of 
 % #custom fields, fudge it so we know where to put in the table break

Modified: rt/branches/3.6-RELEASE/lib/RT/Interface/Email/Auth/MailFrom.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Interface/Email/Auth/MailFrom.pm	(original)
+++ rt/branches/3.6-RELEASE/lib/RT/Interface/Email/Auth/MailFrom.pm	Tue Sep 26 20:32:59 2006
@@ -60,6 +60,11 @@
 
     # We don't need to do any external lookups
     my ( $Address, $Name ) = ParseSenderAddressFromHead( $args{'Message'}->head );
+
+    unless ($Address) {
+        return ( $args{'CurrentUser'}, -1 );
+    }
+
     my $CurrentUser = RT::CurrentUser->new();
     $CurrentUser->LoadByEmail($Address);
 

Modified: rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm	(original)
+++ rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm	Tue Sep 26 20:32:59 2006
@@ -1193,161 +1193,174 @@
     # Build up a list of objects that we want to work with
     my %custom_fields_to_mod;
     foreach my $arg ( keys %$ARGSRef ) {
-        if ( $arg =~ /^Object-([\w:]+)-(\d*)-CustomField-(\d+)-/ ) {
-            # For each of those objects, find out what custom fields we want to work with.
-            $custom_fields_to_mod{$1}{$2 || $args{'Object'}->Id}{$3} = 1;
-        }
+        # format: Object-<object class>-<object id>-CustomField-<CF id>-<commands>
+        next unless $arg =~ /^Object-([\w:]+)-(\d*)-CustomField-(\d+)-(.*)$/;
+
+        # For each of those objects, find out what custom fields we want to work with.
+        $custom_fields_to_mod{ $1 }{ $2 || 0 }{ $3 }{ $4 } = $ARGSRef->{ $arg };
     }
 
     # For each of those objects
     foreach my $class ( keys %custom_fields_to_mod ) {
         foreach my $id ( keys %{$custom_fields_to_mod{$class}} ) {
             my $Object = $args{'Object'};
-            if (!$Object or ref($Object) ne $class or $Object->id != $id) {
-                $Object = $class->new( $session{'CurrentUser'} );
-                $Object->Load($id);
-            }
-
-            # For each custom field  
-            foreach my $cf ( keys %{ $custom_fields_to_mod{$class}{$id} } ) {
-                my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
-                $CustomFieldObj->LoadById($cf);
-
-                foreach my $arg ( keys %{$ARGSRef} ) {
-                    # Only interested in args for the current CF:
-                    next unless ( $arg =~ /^Object-$class-(?:$id)?-CustomField-$cf-/ );
-
-                    # since http won't pass in a form element with a null value, we need
-                    # to fake it
-                    if ($arg =~ /^(.*?)-Values-Magic$/ ) {
-                        # We don't care about the magic, if there's really a values element;
-                        next if ($ARGSRef->{$1.'-Value'} || $ARGSRef->{$1.'-Values'}) ;
-
-                        # "Empty" values does not mean anything for Image and Binary fields
-                        next if $CustomFieldObj->Type =~ /^(?:Image|Binary)$/;
-
-                        $arg = $1."-Values";
-                        $ARGSRef->{$1."-Values"} = undef;
-                    
-                    }
-                    my @values = ();
-                    if (ref( $ARGSRef->{$arg} ) eq 'ARRAY' ) {
-                        @values = @{ $ARGSRef->{$arg} };
-                    } elsif ($CustomFieldObj->Type =~ /text/i) { # Both Text and Wikitext
-                        @values = ($ARGSRef->{$arg});
-                    } else {
-                        @values = split /\n/, $ARGSRef->{$arg};
-                    }
-                    
-                    if ( ($CustomFieldObj->Type eq 'Freeform' 
-                          && ! $CustomFieldObj->SingleValue) ||
-                          $CustomFieldObj->Type =~ /text/i) {
-                        foreach my $val (@values) {
-                            $val =~ s/\r//g;
-                        }
-                    }
-
-                    if ( ( $arg =~ /-AddValue$/ ) || ( $arg =~ /-Value$/ ) ) {
-                        foreach my $value (@values) {
-                            next unless length($value);
-                            my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                                Field => $cf,
-                                Value => $value
-                            );
-                            push ( @results, $msg );
-                        }
-                    }
-                    elsif ( $arg =~ /-Upload$/ ) {
-                        my $value_hash = _UploadedFile($arg) or next;
-
-                        my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                            %$value_hash,
-                            Field => $cf,
-                        );
-                        push ( @results, $msg );
-                    }
-                    elsif ( $arg =~ /-DeleteValues$/ ) {
-                        foreach my $value (@values) {
-                            next unless length($value);
-                            my ( $val, $msg ) = $Object->DeleteCustomFieldValue(
-                                Field => $cf,
-                                Value => $value
-                            );
-                            push ( @results, $msg );
-                        }
-                    }
-                    elsif ( $arg =~ /-DeleteValueIds$/ ) {
-                        foreach my $value (@values) {
-                            next unless length($value);
-                            my ( $val, $msg ) = $Object->DeleteCustomFieldValue(
-                                Field => $cf,
-                                ValueId => $value,
-                            );
-                            push ( @results, $msg );
-                        }
-                    }
-                    elsif ( $arg =~ /-Values$/ and !$CustomFieldObj->Repeated) {
-                        my $cf_values = $Object->CustomFieldValues($cf);
-
-                        my %values_hash;
-                        foreach my $value (@values) {
-                            next unless length($value);
-
-                            # build up a hash of values that the new set has
-                            $values_hash{$value} = 1;
-
-                            unless ( $cf_values->HasEntry($value) ) {
-                                my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                                    Field => $cf,
-                                    Value => $value
-                                );
-                                push ( @results, $msg );
-                            }
-
-                        }
-                        while ( my $cf_value = $cf_values->Next ) {
-                            unless ( $values_hash{ $cf_value->Content } == 1 ) {
-                                my ( $val, $msg ) = $Object->DeleteCustomFieldValue(
-                                    Field => $cf,
-                                    Value => $cf_value->Content
-                                );
-                                push ( @results, $msg);
-
-                            }
-                        }
-                    }
-                    elsif ( $arg =~ /-Values$/ ) {
-                        my $cf_values = $Object->CustomFieldValues($cf);
-
-                        # keep everything up to the point of difference, delete the rest
-                        my $delete_flag;
-                        foreach my $old_cf (@{$cf_values->ItemsArrayRef}) {
-                            if (!$delete_flag and @values and $old_cf->Content eq $values[0]) {
-                                shift @values;
-                                next;
-                            }
-
-                            $delete_flag ||= 1;
-                            $old_cf->Delete;
-                        }
-
-                        # now add/replace extra things, if any
-                        foreach my $value (@values) {
-                            my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                                Field => $cf,
-                                Value => $value
-                            );
-                            push ( @results, $msg );
-                        }
-                    }
-                    else {
-                        push ( @results, loc("User asked for an unknown update type for custom field [_1] for [_2] object #[_3]", $CustomFieldObj->Name, $class, $Object->id ) );
-                    }
+            $Object = $class->new( $session{'CurrentUser'} )
+                unless $Object && ref $Object eq $class;
+
+            $Object->Load( $id ) unless ($Object->id || 0) == $id;
+            unless ( $Object->id ) {
+                $RT::Logger->warning("Couldn't load object $class #$id");
+                next;
+            }
+
+            foreach my $cf ( keys %{ $custom_fields_to_mod{ $class }{ $id } } ) {
+                my $CustomFieldObj = RT::CustomField->new( $session{'CurrentUser'} );
+                $CustomFieldObj->LoadById( $cf );
+                unless ( $CustomFieldObj->id ) {
+                    $RT::Logger->warning("Couldn't load custom field #$id");
+                    next;
                 }
+                push @results, _ProcessObjectCustomFieldUpdates(
+                    Prefix      => "Object-$class-$id-CustomField-$cf-",
+                    Object      => $Object,
+                    CustomField => $CustomFieldObj,
+                    ARGS        => $custom_fields_to_mod{$class}{$id}{$cf},
+                );
             }
-            return (@results);
         }
     }
+    return @results;
+}
+
+sub _ProcessObjectCustomFieldUpdates {
+    my %args = @_;
+    my $cf = $args{'CustomField'};
+    my $cf_type = $cf->Type;
+
+    my @results;
+    foreach my $arg ( keys %{ $args{'ARGS'} } ) {
+
+        # since http won't pass in a form element with a null value, we need
+        # to fake it
+        if ( $arg eq 'Values-Magic' ) {
+            # We don't care about the magic, if there's really a values element;
+            next if $args{'ARGS'}->{'Value'} || $args{'ARGS'}->{'Values'};
+
+            # "Empty" values does not mean anything for Image and Binary fields
+            next if $cf_type =~ /^(?:Image|Binary)$/;
+
+            $arg = 'Values';
+            $args{'ARGS'}->{'Values'} = undef;
+        }
+
+        my @values = ();
+        if ( ref $args{'ARGS'}->{ $arg } eq 'ARRAY' ) {
+            @values = @{ $args{'ARGS'}->{$arg} };
+        } elsif ( $cf_type =~ /text/i ) { # Both Text and Wikitext
+            @values = ($args{'ARGS'}->{$arg});
+        } else {
+            @values = split /\n/, $args{'ARGS'}->{ $arg };
+        }
+        
+        if ( ( $cf_type eq 'Freeform' && !$cf->SingleValue ) || $cf_type =~ /text/i ) {
+            s/\r//g foreach @values;
+        }
+        @values = grep defined && $_ ne '', @values;
+
+        if ( $arg eq 'AddValue' || $arg eq 'Value' ) {
+            foreach my $value (@values) {
+                my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                    Field => $cf->id,
+                    Value => $value
+                );
+                push ( @results, $msg );
+            }
+        }
+        elsif ( $arg eq 'Upload' ) {
+            my $value_hash = _UploadedFile( $args{'Prefix'} . $arg ) or next;
+            my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                %$value_hash,
+                Field => $cf,
+            );
+            push ( @results, $msg );
+        }
+        elsif ( $arg eq 'DeleteValues' ) {
+            foreach my $value ( @values ) {
+                my ( $val, $msg ) = $args{'Object'}->DeleteCustomFieldValue(
+                    Field => $cf,
+                    Value => $value,
+                );
+                push ( @results, $msg );
+            }
+        }
+        elsif ( $arg eq 'DeleteValueIds' ) {
+            foreach my $value ( @values ) {
+                my ( $val, $msg ) = $args{'Object'}->DeleteCustomFieldValue(
+                    Field   => $cf,
+                    ValueId => $value,
+                );
+                push ( @results, $msg );
+            }
+        }
+        elsif ( $arg eq 'Values' && !$cf->Repeated ) {
+            my $cf_values = $args{'Object'}->CustomFieldValues( $cf->id );
+
+            my %values_hash;
+            foreach my $value ( @values ) {
+                # build up a hash of values that the new set has
+                $values_hash{$value} = 1;
+                next if $cf_values->HasEntry( $value );
+
+                my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                    Field => $cf,
+                    Value => $value
+                );
+                push ( @results, $msg );
+            }
+
+            $cf_values->RedoSearch;
+            while ( my $cf_value = $cf_values->Next ) {
+                next if $values_hash{ $cf_value->Content };
+
+                my ( $val, $msg ) = $args{'Object'}->DeleteCustomFieldValue(
+                    Field => $cf,
+                    Value => $cf_value->Content
+                );
+                push ( @results, $msg);
+            }
+        }
+        elsif ( $arg eq 'Values' ) {
+            my $cf_values = $args{'Object'}->CustomFieldValues( $cf->id );
+
+            # keep everything up to the point of difference, delete the rest
+            my $delete_flag;
+            foreach my $old_cf (@{$cf_values->ItemsArrayRef}) {
+                if (!$delete_flag and @values and $old_cf->Content eq $values[0]) {
+                    shift @values;
+                    next;
+                }
+
+                $delete_flag ||= 1;
+                $old_cf->Delete;
+            }
+
+            # now add/replace extra things, if any
+            foreach my $value ( @values ) {
+                my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                    Field => $cf,
+                    Value => $value
+                );
+                push ( @results, $msg );
+            }
+        }
+        else {
+            push ( @results,
+                loc("User asked for an unknown update type for custom field [_1] for [_2] object #[_3]",
+                $cf->Name, ref $args{'Object'}, $args{'Object'}->id )
+            );
+        }
+    }
+    return @results;
 }
 
 # {{{ sub ProcessTicketWatchers

Modified: rt/branches/3.6-RELEASE/lib/RT/Record.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Record.pm	(original)
+++ rt/branches/3.6-RELEASE/lib/RT/Record.pm	Tue Sep 26 20:32:59 2006
@@ -1640,10 +1640,11 @@
                       );
                 }
             }
+            $values->RedoSearch if $i; # redo search if have deleted at least one value
         }
 
         my ( $old_value, $old_content );
-        if ( $old_value = $cf->ValuesForObject($self)->First ) {
+        if ( $old_value = $values->First ) {
             $old_content = $old_value->Content();
             return (1) if( $old_content eq $args{'Value'} && $old_value->LargeContent eq $args{'LargeContent'});;
         }

Modified: rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm	(original)
+++ rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm	Tue Sep 26 20:32:59 2006
@@ -966,25 +966,29 @@
 
 sub OldValue {
     my $self = shift;
-    if (my $type = $self->__Value('ReferenceType')) {
-	my $Object = $type->new($self->CurrentUser);
-	$Object->Load($self->__Value('OldReference'));
-	return $Object->Content;
+    if ( my $type = $self->__Value('ReferenceType')
+         and my $id = $self->__Value('OldReference') )
+    {
+        my $Object = $type->new($self->CurrentUser);
+        $Object->Load( $id );
+        return $Object->Content;
     }
     else {
-	return $self->__Value('OldValue');
+        return $self->__Value('OldValue');
     }
 }
 
 sub NewValue {
     my $self = shift;
-    if (my $type = $self->__Value('ReferenceType')) {
-	my $Object = $type->new($self->CurrentUser);
-	$Object->Load($self->__Value('NewReference'));
-	return $Object->Content;
+    if ( my $type = $self->__Value('ReferenceType')
+         and my $id = $self->__Value('NewReference') )
+    {
+        my $Object = $type->new($self->CurrentUser);
+        $Object->Load( $id );
+        return $Object->Content;
     }
     else {
-	return $self->__Value('NewValue');
+        return $self->__Value('NewValue');
     }
 }
 


More information about the Rt-commit mailing list