diff --git a/MimeKit/Utils/Rfc2047.cs b/MimeKit/Utils/Rfc2047.cs index 80638c827c..a588f41370 100644 --- a/MimeKit/Utils/Rfc2047.cs +++ b/MimeKit/Utils/Rfc2047.cs @@ -813,8 +813,9 @@ public static string DecodeText (byte[] text) static byte[] FoldTokens (FormatOptions options, IList tokens, string field, byte[] input) { - var output = new StringBuilder (input.Length + 2); + var output = new StringBuilder (input.Length + ((input.Length / options.MaxLineLength) * 2) + 2); int lineLength = field.Length + 2; + var firstToken = true; int lwsp = 0, tab = 0; Token token; @@ -845,6 +846,8 @@ static byte[] FoldTokens (FormatOptions options, IList tokens, string fie output.Append (' '); lineLength = 1; } + + firstToken = false; } else if (token.Encoding != ContentEncoding.Default) { string charset = token.CharsetCulture; @@ -857,7 +860,7 @@ static byte[] FoldTokens (FormatOptions options, IList tokens, string fie // break just before the last lwsp character output.Insert (lwsp, options.NewLine); lineLength = 1; - } else if (lineLength > 1) { + } else if (lineLength > 1 && !firstToken) { // force a line break... output.Append (options.NewLine); output.Append (' '); @@ -875,6 +878,7 @@ static byte[] FoldTokens (FormatOptions options, IList tokens, string fie output.Append ("?="); lineLength += token.Length + charset.Length + 7; + firstToken = false; lwsp = 0; tab = 0; } else if (lineLength + token.Length > options.MaxLineLength) { @@ -886,7 +890,7 @@ static byte[] FoldTokens (FormatOptions options, IList tokens, string fie // break just before the last lwsp character output.Insert (lwsp, options.NewLine); lineLength = 1; - } else if (lineLength > 1) { + } else if (lineLength > 1 && !firstToken) { // force a line break... output.Append (options.NewLine); output.Append (' '); @@ -913,6 +917,7 @@ static byte[] FoldTokens (FormatOptions options, IList tokens, string fie lineLength += token.Length; } + firstToken = false; lwsp = 0; tab = 0; } else { @@ -920,6 +925,7 @@ static byte[] FoldTokens (FormatOptions options, IList tokens, string fie output.Append ((char) input[n]); lineLength += token.Length; + firstToken = false; lwsp = 0; tab = 0; } diff --git a/UnitTests/HeaderTests.cs b/UnitTests/HeaderTests.cs index aab2279b01..480f9f1004 100644 --- a/UnitTests/HeaderTests.cs +++ b/UnitTests/HeaderTests.cs @@ -147,6 +147,16 @@ public void TestMessageIdHeaderFolding () Assert.AreEqual (expected, raw, "The folded Message-Id header does not match the expected value."); } + [Test] + public void TestSubjectHeaderFolding () + { + const string expected = " =?utf-8?b?0KLQtdGB0YLQvtCy0YvQuSDQt9Cw0LPQvtC70L7QstC+0Log0L/QuNGB0YzQvNCw?=\n"; + var header = new Header ("Subject", "Тестовый заголовок письма"); + var actual = ByteArrayToString (header.RawValue).Replace ("\r", ""); + + Assert.AreEqual (expected, actual); + } + static readonly string[] ReceivedHeaderValues = { " from thumper.bellcore.com by greenbush.bellcore.com (4.1/4.7)" + FormatOptions.Default.NewLine + "\tid for nsb; Fri, 29 Nov 91 07:13:33 EST", " from joyce.cs.su.oz.au by thumper.bellcore.com (4.1/4.7)" + FormatOptions.Default.NewLine + "\tid for nsb@greenbush; Fri, 29 Nov 91 07:11:57 EST",