diff --git a/lib/Email/MIME/Header.pm b/lib/Email/MIME/Header.pm index e2c6fea..600a1ad 100644 --- a/lib/Email/MIME/Header.pm +++ b/lib/Email/MIME/Header.pm @@ -56,8 +56,6 @@ sub header_str { foreach my $header (@header) { next unless defined $header; - next unless $header =~ /=\?/; - _maybe_decode($_[0], \$header); } return $wanta ? @header : $header[0]; diff --git a/lib/Email/MIME/Header/AddressList.pm b/lib/Email/MIME/Header/AddressList.pm index 311369f..497c4ea 100644 --- a/lib/Email/MIME/Header/AddressList.pm +++ b/lib/Email/MIME/Header/AddressList.pm @@ -8,6 +8,7 @@ use warnings; use Carp (); use Email::Address::XS; use Email::MIME::Encode; +use Net::IDN::Encode; =encoding utf8 @@ -17,6 +18,10 @@ Email::MIME::Header::AddressList - MIME support for list of Email::Address::XS o =head1 SYNOPSIS + use utf8; + use Email::Address::XS; + use Email::MIME::Header::AddressList; + my $address1 = Email::Address::XS->new('Name1' => 'address1@host.com'); my $address2 = Email::Address::XS->new("Name2 \N{U+263A}" => 'address2@host.com'); my $mime_address = Email::Address::XS->new('=?UTF-8?B?TmFtZTIg4pi6?=' => 'address2@host.com'); @@ -131,14 +136,20 @@ sub new_mime_groups { $groups[2 * $_ + 1] = [ @{$groups[2 * $_ + 1]} ]; foreach (@{$groups[2 * $_ + 1]}) { next unless Email::Address::XS->is_obj($_); - my $decode_phrase = (defined $_->phrase and $_->phrase =~ /=\?/); - my $decode_comment = (defined $_->comment and $_->comment =~ /=\?/); - next unless $decode_phrase or $decode_comment; + my $phrase = $_->phrase; + my $comment = $_->comment; + my $host = $_->host; + my $decode_phrase = (defined $phrase and $phrase =~ /=\?/); + my $decode_comment = (defined $comment and $comment =~ /=\?/); + my $decode_host = (defined $host and $host =~ /xn--/); + next unless $decode_phrase or $decode_comment or $decode_host; $_ = ref($_)->new(copy => $_); - $_->phrase(Email::MIME::Encode::mime_decode($_->phrase)) + $_->phrase(Email::MIME::Encode::mime_decode($phrase)) if $decode_phrase; - $_->comment(Email::MIME::Encode::mime_decode($_->comment)) + $_->comment(Email::MIME::Encode::mime_decode($comment)) if $decode_comment; + $_->host(Net::IDN::Encode::domain_to_unicode($host)) + if $decode_host; } } return $class->new_groups(@groups); @@ -205,14 +216,20 @@ sub as_mime_string { if Email::MIME::Encode::_needs_mime_encode_addr($groups[2 * $_]); $groups[2 * $_ + 1] = [ @{$groups[2 * $_ + 1]} ]; foreach (@{$groups[2 * $_ + 1]}) { - my $encode_phrase = Email::MIME::Encode::_needs_mime_encode_addr($_->phrase); - my $encode_comment = Email::MIME::Encode::_needs_mime_encode_addr($_->comment); - next unless $encode_phrase or $encode_comment; + my $phrase = $_->phrase; + my $comment = $_->comment; + my $host = $_->host; + my $encode_phrase = Email::MIME::Encode::_needs_mime_encode_addr($phrase); + my $encode_comment = Email::MIME::Encode::_needs_mime_encode_addr($comment); + my $encode_host = (defined $host and $host =~ /\P{ASCII}/); + next unless $encode_phrase or $encode_comment or $encode_host; $_ = ref($_)->new(copy => $_); - $_->phrase(Email::MIME::Encode::mime_encode($_->phrase, $charset)) + $_->phrase(Email::MIME::Encode::mime_encode($phrase, $charset)) if $encode_phrase; - $_->comment(Email::MIME::Encode::mime_encode($_->comment, $charset)) + $_->comment(Email::MIME::Encode::mime_encode($comment, $charset)) if $encode_comment; + $_->host(Net::IDN::Encode::domain_to_ascii($host)) + if $encode_host; } } return Email::Address::XS::format_email_groups(@groups); diff --git a/t/unicode.t b/t/unicode.t index f6c7cc3..4efc4be 100644 --- a/t/unicode.t +++ b/t/unicode.t @@ -72,6 +72,8 @@ SKIP: { 'Doy ', # not '"," ', # address-like pattern in phrase '"Döy ," ', # unicode address-like pattern in phrase + 'adam@äli.as', # unicode host + 'Ädam ', # unicode phrase and host ); for my $subject (@subjects) { @@ -93,8 +95,13 @@ SKIP: { $email->header_str_set('To', $to); is(scalar($email->header_str('To')), $to, "To header is correct"); - like($email->as_string, qr/test\@example\.com/, - "address isn't encoded"); + if ($to =~ /adam/) { + like($email->header_raw('To'), qr/adam\@xn--li-uia.as/, + 'To raw header is correct'); + } else { + like($email->as_string, qr/test\@example\.com/, + "address isn't encoded"); + } like($email->as_string, qr/\A\p{ASCII}*\z/, "email doesn't contain any non-ascii characters"); }