Skip Menu |

This queue is for tickets about the MIME-tools CPAN distribution.

Report information
The Basics
Id: 87835
Status: new
Priority: 0/
Queue: MIME-tools

People
Owner: Nobody in particular
Requestors: cpan [...] chmrr.net
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Round-trip mutlipart preambles with CRLF
The test to detect "unless the last line consists only of a CRLF" did not adequately catch CRLF, only CR or LF separately. Patch is attached. - Alex
Subject: 0001-Round-trip-multipart-preambles-with-trailing-CRLF-ne.patch
From ee1422d25e7d64f26268892462abb47ccb529d69 Mon Sep 17 00:00:00 2001 From: Alex Vandiver <alex@chmrr.net> Date: Tue, 13 Aug 2013 19:10:29 -0400 Subject: [PATCH] Round-trip multipart preambles with trailing CRLF newlines. The test to detect "unless the last line consists only of a CRLF" did not adequately catch CRLF, only CR or LF separately. --- lib/MIME/Parser/Reader.pm | 2 +- t/ParserPreamble.t | 34 ++++++++++++++++++++++++++++------ testmsgs/multi-crlf.msg | 25 +++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 testmsgs/multi-crlf.msg diff --git a/lib/MIME/Parser/Reader.pm b/lib/MIME/Parser/Reader.pm index a7eaf5c..0d63b66 100644 --- a/lib/MIME/Parser/Reader.pm +++ b/lib/MIME/Parser/Reader.pm @@ -293,7 +293,7 @@ sub read_chunk { # Write out last held line, removing terminating CRLF if ended on bound, # unless the line consists only of CRLF and we're wanting to keep the # preceding blank line (as when parsing a preamble) - $last =~ s/[\r\n]+\Z// if ($eos =~ /^(DELIM|CLOSE)/ && !($keep_newline && $last =~ m/^[\r\n]\z/)); + $last =~ s/[\r\n]+\Z// if ($eos =~ /^(DELIM|CLOSE)/ && !($keep_newline && $last =~ m/^[\r\n]+\z/)); $out->print($last); ### Save and return what we finished on: diff --git a/t/ParserPreamble.t b/t/ParserPreamble.t index e10a016..f287eda 100644 --- a/t/ParserPreamble.t +++ b/t/ParserPreamble.t @@ -1,7 +1,7 @@ #!/usr/bin/perl -w use strict; use warnings; -use Test::More tests => 7; +use Test::More tests => 9; use Test::Deep; my %files = ( @@ -11,6 +11,13 @@ my %files = ( "is a handy place for mail composers to include an\n", "explanatory note to non-MIME conformant readers." ], + 'testmsgs/multi-crlf.msg' => [ + "This is the preamble. It is to be ignored, though it\r\n", + "is a handy place for mail composers to include an\r\n", + "explanatory note to non-MIME conformant readers. It\r\n", + "ends with a linebreak.\r\n", + "\r" + ], 'testmsgs/ticket-60931.msg' => [ ], ); @@ -22,19 +29,34 @@ my $parser = MIME::Parser->new(); $parser->output_to_core(1); $parser->decode_bodies(0); -foreach my $file (keys %files) { - #-- Parse quoted-printable encoded file +foreach my $file (sort keys %files) { open (my $fh, $file) - or die "can't open testmsgs/empty-preamble.msg: $!"; + or die "can't open $file: $!"; my $entity = $parser->parse($fh); $fh->seek(0,0); my $expected = do { local $/; <$fh> }; close $fh; - cmp_deeply( $entity->preamble(), $files{$file}, 'Preamble is as expected'); + cmp_deeply( $entity->preamble(), $files{$file}, "Preamble is as expected in $file"); + + if ($entity->as_string ne $expected) { + { + my $str = $entity->as_string; + $str =~ s/(?<!\r)\n/\\n\n/g; + $str =~ s/\r\n/\\r\\n\n/g; + diag Carp::longmess("==============Round-tripped:\n$str"); + } + + { + my $str = $expected; + $str =~ s/(?<!\r)\n/\\n\n/g; + $str =~ s/\r\n/\\r\\n\n/g; + diag Carp::longmess("==============Expected:\n$str"); + } +} - is( $entity->as_string(), $expected, 'File with preamble roundtripped correctly'); + is( $entity->as_string(), $expected, "$file with preamble roundtripped correctly"); } 1; diff --git a/testmsgs/multi-crlf.msg b/testmsgs/multi-crlf.msg new file mode 100644 index 0000000..a2d20c5 --- /dev/null +++ b/testmsgs/multi-crlf.msg @@ -0,0 +1,25 @@ +From: Nathaniel Borenstein <nsb@bellcore.com> +To: Ned Freed <ned@innosoft.com> +Subject: Sample message +MIME-Version: 1.0 +Content-type: multipart/mixed; boundary="simple + boundary" + +This is the preamble. It is to be ignored, though it +is a handy place for mail composers to include an +explanatory note to non-MIME conformant readers. It +ends with a linebreak. + +--simple boundary + +This is implicitly typed plain ASCII text. +It does NOT end with a linebreak. +--simple boundary +Content-type: text/plain; charset=us-ascii + +This is explicitly typed plain ASCII text. +It DOES end with a linebreak. + +--simple boundary-- +This is the epilogue. It is also to be ignored. + -- 1.8.3.4
On 2013-08-13T19:14:14-04:00, ALEXMV wrote: Show quoted text
> The test to detect "unless the last line consists only of a CRLF" did > not adequately catch CRLF, only CR or LF separately. Patch is > attached.
That version of the patch mistakenly included debugging changes in t/ParserPreamble.t Updated version attached. - Alex
Subject: 0001-Round-trip-multipart-preambles-with-trailing-CRLF-ne.patch
From 089cbf07b21088e8442e71479ce970fedce4abdd Mon Sep 17 00:00:00 2001 From: Alex Vandiver <alex@chmrr.net> Date: Tue, 13 Aug 2013 19:10:29 -0400 Subject: [PATCH] Round-trip multipart preambles with trailing CRLF newlines. The test to detect "unless the last line consists only of a CRLF" did not adequately catch CRLF, only CR or LF separately. --- lib/MIME/Parser/Reader.pm | 2 +- t/ParserPreamble.t | 18 ++++++++++++------ testmsgs/multi-crlf.msg | 25 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 testmsgs/multi-crlf.msg diff --git a/lib/MIME/Parser/Reader.pm b/lib/MIME/Parser/Reader.pm index a7eaf5c..0d63b66 100644 --- a/lib/MIME/Parser/Reader.pm +++ b/lib/MIME/Parser/Reader.pm @@ -293,7 +293,7 @@ sub read_chunk { # Write out last held line, removing terminating CRLF if ended on bound, # unless the line consists only of CRLF and we're wanting to keep the # preceding blank line (as when parsing a preamble) - $last =~ s/[\r\n]+\Z// if ($eos =~ /^(DELIM|CLOSE)/ && !($keep_newline && $last =~ m/^[\r\n]\z/)); + $last =~ s/[\r\n]+\Z// if ($eos =~ /^(DELIM|CLOSE)/ && !($keep_newline && $last =~ m/^[\r\n]+\z/)); $out->print($last); ### Save and return what we finished on: diff --git a/t/ParserPreamble.t b/t/ParserPreamble.t index e10a016..8f081a1 100644 --- a/t/ParserPreamble.t +++ b/t/ParserPreamble.t @@ -1,7 +1,7 @@ #!/usr/bin/perl -w use strict; use warnings; -use Test::More tests => 7; +use Test::More tests => 9; use Test::Deep; my %files = ( @@ -11,6 +11,13 @@ my %files = ( "is a handy place for mail composers to include an\n", "explanatory note to non-MIME conformant readers." ], + 'testmsgs/multi-crlf.msg' => [ + "This is the preamble. It is to be ignored, though it\r\n", + "is a handy place for mail composers to include an\r\n", + "explanatory note to non-MIME conformant readers. It\r\n", + "ends with a linebreak.\r\n", + "\r" + ], 'testmsgs/ticket-60931.msg' => [ ], ); @@ -22,19 +29,18 @@ my $parser = MIME::Parser->new(); $parser->output_to_core(1); $parser->decode_bodies(0); -foreach my $file (keys %files) { - #-- Parse quoted-printable encoded file +foreach my $file (sort keys %files) { open (my $fh, $file) - or die "can't open testmsgs/empty-preamble.msg: $!"; + or die "can't open $file: $!"; my $entity = $parser->parse($fh); $fh->seek(0,0); my $expected = do { local $/; <$fh> }; close $fh; - cmp_deeply( $entity->preamble(), $files{$file}, 'Preamble is as expected'); + cmp_deeply( $entity->preamble(), $files{$file}, "Preamble is as expected in $file"); - is( $entity->as_string(), $expected, 'File with preamble roundtripped correctly'); + is( $entity->as_string(), $expected, "$file with preamble roundtripped correctly"); } 1; diff --git a/testmsgs/multi-crlf.msg b/testmsgs/multi-crlf.msg new file mode 100644 index 0000000..a2d20c5 --- /dev/null +++ b/testmsgs/multi-crlf.msg @@ -0,0 +1,25 @@ +From: Nathaniel Borenstein <nsb@bellcore.com> +To: Ned Freed <ned@innosoft.com> +Subject: Sample message +MIME-Version: 1.0 +Content-type: multipart/mixed; boundary="simple + boundary" + +This is the preamble. It is to be ignored, though it +is a handy place for mail composers to include an +explanatory note to non-MIME conformant readers. It +ends with a linebreak. + +--simple boundary + +This is implicitly typed plain ASCII text. +It does NOT end with a linebreak. +--simple boundary +Content-type: text/plain; charset=us-ascii + +This is explicitly typed plain ASCII text. +It DOES end with a linebreak. + +--simple boundary-- +This is the epilogue. It is also to be ignored. + -- 1.8.3.4