Skip to content

Commit

Permalink
Implemented a better fix for issue #443
Browse files Browse the repository at this point in the history
  • Loading branch information
jstedfast committed Oct 26, 2018
1 parent 621ad1b commit b377332
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
5 changes: 5 additions & 0 deletions MimeKit/AsyncMimeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ async Task<MimeParserState> StepAsync (CancellationToken cancellationToken)
case MimeParserState.MessageHeaders:
case MimeParserState.Headers:
await StepHeadersAsync (cancellationToken).ConfigureAwait (false);
toplevel = false;
break;
}

Expand Down Expand Up @@ -509,6 +510,8 @@ async Task<BoundaryType> ConstructMultipartAsync (Multipart multipart, Cancellat
stream.Seek (offset, SeekOrigin.Begin);

state = MimeParserState.Headers;
toplevel = true;

if (await StepAsync (cancellationToken).ConfigureAwait (false) == MimeParserState.Error)
throw new FormatException ("Failed to parse entity headers.");

Expand Down Expand Up @@ -570,6 +573,8 @@ async Task<BoundaryType> ConstructMultipartAsync (Multipart multipart, Cancellat
}
}

toplevel = true;

// parse the headers
if (state < MimeParserState.Content && await StepAsync (cancellationToken).ConfigureAwait (false) == MimeParserState.Error)
throw new FormatException ("Failed to parse message headers.");
Expand Down
34 changes: 24 additions & 10 deletions MimeKit/MimeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ public partial class MimeParser : IEnumerable<MimeMessage>
MimeParserState state;
MimeFormat format;
bool persistent;
bool toplevel;
bool eos;

ParserOptions options;
Expand Down Expand Up @@ -330,9 +331,11 @@ public void SetStream (ParserOptions options, Stream stream, MimeFormat format,
contentEnd = 0;

offset = stream.CanSeek ? stream.Position : 0;
preHeaderLength = 0;
headers.Clear ();
headerOffset = 0;
headerIndex = 0;
toplevel = false;
eos = false;

bounds.Clear ();
Expand Down Expand Up @@ -748,6 +751,7 @@ unsafe bool StepHeaders (byte* inbuf, ref bool scanningFieldName, ref bool check
if (IsBlank (*inptr)) {
blank = true;
} else if (blank || IsControl (*inptr)) {
char c = (char) *inptr;
valid = false;
break;
}
Expand All @@ -771,7 +775,7 @@ unsafe bool StepHeaders (byte* inbuf, ref bool scanningFieldName, ref bool check
if (!valid) {
length = inptr - start;

if (format == MimeFormat.Mbox && length >= 5 && IsMboxMarker (start)) {
if (format == MimeFormat.Mbox && inputIndex >= contentEnd && length >= 5 && IsMboxMarker (start)) {
// we've found the start of the next message...
inputIndex = (int) (start - inbuf);
state = MimeParserState.Complete;
Expand All @@ -782,14 +786,14 @@ unsafe bool StepHeaders (byte* inbuf, ref bool scanningFieldName, ref bool check
if (headers.Count == 0) {
if (state == MimeParserState.MessageHeaders) {
// ignore From-lines that might appear at the start of a message
if (length < 5 || !IsMboxMarker (start, true)) {
if (toplevel && (length < 5 || !IsMboxMarker (start, true))) {
// not a From-line...
inputIndex = (int) (start - inbuf);
state = MimeParserState.Error;
headerIndex = 0;
return false;
}
} else if (state == MimeParserState.Headers) {
} else if (toplevel && state == MimeParserState.Headers) {
inputIndex = (int) (start - inbuf);
state = MimeParserState.Error;
headerIndex = 0;
Expand Down Expand Up @@ -839,18 +843,23 @@ unsafe bool StepHeaders (byte* inbuf, ref bool scanningFieldName, ref bool check

length = (inptr + 1) - start;

if (!valid && headers.Count == 0 && length >= 5 && IsMboxMarker (start, true)) {
if (inptr[-1] == (byte) '\r')
if (!valid && headers.Count == 0) {
if (length > 0 && preHeaderLength == 0) {
if (inptr[-1] == (byte) '\r')
length--;
length--;
length--;

preHeaderLength = (int) length;
preHeaderLength = (int) length;

if (preHeaderLength > preHeaderBuffer.Length)
Array.Resize (ref preHeaderBuffer, NextAllocSize (preHeaderLength));
if (preHeaderLength > preHeaderBuffer.Length)
Array.Resize (ref preHeaderBuffer, NextAllocSize (preHeaderLength));

Buffer.BlockCopy (input, (int) (start - inbuf), preHeaderBuffer, 0, preHeaderLength);
Buffer.BlockCopy (input, (int) (start - inbuf), preHeaderBuffer, 0, preHeaderLength);
}
scanningFieldName = true;
checkFolded = false;
blank = false;
valid = true;
} else {
AppendRawHeaderData ((int) (start - inbuf), (int) length);
checkFolded = true;
Expand Down Expand Up @@ -974,6 +983,7 @@ unsafe MimeParserState Step (byte* inbuf, CancellationToken cancellationToken)
case MimeParserState.MessageHeaders:
case MimeParserState.Headers:
StepHeaders (inbuf, cancellationToken);
toplevel = false;
break;
}

Expand Down Expand Up @@ -1477,6 +1487,8 @@ unsafe MimeEntity ParseEntity (byte* inbuf, CancellationToken cancellationToken)
stream.Seek (offset, SeekOrigin.Begin);

state = MimeParserState.Headers;
toplevel = true;

if (Step (inbuf, cancellationToken) == MimeParserState.Error)
throw new FormatException ("Failed to parse entity headers.");

Expand Down Expand Up @@ -1547,6 +1559,8 @@ unsafe MimeMessage ParseMessage (byte* inbuf, CancellationToken cancellationToke
}
}

toplevel = true;

// parse the headers
if (state < MimeParserState.Content && Step (inbuf, cancellationToken) == MimeParserState.Error)
throw new FormatException ("Failed to parse message headers.");
Expand Down
1 change: 1 addition & 0 deletions UnitTests/TestData/mbox/jwz.mbox.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6595,6 +6595,7 @@ a
--PART.BOUNDARY.2418.16114.COSMOS.VLSI.CS.CMU.EDU.715029153.2
Content-type: message/rfc822

26-Aug-92 22:15:02-LCL,22076;000000000000
Received: from po3.andrew.cmu.edu by COSMOS.VLSI.CS.CMU.EDU id aa13358;
26 Aug 92 22:14:26 EDT
Received: from sqhilton.pc.cs.cmu.edu by po3.andrew.cmu.edu (5.54/3.15) id <AA21478> for [email protected]; Wed, 26 Aug 92 22:14:07 EDT
Expand Down

0 comments on commit b377332

Please sign in to comment.