fix parsing of multiple To: addresses, #73241
authorMark Wells <mark@freeside.biz>
Wed, 14 Dec 2016 21:00:24 +0000 (13:00 -0800)
committerMark Wells <mark@freeside.biz>
Wed, 14 Dec 2016 21:41:58 +0000 (13:41 -0800)
FS/FS/Misc.pm
FS/FS/msg_template/email.pm
httemplate/search/cust_msg.html
httemplate/view/cust_msg.html

index 9a43180..a2d1b3e 100644 (file)
@@ -256,10 +256,17 @@ sub send_email {
   }
   
   push @to, $options{bcc} if defined($options{bcc});
+  # fully unpack all addresses found in @to (including Bcc) to make the
+  # envelope list
+  my @env_to;
+  foreach my $dest (@to) {
+    push @env_to, map { $_->address } Email::Address->parse($dest);
+  }
+
   local $@; # just in case
   eval { sendmail($message, { transport => $transport,
                               from      => $from,
-                              to        => \@to }) };
+                              to        => \@env_to }) };
 
   my $error = '';
   if(ref($@) and $@->isa('Email::Sender::Failure')) {
@@ -274,7 +281,7 @@ sub send_email {
   if ( $conf->exists('log_sent_mail') ) {
     my $cust_msg = FS::cust_msg->new({
         'env_from'  => $options{'from'},
-        'env_to'    => join(', ', @to),
+        'env_to'    => join(', ', @env_to),
         'header'    => $message->header_as_string,
         'body'      => $message->body_as_string,
         '_date'     => $time,
index cc5428b..4ae89f0 100644 (file)
@@ -290,7 +290,7 @@ sub prepare {
   my @to;
   if ( exists($opt{'to'}) ) {
 
-    @to = split(/\s*,\s*/, $opt{'to'});
+    @to = map { $_->format } Email::Address->parse($opt{'to'});
 
   } elsif ( $cust_main ) {
 
@@ -393,14 +393,17 @@ sub prepare {
 
   # effective To: address (not in headers)
   push @to, $self->bcc_addr if $self->bcc_addr;
-  my $env_to = join(', ', @to);
+  my @env_to;
+  foreach my $dest (@to) {
+    push @env_to, map { $_->address } Email::Address->parse($dest);
+  }
 
   my $cust_msg = FS::cust_msg->new({
       'custnum'   => $cust_main ? $cust_main->custnum : '',
       'msgnum'    => $self->msgnum,
       '_date'     => $time,
       'env_from'  => $env_from,
-      'env_to'    => $env_to,
+      'env_to'    => join(',', @env_to),
       'header'    => $message->header_as_string,
       'body'      => $message->body_as_string,
       'error'     => '',
@@ -507,7 +510,9 @@ sub send_prepared {
     $domain = $1;
   }
 
-  my @to = split(/\s*,\s*/, $cust_msg->env_to);
+  # in principle should already be a list of bare addresses, but run it
+  # through Email::Address to make sure
+  my @env_to = map { $_->address } Email::Address->parse($cust_msg->env_to);
 
   my %smtp_opt = ( 'host' => $conf->config('smtpmachine'),
                    'helo' => $domain );
@@ -533,7 +538,7 @@ sub send_prepared {
   eval {
     sendmail( $message, { transport => $transport,
                           from      => $cust_msg->env_from,
-                          to        => \@to })
+                          to        => \@env_to })
   };
   my $error = '';
   if(ref($@) and $@->isa('Email::Sender::Failure')) {
index 33e1815..65460f7 100644 (file)
                               ucfirst($_[0]->msgtype) || $_[0]->msgname
                             },
                             sub {
-                              join('<BR>', split(/,\s*/, $_[0]->env_to) )
+                              join('<BR>',
+                                map { encode_entities($_->format) }
+                                Email::Address->parse($_[0]->env_to)
+                              )
                             },
                             'status',
                             sub { encode_entities($_[0]->error) },
index 91a08eb..d2b043c 100755 (executable)
@@ -61,7 +61,9 @@ $custmsgnum =~ /^(\d+)$/ or die "illegal custmsgnum";
 my $cust_msg = qsearchs('cust_msg', { 'custmsgnum' => $custmsgnum });
 my $date = '';
 $date = time2str('%Y-%m-%d %T', $cust_msg->_date) if ( $cust_msg->_date );
-my $env_to = join('</TD></TR><TR><TD></TD><TD>', split(',', $cust_msg->env_to));
+my @to = map { encode_entities($_->format) }
+          Email::Address->parse($cust_msg->env_to);
+my $env_to = join('</TD></TR><TR><TD></TD><TD>', @to);
 
 my %label = (
   'sent'   => 'Sent:',