diff --git a/MimeKit/Multipart.cs b/MimeKit/Multipart.cs index 3d6224a144..6cc74171ed 100644 --- a/MimeKit/Multipart.cs +++ b/MimeKit/Multipart.cs @@ -423,10 +423,14 @@ public override void Prepare (EncodingConstraint constraint, int maxLineLength = if (cancellable != null) { for (int i = 0; i < children.Count; i++) { + var part = children[i] as MimePart; + cancellable.Write (boundary, 0, boundary.Length - 2, cancellationToken); cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); children[i].WriteTo (options, stream, false, cancellationToken); - cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); + + if (part == null || (part.ContentObject != null && part.ContentObject.Stream.Length != 0)) + cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); } cancellable.Write (boundary, 0, boundary.Length, cancellationToken); @@ -435,11 +439,15 @@ public override void Prepare (EncodingConstraint constraint, int maxLineLength = cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); } else { for (int i = 0; i < children.Count; i++) { + var part = children[i] as MimePart; + cancellationToken.ThrowIfCancellationRequested (); stream.Write (boundary, 0, boundary.Length - 2); stream.Write (options.NewLineBytes, 0, options.NewLineBytes.Length); children[i].WriteTo (options, stream, false, cancellationToken); - stream.Write (options.NewLineBytes, 0, options.NewLineBytes.Length); + + if (part == null || (part.ContentObject != null && part.ContentObject.Stream.Length != 0)) + stream.Write (options.NewLineBytes, 0, options.NewLineBytes.Length); } cancellationToken.ThrowIfCancellationRequested (); diff --git a/UnitTests/MimeMessageTests.cs b/UnitTests/MimeMessageTests.cs index dc3bc6dcb4..53c723771f 100644 --- a/UnitTests/MimeMessageTests.cs +++ b/UnitTests/MimeMessageTests.cs @@ -103,6 +103,51 @@ [An Andrew ToolKit view (mailobjv) was included here, but could not be --Alternative.Boundary.IeCBvV20M2Yt4oU=wd-- +--Interpart.Boundary.IeCBvV20M2YtEoUA0A-- +"; + string result; + + using (var source = new MemoryStream (Encoding.UTF8.GetBytes (rawMessageText.Replace ("\r\n", "\n")))) { + var parser = new MimeParser (source, MimeFormat.Default); + var message = parser.ParseMessage (); + + using (var serialized = new MemoryStream ()) { + var options = FormatOptions.Default.Clone (); + options.NewLineFormat = NewLineFormat.Unix; + + message.WriteTo (options, serialized); + + result = Encoding.UTF8.GetString (serialized.ToArray ()); + } + } + + Assert.AreEqual (rawMessageText, result, "Reserialized message is not identical to the original."); + } + + [Test] + public void TestReserializationEmptyPart () + { + const string rawMessageText = @"Date: Fri, 12 Jun 1992 13:29:05 -0400 (EDT) +From: Nathaniel Borenstein +X-Andrew-Message-Size: 152+1 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary=""Interpart.Boundary.IeCBvV20M2YtEoUA0A"" +To: Ned Freed , + ysato@etl.go.jp (Yutaka Sato =?ISO-2022-JP?B?GyRAOjRGI0stGyhK?= ) +Subject: MIME & int'l mail + +> THIS IS A MESSAGE IN 'MIME' FORMAT. Your mail reader does not support MIME. +> Please read the first section, which is plain text, and ignore the rest. + +--Interpart.Boundary.IeCBvV20M2YtEoUA0A +Content-type: text/plain; charset=US-ASCII + +This is the body. + +--Interpart.Boundary.IeCBvV20M2YtEoUA0A +Content-type: text/plain; charset=US-ASCII; name=empty.txt + --Interpart.Boundary.IeCBvV20M2YtEoUA0A-- "; string result;