I debugged my demo program and now I assume the problem is located in
the line concatenation of Email::MIME. The additional parameter is
located on a separate line:

>   Content-Type: multipart/related
>     ;boundary="E12E79A3A5A642B5BDEDBECB78526EFD"
>     ;type="text/html"

. The module concatenates the lines before parsing them, but preserves
some whitespace. The attributes part then reads *like* this:

    boundary="E12E79A3A5A642B5BDEDBECB78526EFD" ; type="text/html"

Please note the whitespace before the semi-colon. This whitespace
causes trouble when Email::MIME::_extract_ct_attribute_value() has
found an attribute value and tries to find out if everything is

    /^;/ and last;

Because the remaining string reads qq( ; type="text/html") at this
time, the method continues value aggregation and adds the additional
whitespace subsequently. Then when the value is used as a boundary
string it does not match because of the additional whitespace.

So, as a quick patch I suggest something like

  diff --git a/MIME/ContentType.pm b/MIME/ContentType.pm
  index a2afb45..89f6615 100644
  --- a/MIME/ContentType.pm
  +++ b/MIME/ContentType.pm
  @@ -71,7 +71,7 @@ sub _extract_ct_attribute_value { # EXPECTS AND MODIFIES $_
               my $sub = $1; $sub =~ s/^["']//; $sub =~ s/["']$//;
               $value .= $sub;
  -        /^;/ and last;
  +        /^\s*;/ and last;
           /^([$tspecials])/ and do {
               carp "Unquoted $1 not allowed in Content-Type!";

but I am not sure if this is the correct place. Possibly the
concatenation could be modified (but then, we still had problems
with valid whitespace around semi-colons within a line), or possibly
the function should return when it read a quoted value, as this
value should be complete.

Another approach was to patch Email::MIME itself where it uses the
boundary value, and to delete trailing whitespace:

   diff --git a/MIME.pm b/MIME.pm
   index 26a3c1f..f2d2428 100644
   --- a/MIME.pm
   +++ b/MIME.pm
   @@ -341,6 +341,10 @@ sub parts_multipart {
      my $self     = shift;
      my $boundary = $self->{ct}->{attributes}->{boundary};

   +  # boundary values happen to have trailing whitespace sometimes, remove it
   +  # - jstenzel, 2009-12-16
   +  $boundary =~ s/\s+$//;
      # Take a message, join all its lines together.  Now try to 
      # it with 1.861 or earlier.  Death!  It tries to recurse endlessly on the
      # body, because every time it splits on boundary it gets itself. Obviously

but this is fairly late and will affect boundary values only.

With both patches, the demo script analyzes the demo message correctly now.

Could the maintainers please have a look to see if one of these patches
is sufficient?

Thanks and regards


Reply via email to