]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/MIME.pm
mime: avoid SUPER usage in Email::MIME subclass
[public-inbox.git] / lib / PublicInbox / MIME.pm
1 # This library is free software; you can redistribute it and/or modify
2 # it under the same terms as Perl itself.
3 #
4 # The license for this file differs from the rest of public-inbox.
5 #
6 # It monkey patches the "parts_multipart" subroutine with patches
7 # from Matthew Horsfall <wolfsage@gmail.com> at:
8 #
9 # git clone --mirror https://github.com/rjbs/Email-MIME.git refs/pull/28/head
10 #
11 # commit fe0eb870ab732507aa39a1070a2fd9435c7e4877
12 # ("Make sure we don't modify the body of a message when injecting a header.")
13 # commit 981d8201a7239b02114489529fd366c4c576a146
14 # ("GH #14 - Handle CRLF emails properly.")
15 # commit 2338d93598b5e8432df24bda8dfdc231bdeb666e
16 # ("GH #14 - Support multipart messages without content-type in subparts.")
17 #
18 # For Email::MIME >= 1.923 && < 1.935,
19 # commit dcef9be66c49ae89c7a5027a789bbbac544499ce
20 # ("removing all trailing newlines was too much")
21 # is also included
22 package PublicInbox::MIME;
23 use strict;
24 use warnings;
25 use base qw(Email::MIME);
26
27 if ($Email::MIME::VERSION <= 1.937) {
28 sub parts_multipart {
29   my $self     = shift;
30   my $boundary = $self->{ct}->{attributes}->{boundary};
31
32   # Take a message, join all its lines together.  Now try to Email::MIME->new
33   # it with 1.861 or earlier.  Death!  It tries to recurse endlessly on the
34   # body, because every time it splits on boundary it gets itself. Obviously
35   # that means it's a bogus message, but a mangled result (or exception) is
36   # better than endless recursion. -- rjbs, 2008-01-07
37   return $self->parts_single_part
38     unless $boundary and $self->body_raw =~ /^--\Q$boundary\E\s*$/sm;
39
40   $self->{body_raw} = Email::Simple::body($self);
41
42   # rfc1521 7.2.1
43   my ($body, $epilogue) = split /^--\Q$boundary\E--\s*$/sm, $self->body_raw, 2;
44
45   # Split on boundaries, but keep blank lines after them intact
46   my @bits = split /^--\Q$boundary\E\s*?(?=$self->{mycrlf})/m, ($body || '');
47
48   Email::Simple::body_set($self, undef);
49
50   # If there are no headers in the potential MIME part, it's just part of the
51   # body.  This is a horrible hack, although it's debatable whether it was
52   # better or worse when it was $self->{body} = shift @bits ... -- rjbs,
53   # 2006-11-27
54   Email::Simple::body_set($self, shift @bits) if ($bits[0] || '') !~ /.*:.*/;
55
56   my $bits = @bits;
57
58   my @parts;
59   for my $bit (@bits) {
60     # Parts don't need headers. If they don't have them, they look like this:
61     #
62     #   --90e6ba6e8d06f1723604fc1b809a
63     #
64     #   Part 2
65     #
66     #   Part 2a
67     #
68     # $bit will contain two new lines before Part 2.
69     #
70     # Anything with headers will only have one new line.
71     #
72     # RFC 1341 Section 7.2 says parts without headers are to be considered
73     # plain US-ASCII text. -- alh
74     # 2016-08-01
75     my $added_header;
76
77     if ($bit =~ /^(?:$self->{mycrlf}){2}/) {
78       $bit = "Content-type: text/plain; charset=us-ascii" . $bit;
79
80       $added_header = 1;
81     }
82
83     $bit =~ s/\A[\n\r]+//smg;
84     $bit =~ s/(?<!\x0d)$self->{mycrlf}\Z//sm;
85
86     my $email = (ref $self)->new($bit);
87
88     if ($added_header) {
89       # Remove our changes so we don't change the raw email content
90       $email->header_str_set('Content-Type');
91     }
92
93     push @parts, $email;
94   }
95
96   $self->{parts} = \@parts;
97
98   return @{ $self->{parts} };
99 }
100 }
101
102 1;