Skip to content

Commit

Permalink
Added MimeParser tests for garbage before message/entity headers
Browse files Browse the repository at this point in the history
  • Loading branch information
jstedfast committed Jun 27, 2024
1 parent a4552bc commit 64c88d9
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
2 changes: 1 addition & 1 deletion MimeKit/AsyncMimeReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async Task StepHeadersAsync (CancellationToken cancellationToken)
if (await ReadAheadAsync (atleast, 0, cancellationToken).ConfigureAwait (false) < atleast)
break;
} while (true);
} else if (input[inputIndex] == (byte) 'F') {
} else if (input[inputIndex] == (byte) 'F' || input[inputIndex] == (byte) '>') {
// Check for an mbox-style From-line. Again, if the message is properly formatted and not truncated, this will NEVER happen.
do {
unsafe {
Expand Down
74 changes: 74 additions & 0 deletions UnitTests/ExperimentalMimeParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2571,6 +2571,80 @@ public async Task TestMimePartBasicAsync ()
}
}

[Test]
public void TestGarbageBeforeMessageHeaders ()
{
string text = @">F!&^#%&^
From: mimekit@example.com
To: mimekit@example.com
Subject: This message has garbage before the headers
Date: Tue, 12 Nov 2013 09:12:42 -0500
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
This is the message body.
".Replace ("\r\n", "\n");

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseMessage ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseMessage ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseMessageAsync ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseMessageAsync ());
}
}

[Test]
public void TestGarbageBeforeEntityHeaders ()
{
string text = @">F!&^#%&^
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
This is the message body.
".Replace ("\r\n", "\n");

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseEntity ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseEntity ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseEntityAsync ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new ExperimentalMimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseEntityAsync ());
}
}

static void AssertSimpleMbox (Stream stream)
{
var parser = new ExperimentalMimeParser (stream, MimeFormat.Mbox);
Expand Down
74 changes: 74 additions & 0 deletions UnitTests/MimeParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2555,6 +2555,80 @@ public async Task TestMimePartBasicAsync ()
}
}

[Test]
public void TestGarbageBeforeMessageHeaders ()
{
string text = @">F!&^#%&^
From: mimekit@example.com
To: mimekit@example.com
Subject: This message has garbage before the headers
Date: Tue, 12 Nov 2013 09:12:42 -0500
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
This is the message body.
".Replace ("\r\n", "\n");

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseMessage ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseMessage ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseMessageAsync ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseMessageAsync ());
}
}

[Test]
public void TestGarbageBeforeEntityHeaders ()
{
string text = @">F!&^#%&^
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
This is the message body.
".Replace ("\r\n", "\n");

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseEntity ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.Throws<FormatException> (() => parser.ParseEntity ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseEntityAsync ());
}

using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (text.Replace ("\n", "\r\n")), false)) {
var parser = new MimeParser (stream, MimeFormat.Entity);

Assert.ThrowsAsync<FormatException> (async () => await parser.ParseEntityAsync ());
}
}

static void AssertSimpleMbox (Stream stream)
{
var parser = new MimeParser (stream, MimeFormat.Mbox);
Expand Down

0 comments on commit 64c88d9

Please sign in to comment.