Re: Header folding

David A Golden <[email protected]> Wed, 18 Aug 2004 17:48:25 -0400
Newsgroups gmane.comp.lang.perl.modules.mail-box
Message-ID <5.2.0.9.2.20040818164000.00b69dd0@localhost>
Mark -- 

I looked a little further at this issue.  It appears to be a result of parsed fields not getting folded.  Also, the parser tries to make sure that every header field body ends in "\n", whereas  setWrapLength assumes that a field is already folded if called with no argument and if the body ends in "\n".  So just calling setWrapLength on parsed headers doesn't help as any parsed line is assumed to be folded.  

The patches below change the Perl parser to *never* put a trailing "\n" on headers -- these will only appear in the middle of a folded header.  setWrapLength now looks for any "\n", not just limited to one at the end (as there will now never be one on parsed text). Finally, the Mail::Message::Head::read() function is patched to call setWrapLength to force header folding on any unfolded headers longer than the default wrapping length.

These patches pass the test suite on Mail::Box version 2.056.  Since the logic of the Perl parser is changed slightly, the C parser will likely need to be changed to match.

Regards,
David

Index: Mail/Message/Field.pm
===================================================================
--- Mail/Message/Field.pm       (revision 3)
+++ Mail/Message/Field.pm       (working copy)
@@ -421,7 +421,7 @@
 {   my $self = shift;
 
     $self->[1] = $self->fold($self->[0],$self->unfoldedBody, @_)
-        if @_ || $self->[1] !~ m/\n$/;
+        if @_ || $self->[1] !~ m/\n/;
 
     $self;
 }
Index: Mail/Message/Head.pm
===================================================================
--- Mail/Message/Head.pm        (revision 3)
+++ Mail/Message/Head.pm        (working copy)
@@ -175,8 +175,11 @@
 
     my $type   = $self->{MMH_field_type} || 'Mail::Message::Field::Fast';
 
-    $self->addNoRealize($type->new( @$_ ))
-        foreach @fields;
+    for (@fields) {
+        my $new_field = $type->new( @$_ );
+        $new_field->setWrapLength();
+        $self->addNoRealize($new_field);
+    }
 
     $self;
 }
Index: Mail/Box/Parser/Perl.pm
===================================================================
--- Mail/Box/Parser/Perl.pm     (revision 3)
+++ Mail/Box/Parser/Perl.pm     (working copy)
@@ -79,11 +79,11 @@
             }
         }
 
-        $body = "\n" unless length $body;
+        chomp $body; # No trailing newlines
 
         # Collect folded lines
         while($line = $file->getline)
-        {   $line =~ m!^[ \t]! ? ($body .= $line) : last;
+        {   $line =~ m!^[ \t]! ? ($body .= "\n$line") : last;
         }
 
         $body =~ s/\015//g;