Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Email-Simple CPAN distribution.

Report information
The Basics
Id: 16271
Status: resolved
Priority: 0/
Queue: Email-Simple

People
Owner: Nobody in particular
Requestors: adam [...] worrall.cc
Cc:
AdminCc:

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



Subject: Bug in _fold
I was trying to feed the output of Email::Simple::as_string back into itself, but it turns out the headers are badly formatted. Run the attached script to see what I mean. The problem is with the headers that get wrapped; the last line of a wrapped header ends with \r\r\n, not \r\n. This tickles the 'be flexible in what we accept' part of _split_head_from_body, which takes \r to be the separator, and thus \r\r to indicate an empty line, and the end of the headers. The prob comes from _header_as_string; it adds a {mycrlf} to the long line and passes it into _fold().\, but fold doesn't expect any line endings inside. When fold reaches the last part of the $line, the (\s|\z) in the regex matches the \n added via {mycrlf}, but leaves the preceding \r in $1. Another {mycrlf} gets added, leaving the final line with \r\r\n. Doh ! I fixed this by changing the call to _fold to look like this (modulo form wrapping :) my $ret = join "", map { $_ = "$field: $_"; length > 78 ? $self->_fold($_) : "$_$self->{mycrlf}" } @stuff; I.e. only add the {crlf} if we're not passing to _fold. I'm puzzled that I came across this, since I can't see how anyone is doing much with Email::MIME, since it needs to reparse the Email::Simple objects. Anyway, hope this helps ... - Adam
#!/usr/bin/perl use warnings; use strict; use Email::Simple; my $email = ''; $email .= $_ while (<DATA>); my $msg1 = Email::Simple->new($email); my $msg2 = Email::Simple->new($msg1->as_string); print "Oh no, we've lost our headers!\n".$msg2->_headers_as_string(); __DATA__ Return-Path: <sundar@foo.com> Received: from murder ([unix socket]) (authenticated user=adam bits=0) by mail1.foo.com (Cyrus v2.2.12-OS X 10.4.0) with LMTPA; Tue, 25 Oct 2005 07:26:59 -0400 X-Sieve: CMU Sieve 2.2 X-Original-To: adam@mail1.internal.foo.com Delivered-To: adam@mail1.internal.foo.com Received: from localhost (localhost [127.0.0.1]) by mail1.foo.com (Postfix) with ESMTP id C24ABADEA15 for <adam@mail1.internal.foo.com>; Tue, 25 Oct 2005 07:26:58 -0400 (EDT) Received: from mail1.foo.com ([127.0.0.1]) by localhost (localhost [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 20330-05 for <adam@mail1.internal.foo.com>; Tue, 25 Oct 2005 07:26:55 -0400 (EDT) Received: from mta.internal.foo.com (mta.internal.foo.com [0.0.0.0]) by mail1.foo.com (Postfix) with ESMTP id 1D919ADE9FE for <adam@mail1.internal.foo.com>; Tue, 25 Oct 2005 07:26:55 -0400 (EDT) Received: from [0.0.0.0] ([0.0.0.0]) (authenticated bits=0) by mta.internal.foo.com (8.12.8/8.12.8) with ESMTP id j9PBQoCT026374 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for <adam@foo.com>; Tue, 25 Oct 2005 07:26:53 -0400 Message-ID: <blah@foo.com> Date: Tue, 25 Oct 2005 07:30:17 -0400 From: x <x@foo.com> Reply-To: x@foo.com User-Agent: Mozilla Thunderbird 1.0.6 (Windows/20050716) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Adam Worrall <adam@foo.com> Subject: My subject X-Enigmail-Version: 0.91.0.0 Content-Type: multipart/mixed; boundary="------------040701020305070002070307" X-PMX-Version: 4.6.1.107272 X-Virus-Scanned: by amavisd-new at foo.com This is a multi-part message in MIME format. --------------040701020305070002070307 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Blah blah --------------040701020305070002070307--
From: rjbs [...] cpan.org
Attached is a patch using Adam's fix (mostly). It also adds tests, including (oops) unrelated tests for messages with no body.
diff -Nur Email-Simple-1.92/Changes Email-Simple-1.94/Changes --- Email-Simple-1.92/Changes 2004-11-11 20:09:33.000000000 -0500 +++ Email-Simple-1.94/Changes 2006-07-03 19:59:55.000000000 -0400 @@ -1,5 +1,10 @@ Revision history for Perl extension Email::Simple. +1.94 2006-07-03 + + - Fix folding of long headers with \r as line ending (thanks Adam Worrall) + - add tests for message with no body + 1.92 2004-11-11 - Update dependencies. diff -Nur Email-Simple-1.92/MANIFEST Email-Simple-1.94/MANIFEST --- Email-Simple-1.92/MANIFEST 2004-07-11 17:06:59.000000000 -0400 +++ Email-Simple-1.94/MANIFEST 2006-07-03 19:57:34.000000000 -0400 @@ -7,7 +7,11 @@ t/2.t t/3.t t/4.t +t/badly-folded.t +t/no-body.t +t/test-mails/badly-folded t/test-mails/josey-fold +t/test-mails/josey-nobody t/test-mails/josey-nofold t/test-mails/long-msgid t/unit.t diff -Nur Email-Simple-1.92/Simple.pm Email-Simple-1.94/Simple.pm --- Email-Simple-1.92/Simple.pm 2004-11-11 20:08:33.000000000 -0500 +++ Email-Simple-1.94/Simple.pm 2006-07-03 19:54:13.000000000 -0400 @@ -5,7 +5,7 @@ use Carp; use vars qw($VERSION $GROUCHY); -$VERSION = '1.92'; +$VERSION = '1.94'; my $crlf = qr/\x0a\x0d|\x0d\x0a|\x0a|\x0d/; # We are liberal in what we accept. # But then, so is a six dollar whore. @@ -218,8 +218,8 @@ my @stuff = @$data; # Ignore "empty" headers return '' unless @stuff = grep { defined $_ } @stuff; - return join "", map { $_ = "$field: $_$self->{mycrlf}"; - length > 78 ? $self->_fold($_) : $_ } + return join "", map { length > 78 ? $self->_fold($_) : "$_$self->{mycrlf}" } + map { "$field: $_" } @stuff; } diff -Nur Email-Simple-1.92/t/badly-folded.t Email-Simple-1.94/t/badly-folded.t --- Email-Simple-1.92/t/badly-folded.t 1969-12-31 19:00:00.000000000 -0500 +++ Email-Simple-1.94/t/badly-folded.t 2006-07-03 19:53:09.000000000 -0400 @@ -0,0 +1,19 @@ +#!perl -w +use strict; +use Test::More tests => 2; + +# This time, with folding! + +use_ok("Email::Simple"); +sub read_file { local $/; local *FH; open FH, shift or die $!; return <FH> } + +my $mail_text = read_file("t/test-mails/badly-folded"); + +my $msg1 = Email::Simple->new($mail_text); +my $msg2 = Email::Simple->new($msg1->as_string); + +is( + $msg2->header('X-Sieve'), + 'CMU Sieve 2.2', + "still have X-Sieve header after round trip", +); diff -Nur Email-Simple-1.92/t/no-body.t Email-Simple-1.94/t/no-body.t --- Email-Simple-1.92/t/no-body.t 1969-12-31 19:00:00.000000000 -0500 +++ Email-Simple-1.94/t/no-body.t 2006-07-03 19:46:14.000000000 -0400 @@ -0,0 +1,25 @@ +#!perl -w +use strict; +use Test::More tests => 4; + +# This time, with folding! + +use_ok("Email::Simple"); +sub read_file { local $/; local *FH; open FH, shift or die $!; return <FH> } + +my $mail_text = read_file("t/test-mails/josey-nobody"); + +my $mail = Email::Simple->new($mail_text); +isa_ok($mail, "Email::Simple"); + +is( + $mail->header('From'), + 'Andrew Josey <ajosey@rdg.opengroup.org>', + 'correct From header on bodyless message', +); + +SKIP: { + skip "no alarm() on win32", 1 if $^O =~ /mswin32/i; + alarm 5; + ok($mail->as_string(), "doesn't hang"); +}; diff -Nur Email-Simple-1.92/t/test-mails/badly-folded Email-Simple-1.94/t/test-mails/badly-folded --- Email-Simple-1.92/t/test-mails/badly-folded 1969-12-31 19:00:00.000000000 -0500 +++ Email-Simple-1.94/t/test-mails/badly-folded 2006-07-03 19:47:43.000000000 -0400 @@ -0,0 +1,48 @@ +Return-Path: <sundar@foo.com> +Received: from murder ([unix socket]) + (authenticated user=adam bits=0) + by mail1.foo.com (Cyrus v2.2.12-OS X 10.4.0) with LMTPA; + Tue, 25 Oct 2005 07:26:59 -0400 +X-Sieve: CMU Sieve 2.2 +X-Original-To: adam@mail1.internal.foo.com +Delivered-To: adam@mail1.internal.foo.com +Received: from localhost (localhost [127.0.0.1]) + by mail1.foo.com (Postfix) with ESMTP id C24ABADEA15 + for <adam@mail1.internal.foo.com>; Tue, 25 Oct 2005 07:26:58 -0400 (EDT) +Received: from mail1.foo.com ([127.0.0.1]) + by localhost (localhost [127.0.0.1]) (amavisd-new, port 10024) with ESMTP + id 20330-05 for <adam@mail1.internal.foo.com>; + Tue, 25 Oct 2005 07:26:55 -0400 (EDT) +Received: from mta.internal.foo.com (mta.internal.foo.com [0.0.0.0]) + by mail1.foo.com (Postfix) with ESMTP id 1D919ADE9FE + for <adam@mail1.internal.foo.com>; Tue, 25 Oct 2005 07:26:55 -0400 (EDT) +Received: from [0.0.0.0] ([0.0.0.0]) + (authenticated bits=0) + by mta.internal.foo.com (8.12.8/8.12.8) with ESMTP id j9PBQoCT026374 + (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) + for <adam@foo.com>; Tue, 25 Oct 2005 07:26:53 -0400 +Message-ID: <blah@foo.com> +Date: Tue, 25 Oct 2005 07:30:17 -0400 +From: x <x@foo.com> +Reply-To: x@foo.com +User-Agent: Mozilla Thunderbird 1.0.6 (Windows/20050716) +X-Accept-Language: en-us, en +MIME-Version: 1.0 +To: Adam Worrall <adam@foo.com> +Subject: My subject +X-Enigmail-Version: 0.91.0.0 +Content-Type: multipart/mixed; + boundary="------------040701020305070002070307" +X-PMX-Version: 4.6.1.107272 +X-Virus-Scanned: by amavisd-new at foo.com + +This is a multi-part message in MIME format. +--------------040701020305070002070307 +Content-Type: text/plain; charset=ISO-8859-1 +Content-Transfer-Encoding: 7bit + +Blah blah + +--------------040701020305070002070307-- + + diff -Nur Email-Simple-1.92/t/test-mails/josey-nobody Email-Simple-1.94/t/test-mails/josey-nobody --- Email-Simple-1.92/t/test-mails/josey-nobody 1969-12-31 19:00:00.000000000 -0500 +++ Email-Simple-1.94/t/test-mails/josey-nobody 2006-07-03 19:46:14.000000000 -0400 @@ -0,0 +1,18 @@ +Received: (qmail 1679 invoked by uid 503); 13 Nov 2002 10:10:49 -0000 +Resent-Date: 13 Nov 2002 10:10:49 -0000 +Date: Wed, 13 Nov 2002 10:06:51 GMT +From: Andrew Josey <ajosey@rdg.opengroup.org> +Message-Id: <1021113100650.ZM12997@skye.rdg.opengroup.org> +In-Reply-To: Joanna Farley's message as of Nov 13, 9:56am. +X-Mailer: Z-Mail (5.0.0 30July97) +To: austin-group-l@opengroup.org +Subject: Re: Defect in XBD lround +MIME-Version: 1.0 +Resent-Message-ID: <gZGK1B.A.uY.iUi09@mailman> +Resent-To: austin-group-l@opengroup.org +Resent-From: austin-group-l@opengroup.org +X-Mailing-List: austin-group-l:archive/latest/4823 +X-Loop: austin-group-l@opengroup.org +Precedence: list +Resent-Sender: austin-group-l-request@opengroup.org +Content-Type: text/plain; charset=us-ascii
fixed and released -- rjbs