Subject: | MIME::Parser::Reader removes trailing \r from data |
When a file being decoded ends in a \r (0x0D) byte and is followed by the MIME boundary, MIME::Parser::Reader removes that \r byte. The line of code in error is this (line 282 of Reader.pm)
$last =~ s/[\r\n]+\Z// if ($eos =~ /^(DELIM|CLOSE)/);
This strips off any number of trailing \r or \n bytes. Due to the context of how the code got there $last will contain bytes since the previous \n, so there will only be one \n to be stripped but potentially several \r bytes.
The attached script demonstrates the problem for a text file and a binary file. The size of the decoded files shown by dump_skeleton are one byte less than the original data.
perl, v5.6.1 built for MSWin32-x86-multi-thread
distribution is MIME::Tools 5.414 (the same problem is in 6.02)
Windows 98 (and Windows 2000)
The difficulty of providing a fix is that the code tries to handle both both \r\n and \n only as end of line sequences, so there is no clear way to know whether the \r should be removed.
The best solution would be to firm up on using \r\n only as end of line sequences, but that would be a big change.
use strict;
use MIME::Entity;
use MIME::Parser;
use Devel::Peek;
my $top = MIME::Entity->build(Type => 'multipart/mixed');
$top->attach(
Data => "\x01\x02\x03hello\r",
Type => 'application/octet-stream',
Encoding => 'binary'
);
$top->attach(
Data => "hello\r",
Type => 'text/plain',
Encoding => '7bit'
);
my $message = $top->stringify;
print Dump $message;
my $parser = new MIME::Parser;
my $entity = $parser->parse_data($message);
$entity->dump_skeleton;