]> Sergey Matveev's repositories - public-inbox.git/commitdiff
filter: preserve QP when collapsing multipart
authorEric Wong <e@80x24.org>
Mon, 4 Aug 2014 20:16:51 +0000 (20:16 +0000)
committerEric Wong <e@80x24.org>
Mon, 4 Aug 2014 20:16:51 +0000 (20:16 +0000)
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
t/filter.t

index a1587682a3f3a8d4dd866db535b15a0623382252..e784cded644139160d84b4205cb5f6ffbc275923 100644 (file)
@@ -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;
 }
index c3cd39f426f9c3a1b4c8de17e7c1b3d73aa82120..e4f6a2b09ada860fff07b12ed4d8da292610c56d 100644 (file)
@@ -15,6 +15,53 @@ sub count_body_parts {
        $bodies->{$body}++;
 }
 
+# multipart/alternative: HTML and quoted-printable, keep the plain-text
+{
+       my $html_body = "<html><body>hi</body></html>";
+       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(