From 8807f0d093961851b7d6d48daf783b799a47c3c9 Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Mon, 2 Dec 2013 12:44:32 -0500 Subject: [PATCH] =?UTF-8?q?Ensure=20that=20outgoing=20mail=20is=20not=20lo?= =?UTF-8?q?st=20if=20HTML=20=E2=86=92=20text=20conversion=20fails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HTML::FormatText::WithLinks::AndTables may contain errors which make it incapable of rendering the HTML to text. If the conversion fails, trap it and ensure that we still at least send out the HTML version. It is expected that these tests may begin to fail if HTML::FormatText::WithLinks::AndTables resolves its bug surrounding nested tables. Unfortunately, marking them TODO is difficult. --- lib/RT/Template.pm | 16 ++++++++++++---- t/mail/html-outgoing.t | 26 +++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm index 43c08baacd9..71f83db16a8 100644 --- a/lib/RT/Template.pm +++ b/lib/RT/Template.pm @@ -660,14 +660,22 @@ sub _DowngradeFromHTML { $orig_entity->head->mime_attr( "Content-Type" => 'text/html' ); $orig_entity->head->mime_attr( "Content-Type.charset" => 'utf-8' ); - $orig_entity->make_multipart('alternative', Force => 1); require Encode; - $new_entity->bodyhandle(MIME::Body::InCore->new( + my $html = eval { + my $body = $new_entity->bodyhandle->as_string; # need to decode_utf8, see the doc of MIMEObj method - \(RT::Interface::Email::ConvertHTMLToText(Encode::decode_utf8($new_entity->bodyhandle->as_string))) - )); + $body = Encode::decode_utf8( $body ); + RT::Interface::Email::ConvertHTMLToText( $body ); + }; + if ($@) { + $RT::Logger->error("Failed to downgrade HTML to plain text: $@"); + return; + } + $new_entity->bodyhandle(MIME::Body::InCore->new( \$html )); + + $orig_entity->make_multipart('alternative', Force => 1); $orig_entity->add_part($new_entity, 0); # plain comes before html $self->{MIMEObj} = $orig_entity; diff --git a/t/mail/html-outgoing.t b/t/mail/html-outgoing.t index d20dd630c39..1b460c2a79b 100644 --- a/t/mail/html-outgoing.t +++ b/t/mail/html-outgoing.t @@ -4,10 +4,11 @@ use RT::Test tests => undef; BEGIN { plan skip_all => 'Email::Abstract and Test::Email required.' unless eval { require Email::Abstract; require Test::Email; 1 }; - plan tests => 18; + plan tests => 22; } use RT::Test::Email; +use Test::Warn; my $root = RT::User->new(RT->SystemUser); $root->Load('root'); @@ -86,6 +87,29 @@ mail_ok { }; +diag "Failing HTML -> Text conversion"; +warnings_like { + my $body = '
Foo
'; + mail_ok { + ($ok, $tmsg) = $t->Correspond( + MIMEObj => HTML::Mason::Commands::MakeMIMEEntity( + Body => $body, + Type => 'text/html', + ), + ); + } { from => qr/RT System/, + bcc => 'root@localhost', + subject => qr/\Q[example.com #1] The internet is broken\E/, + body => qr{Ticket URL: \1.+?$body}s, + 'Content-Type' => qr{text/html}, # TODO + },{ from => qr/RT System/, + to => 'enduser@example.com', + subject => qr/\Q[example.com #1] The internet is broken\E/, + body => qr{
Foo
}, + 'Content-Type' => qr{text/html}, # TODO + }; +} [(qr/uninitialized value/, qr/Failed to downgrade HTML/)x3]; + diag "Admin Comment in HTML"; mail_ok { ($ok, $tmsg) = $t->Comment(