Skip to content

Commit

Permalink
Minor fix to unstructured header folding logic
Browse files Browse the repository at this point in the history
If the first token we get to exceeds the SUGGESTED line length (78),
don't add "\r\n " and then the token or we end up with:

Subject:<SPACE>
<SPACE><TOKEN>

Instead, temporarily ignore the SUGGESTED line length (78) and
forget the newline wrapping, thus producing:

Subject:<SPACE><TOKEN>

Partial fix for issue #451
  • Loading branch information
jstedfast committed Nov 30, 2018
1 parent 33c8fe1 commit cb114fb
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
12 changes: 9 additions & 3 deletions MimeKit/Utils/Rfc2047.cs
Original file line number Diff line number Diff line change
Expand Up @@ -813,8 +813,9 @@ public static string DecodeText (byte[] text)

static byte[] FoldTokens (FormatOptions options, IList<Token> 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;

Expand Down Expand Up @@ -845,6 +846,8 @@ static byte[] FoldTokens (FormatOptions options, IList<Token> tokens, string fie
output.Append (' ');
lineLength = 1;
}

firstToken = false;
} else if (token.Encoding != ContentEncoding.Default) {
string charset = token.CharsetCulture;

Expand All @@ -857,7 +860,7 @@ static byte[] FoldTokens (FormatOptions options, IList<Token> 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 (' ');
Expand All @@ -875,6 +878,7 @@ static byte[] FoldTokens (FormatOptions options, IList<Token> tokens, string fie
output.Append ("?=");

lineLength += token.Length + charset.Length + 7;
firstToken = false;
lwsp = 0;
tab = 0;
} else if (lineLength + token.Length > options.MaxLineLength) {
Expand All @@ -886,7 +890,7 @@ static byte[] FoldTokens (FormatOptions options, IList<Token> 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 (' ');
Expand All @@ -913,13 +917,15 @@ static byte[] FoldTokens (FormatOptions options, IList<Token> tokens, string fie
lineLength += token.Length;
}

firstToken = false;
lwsp = 0;
tab = 0;
} else {
for (int n = token.StartIndex; n < token.StartIndex + token.Length; n++)
output.Append ((char) input[n]);

lineLength += token.Length;
firstToken = false;
lwsp = 0;
tab = 0;
}
Expand Down
10 changes: 10 additions & 0 deletions UnitTests/HeaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <AA01648> 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 <AA11898> for nsb@greenbush; Fri, 29 Nov 91 07:11:57 EST",
Expand Down

0 comments on commit cb114fb

Please sign in to comment.