File Coverage

blib/lib/MIME/Decoder/QuotedPrint.pm
Criterion Covered Total %
statement 44 53 83.0
branch 8 12 66.6
condition 1 3 33.3
subroutine 11 11 100.0
pod 2 4 50.0
total 66 83 79.5


line stmt bran cond sub pod time code
1             package MIME::Decoder::QuotedPrint;
2 8     8   12798 use strict;
  8         18  
  8         337  
3 8     8   43 use warnings;
  8         14  
  8         432  
4 8     8   639 use version;
  8         4211  
  8         96  
5              
6             =head1 NAME
7              
8             MIME::Decoder::QuotedPrint - encode/decode a "quoted-printable" stream
9              
10              
11             =head1 SYNOPSIS
12              
13             A generic decoder object; see L for usage.
14              
15              
16             =head1 DESCRIPTION
17              
18             A MIME::Decoder subclass for the C<"quoted-printable"> encoding.
19             The name was chosen to jibe with the pre-existing MIME::QuotedPrint
20             utility package, which this class actually uses to translate each line.
21              
22             =over 4
23              
24             =item *
25              
26             The B does a line-by-line translation from input to output.
27              
28             =item *
29              
30             The B does a line-by-line translation, breaking lines
31             so that they fall under the standard 76-character limit for this
32             encoding.
33              
34             =back
35              
36              
37             B just like MIME::QuotedPrint, we currently use the
38             native C<"\n"> for line breaks, and not C. This may
39             need to change in future versions.
40              
41             =head1 SEE ALSO
42              
43             L
44              
45             =head1 AUTHOR
46              
47             Eryq (F), ZeeGee Software Inc (F).
48              
49             All rights reserved. This program is free software; you can redistribute
50             it and/or modify it under the same terms as Perl itself.
51              
52             =cut
53              
54 8     8   874 use vars qw(@ISA $VERSION);
  8         15  
  8         556  
55 8     8   43 use MIME::Decoder;
  8         17  
  8         204  
56 8     8   452 use MIME::QuotedPrint;
  8         258  
  8         1342  
57              
58             @ISA = qw(MIME::Decoder);
59              
60             # The package version, both in 1.23 style *and* usable by MakeMaker:
61             $VERSION = "5.517";
62              
63             #------------------------------
64             # If we have MIME::QuotedPrint 3.03 or later, use the three-argument
65             # version. If we have an earlier version of MIME::QuotedPrint, we
66             # may get the wrong results. However, on some systems (RH Linux,
67             # for example), MIME::QuotedPrint is part of the Perl package and
68             # upgrading it separately breaks their magic auto-update tools.
69             # We are supporting older versions of MIME::QuotedPrint even though
70             # they may give incorrect results simply because it's too painful
71             # for many people to upgrade.
72              
73             # The following code is horrible. I know. Beat me up. --dfs
74             BEGIN {
75 8 50   8   59 if (!defined(&encode_qp_threearg)) {
76 8         127 my $ver = version->parse($::MIME::QuotedPrint::VERSION);
77 8 50       448 if ($ver >= version->parse(3.03)) {
78 8     65 0 5571 eval 'sub encode_qp_threearg ( $$$ ) { encode_qp(shift, shift, shift); }';
  65         345  
79             } else {
80 0         0 eval 'sub encode_qp_threearg ( $$$ ) { encode_qp(shift); }';
81             }
82             }
83             }
84              
85             #------------------------------
86             #
87             # encode_qp_really STRING TEXTUAL_TYPE_FLAG
88             #
89             # Encode QP, and then follow guideline 8 from RFC 2049 (thanks to Denis
90             # N. Antonioli) whereby we make things a little safer for the transport
91             # and storage of messages. WARNING: we can only do this if the line won't
92             # grow beyond 76 characters!
93             #
94             sub encode_qp_really {
95 65     65 0 8451 my $enc = encode_qp_threearg(shift, undef, not shift);
96 65 100       154 if (length($enc) < 74) {
97 59         97 $enc =~ s/^\.\n/=2E\n/g; # force encoding of /^\.$/
98 59         116 $enc =~ s/^From /=46rom /g; # force encoding of /^From /
99             }
100 65         165 $enc;
101             }
102              
103             #------------------------------
104             #
105             # decode_it IN, OUT
106             #
107             sub decode_it {
108 14     14 1 69 my ($self, $in, $out) = @_;
109 14         26 my $init = 0;
110 14         28 my $badpdf = 0;
111              
112 14         31 local $_;
113 14         692 while (defined($_ = $in->getline)) {
114             #
115             # Dirty hack to fix QP-Encoded PDFs from MS-Outlook.
116             #
117             # Check if we have a PDF file and if it has been encoded
118             # on Windows. Unix encoded files are fine. If we have
119             # one encoded CR after the PDF init string but are missing
120             # an encoded CR before the newline this means the PDF is broken.
121             #
122 328 100       2986 if (!$init) {
123 14         27 $init = 1;
124 14 50 33     63 if ($_ =~ /^%PDF-[0-9\.]+=0D/ && $_ !~ /=0D\n$/) {
125 0         0 $badpdf = 1;
126             }
127             }
128             #
129             # Decode everything with decode_qp() except corrupted PDFs.
130             #
131 328 50       445 if ($badpdf) {
132 0         0 my $output = $_;
133 0         0 $output =~ s/[ \t]+?(\r?\n)/$1/g;
134 0         0 $output =~ s/=\r?\n//g;
135 0         0 $output =~ s/(^|[^\r])\n\Z/$1\r\n/;
136 0         0 $output =~ s/=([\da-fA-F]{2})/pack("C", hex($1))/ge;
  0         0  
137 0         0 $out->print($output);
138             } else {
139 328         1349 $out->print(decode_qp($_));
140             }
141             }
142 14         338 1;
143             }
144              
145             #------------------------------
146             #
147             # encode_it IN, OUT
148             #
149             sub encode_it {
150 8     8 1 20 my ($self, $in, $out, $textual_type) = @_;
151              
152 8         16 local $_;
153 8         186 while (defined($_ = $in->getline)) {
154 57         511 $out->print(encode_qp_really($_, $textual_type));
155             }
156 8         165 1;
157             }
158              
159             #------------------------------
160             1;