From c9ea7a39daff28e0c75df8b5853fbd4a9bda6bba Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 4 Aug 2014 20:16:51 +0000 Subject: filter: preserve QP when collapsing multipart HTML clients also tend to send quoted-printable crap in their plain-text parts, preserve that so it's displayed correctly for all QP-capable handlers. --- lib/PublicInbox/Filter.pm | 4 ++++ t/filter.t | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/lib/PublicInbox/Filter.pm b/lib/PublicInbox/Filter.pm index a1587682..e784cded 100644 --- a/lib/PublicInbox/Filter.pm +++ b/lib/PublicInbox/Filter.pm @@ -201,6 +201,10 @@ sub collapse { my ($mime, $part) = @_; $mime->header_set('Content-Type', $part->content_type); $mime->body_set($part->body_raw); + my $cte = $part->header('Content-Transfer-Encoding'); + if (defined($cte) && length($cte)) { + $mime->header_set('Content-Transfer-Encoding', $cte); + } mark_changed($mime); return 1; } diff --git a/t/filter.t b/t/filter.t index c3cd39f4..e4f6a2b0 100644 --- a/t/filter.t +++ b/t/filter.t @@ -15,6 +15,53 @@ sub count_body_parts { $bodies->{$body}++; } +# multipart/alternative: HTML and quoted-printable, keep the plain-text +{ + my $html_body = "hi"; + my $parts = [ + Email::MIME->create( + attributes => { + content_type => 'text/html; charset=UTF-8', + encoding => 'base64', + }, + body => $html_body, + ), + Email::MIME->create( + attributes => { + content_type => 'text/plain', + encoding => 'quoted-printable', + }, + body => 'hi = "bye"', + ) + ]; + my $email = Email::MIME->create( + header_str => [ + From => 'a@example.com', + Subject => 'blah', + 'Content-Type' => 'multipart/alternative' + ], + parts => $parts, + ); + is(1, PublicInbox::Filter->run($email), "run was a success"); + my $parsed = Email::MIME->new($email->as_string); + is("text/plain", $parsed->header("Content-Type")); + is(scalar $parsed->parts, 1, "HTML part removed"); + my %bodies; + $parsed->walk_parts(sub { + my ($part) = @_; + return if $part->subparts; # walk_parts already recurses + count_body_parts(\%bodies, $part); + }); + is(scalar keys %bodies, 1, "one bodies"); + is($bodies{"hi =3D \"bye\"="}, 1, "QP text part unchanged"); + $parsed->walk_parts(sub { + my ($part) = @_; + my $b = $part->body; + $b =~ s/\s*\z//; + is($b, "hi = \"bye\"", "decoded body matches"); + }); +} + # plain-text email is passed through unchanged { my $s = Email::MIME->create( -- cgit v1.2.3-24-ge0c7