--- lib/MIME/Parser.pm.orig	2010-05-03 16:02:52.000000000 -0700
+++ lib/MIME/Parser.pm	2010-05-04 11:08:48.000000000 -0700
@@ -221,6 +221,7 @@
     $self->{MP5_UUDecode}        = 0;
     $self->{MP5_MaxParts}        = -1;
     $self->{MP5_TmpDir}          = undef;
+    $self->{MP5_AllowNoTrailingBoundary}    = 0;
 
     $self->interface(ENTITY_CLASS => 'MIME::Entity');
     $self->interface(HEAD_CLASS   => 'MIME::Head');
@@ -446,6 +447,28 @@
 
 #------------------------------
 
+=item allow_no_trailing_boundary [YESNO]
+
+I<Instance method.>
+Controls whether the parser will ignore the error of a missing
+trailing MIME boundary.
+
+If YESNO is true, the parser will ignore missing trailing MIME
+boundaries.
+If YESNO is false (the default), a missing trailing MIME
+boundary is a fatal error
+With no argument, just returns the current setting.
+
+=cut
+
+sub allow_no_trailing_boundary {
+    my ($self, $yesno) = @_;
+    $self->{MP5_AllowNoTrailingBoundary} = $yesno if (@_ > 1);
+    $self->{MP5_AllowNoTrailingBoundary};
+}
+
+#------------------------------
+
 =item decode_bodies [YESNO]
 
 I<Instance method.>
@@ -723,6 +746,7 @@
 	$eos_type = $part_rdr->eos_type;
 	if    ($eos_type eq 'DELIM') { $more_parts = 1 }
 	elsif ($eos_type eq 'CLOSE') { $more_parts = 0; }
+	elsif ($self->allow_no_trailing_boundary() && $eos_type eq 'EOF') { $more_parts = 0; }
 	else                         { $self->error("unexpected end of parts ".
 						    "before epilogue\n");
 				       return 1; }
@@ -774,9 +798,9 @@
 	### ...and look at how we finished up.
 	###     If we have bounds, we want DELIM or CLOSE.
 	###     Otherwise, we want EOF (and that's all we'd get, anyway!).
-	if ($rdr->has_bounds) {
+	if ((!$self->allow_no_trailing_boundary()) && ($rdr->has_bounds)) {
 	    ($rdr->eos_type =~ /^(DELIM|CLOSE)$/) or
-		$self->error("part did not end with expected boundary\n");
+	    $self->error("part did not end with expected boundary\n");
 	}
 
 	### Flush and rewind encoded buffer, so we can read it:
