[Mimedefang] [PATCH] MIME-tools-6.200_02

Martin Blapp mb at imp.ch
Sat Jul 31 07:29:34 EDT 2004


Hi,

I ported the MaxParts patch to MIME-tools-6.200. There were some
minor parts to adjust. The other needed patches seem to be already there.

There are two parts where I'm not sure what to do. The FreeBSD
ports system has them, the MIMEdefang patched version on the
mainpage not:

 sub process_header {
@@ -612,6 +614,10 @@
     foreach (@headlines) { s/[\r\n]+\Z/\n/ }  ### fold

     ### How did we do?
+    if ($hdr_rdr->eos_type eq 'DELIM') {
+       $self->whine("bogus part, without CRLF before body");
+       return;
+    }

  sub process_part {
@@ -983,7 +989,17 @@

     ### Parse and add the header:
     my $head = $self->process_header($in, $rdr);
-    $ent->head($head);
+    if (not defined $head) {
+       $self->debug("bogus empty part");
+       $head = $self->interface('HEAD_CLASS')->new;
+       $head->mime_type('text/plain; charset=US-ASCII');
+       $ent->head($head);
+       $ent->bodyhandle($self->new_body_for($head));
+       $ent->bodyhandle->open("w")->close;
+       $self->results->level(-1);
+       return $ent;
+    }
+    $ent->head($head);

Do you know if they are needed David ?

Martin

Martin Blapp, <mb at imp.ch> <mbr at FreeBSD.org>
------------------------------------------------------------------
ImproWare AG, UNIXSP & ISP, Zurlindenstrasse 29, 4133 Pratteln, CH
Phone: +41 61 826 93 00 Fax: +41 61 826 93 01
PGP: <finger -l mbr at freebsd.org>
PGP Fingerprint: B434 53FC C87C FE7B 0A18 B84C 8686 EF22 D300 551E
------------------------------------------------------------------
-------------- next part --------------
--- lib/MIME/Parser.pm.orig	Sat Jul 31 12:03:36 2004
+++ lib/MIME/Parser.pm	Sat Jul 31 13:07:38 2004
@@ -294,6 +294,7 @@
     $self->{MP_TmpToCore}       = 0;
     $self->{MP_IgnoreErrors}    = 1;
     $self->{MP_UseInnerFiles}   = 0;
+    $self->{MP_MaxParts}       = -1;
 
 
 
@@ -358,6 +359,7 @@
     ### Re-init the filer:
     $self->{MP_Filer}->purgeable([]);   ### too late now, kids!
     $self->{MP_Filer}->init_parse();
+    $self->{MP_NumParts} = 0;
 
     ### Clear the TO-DO list:
     $self->{MP_ToDo} = [];
@@ -749,6 +751,8 @@
 #
 # I<Instance method.>
 # Process and return the next header.
+# Return undef if, instead of a header, the encapsulation boundary is found.
+# Fatal exception on failure.
 # The PARAMHASH can contain:
 #
 #    In      => required: the input filehandle
@@ -917,6 +921,7 @@
 				       Reader  => $part_rdr,
 				       Retype  => $retype,
 				       PartNum => $partno);
+	return undef unless defined($part);
 	$ent->add_part($part);
 
 	### ...and look at how we finished up:
@@ -1132,6 +1137,7 @@
 
     ### Parse the message:
     my $msg = $self->process_part(In=>$in, Reader=>$rdr);
+    return undef unless defined($msg);
 
     ### How to handle nested messages?
     if ($self->extract_nested_messages eq $EXTRACT_REPLACE) {
@@ -1172,6 +1178,14 @@
     my $retype  = $p{Retype};
     my $partnum = $p{PartNum} || 1;
 
+    if ($self->{MP_MaxParts} > 0) {
+	$self->{MP_NumParts}++;
+	if ($self->{MP_NumParts} > $self->{MP_MaxParts}) {
+		# Return UNDEF if msg too complex
+		return undef;
+	}
+    }
+
     ### Start logging:
     #$self->logger->push_prefix("part $partnum");
 
@@ -1183,6 +1197,7 @@
     my $head = $self->process_header(In     => $in, 
 				     Reader => $rdr,
 				     NoBody => \$no_body);
+
     $ent->head($head);
 
     ### Tweak the content-type based on context from our parent...
@@ -1204,13 +1219,13 @@
 
 	### Classify... how should we parse it?
 	if    ($classify eq $CLASS_MULTIPART) {
-	    $self->process_multipart(  In=>$in, Reader=>$rdr, Entity=>$ent);
+	    return undef unless defined($self->process_multipart(  In=>$in, Reader=>$rdr, Entity=>$ent));
 	}
 	elsif ($classify eq $CLASS_MESSAGE) {
-	    $self->process_message(    In=>$in, Reader=>$rdr, Entity=>$ent);
+	    return undef unless defined($self->process_message(    In=>$in, Reader=>$rdr, Entity=>$ent));
 	}
 	elsif ($classify eq $CLASS_SINGLEPART) {
-	    $self->process_singlepart( In=>$in, Reader=>$rdr, Entity=>$ent);
+	    return undef unless defined($self->process_singlepart( In=>$in, Reader=>$rdr, Entity=>$ent));
 	}
 	else {
 	    internal_error "unknown classification '$classify'";
@@ -1374,7 +1389,6 @@
 =back
 
 Returns the parsed MIME::Entity on success.
-Throws exception on failure.
 
 =cut
 
@@ -1412,8 +1426,8 @@
 or as I<any> blessed object conforming to the IO:: interface
 (which minimally implements getline() and read()).
 
-Returns the parsed MIME::Entity on success.
-Throws exception on failure.
+Throws exception on failure.  If the message contained too many
+parts (as set by I<max_parts>), returns undef.
 
 =cut
 
@@ -1946,6 +1960,32 @@
 sub last_head {
     usage_warning "deprecated: use \$parser->results->top_head\n";
     shift->results->top_head;
+}
+
+#------------------------------
+
+=item max_parts NUM
+
+I<Instance method.>
+Limits the number of MIME parts we will parse.
+
+Normally, instances of this class parse a message to the bitter end.
+Messages with many MIME parts can cause excessive memory consumption.
+If you invoke this method, parsing will abort with a die() if a message
+contains more than NUM parts.
+
+If NUM is set to -1 (the default), then no maximum limit is enforced.
+
+With no argument, returns the current setting as an integer
+
+=cut
+
+sub max_parts {
+    my($self, $num) = @_;
+    if (@_ > 1) {
+        $self->{MP_MaxParts} = $num;
+    }
+    return $self->{MP_MaxParts};
 }
 
 #------------------------------


More information about the MIMEDefang mailing list