X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FEmailParser.pm;h=8c4c0f1148058c1b7043fbf31595b3cc98515276;hb=5372897f367498972c96f5494e142e6e11b29eb8;hp=89f7ea4f923021638f593b310c614349af55fb50;hpb=e9e0cf0989259b94d9758eceff448666a2e5a5cc;p=freeside.git diff --git a/rt/lib/RT/EmailParser.pm b/rt/lib/RT/EmailParser.pm index 89f7ea4f9..8c4c0f114 100644 --- a/rt/lib/RT/EmailParser.pm +++ b/rt/lib/RT/EmailParser.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -122,10 +122,9 @@ sub SmartParseMIMEEntityFromScalar { close($fh); if ( -f $temp_file ) { - # We have to trust the temp file's name -- untaint it - $temp_file =~ /(.*)/; - my $entity = $self->ParseMIMEEntityFromFile( $1, $args{'Decode'}, $args{'Exact'} ); - unlink($1); + my $entity = $self->ParseMIMEEntityFromFile( $temp_file, $args{'Decode'}, $args{'Exact'} ); + unlink($temp_file) + or RT->Logger->error("Unable to delete temp file $temp_file, error: $!"); return $entity; } } @@ -299,8 +298,8 @@ sub ParseCcAddressesFromHead { my (@Addresses); - my @ToObjs = Email::Address->parse( $self->Head->get('To') ); - my @CcObjs = Email::Address->parse( $self->Head->get('Cc') ); + my @ToObjs = Email::Address->parse( Encode::decode( "UTF-8", $self->Head->get('To') ) ); + my @CcObjs = Email::Address->parse( Encode::decode( "UTF-8", $self->Head->get('Cc') ) ); foreach my $AddrObj ( @ToObjs, @CcObjs ) { my $Address = $AddrObj->address; @@ -328,6 +327,8 @@ sub IsRTAddress { my $self = shift; my $address = shift; + return undef unless defined($address) and $address =~ /\S/; + if ( my $address_re = RT->Config->Get('RTAddressRegexp') ) { return $address =~ /$address_re/i ? 1 : undef; } @@ -526,30 +527,45 @@ we can use that removes the bandaid =cut +use Email::Address::List; + sub ParseEmailAddress { my $self = shift; my $address_string = shift; - $address_string =~ s/^\s+|\s+$//g; + my @list = Email::Address::List->parse( + $address_string, + skip_comments => 1, + skip_groups => 1, + ); + my $logger = sub { RT->Logger->error( + "Unable to parse an email address from $address_string: ". shift + ) }; my @addresses; - # if it looks like a username / local only email - if ($address_string !~ /@/ && $address_string =~ /^\w+$/) { - my $user = RT::User->new( RT->SystemUser ); - my ($id, $msg) = $user->Load($address_string); - if ($id) { - push @addresses, Email::Address->new($user->Name,$user->EmailAddress); + foreach my $e ( @list ) { + if ($e->{'type'} eq 'mailbox') { + if ($e->{'not_ascii'}) { + $logger->($e->{'value'} ." contains not ASCII values"); + next; + } + push @addresses, $e->{'value'} + } elsif ( $e->{'value'} =~ /^\s*(\w+)\s*$/ ) { + my $user = RT::User->new( RT->SystemUser ); + $user->Load( $1 ); + if ($user->id) { + push @addresses, Email::Address->new($user->Name, $user->EmailAddress); + } else { + $logger->($e->{'value'} ." is not a valid email address and is not user name"); + } } else { - $RT::Logger->error("Unable to parse an email address from $address_string: $msg"); + $logger->($e->{'value'} ." is not a valid email address"); } - } else { - @addresses = Email::Address->parse($address_string); } $self->CleanupAddresses(@addresses); return @addresses; - } =head2 CleanupAddresses ARRAY @@ -618,7 +634,7 @@ sub RescueOutlook { # Add base64 since we've seen examples of double newlines with # this type too. Need an example of a multi-part base64 to # handle that permutation if it exists. - elsif ( $mime->head->get('Content-Transfer-Encoding') =~ m{base64} ) { + elsif ( ($mime->head->get('Content-Transfer-Encoding')||'') =~ m{base64} ) { $text_part = $mime; # Assuming single part, already decoded. }