From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-2.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: meta@public-inbox.org Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id B13101FB36; Tue, 5 Aug 2014 00:45:12 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Cc: Eric Wong Subject: [PATCH 1/2] filter: preserve QP when collapsing multipart Date: Tue, 5 Aug 2014 00:45:05 +0000 Message-Id: <1407199506-15596-1-git-send-email-e@80x24.org> X-Mailer: git-send-email 2.0.1.427.gc47372d List-Id: 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 a158768..e784cde 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 c3cd39f..e4f6a2b 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( -- 2.0.1.427.gc47372d