Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MessageDeliveryStatus accessors throws "Failed to parse headers." if content doesn't end with a blank line #250

Closed
chessels opened this issue Jun 6, 2016 · 16 comments
Labels
compatibility Compatibility with existing software

Comments

@chessels
Copy link

chessels commented Jun 6, 2016

When the last status group in a message/delivery-status MIME part does not end with a blank line the MimeParser throws an "Failed to parse headers." exception when calling the MessageDeliveryStatus.StatusGroups property.

@jstedfast jstedfast changed the title MessageDeliveryStatus.StatusGroups throws "Failed to parse headers." MessageDeliveryStatus accessors throws "Failed to parse headers." if content doesn't end with a blank line Jun 6, 2016
jstedfast added a commit that referenced this issue Jun 6, 2016
@jstedfast
Copy link
Owner

This should be fixed now in git master.

@jstedfast jstedfast added the compatibility Compatibility with existing software label Jun 6, 2016
@chessels
Copy link
Author

chessels commented Jun 6, 2016

Thanks!

@jstedfast
Copy link
Owner

No prob, thanks for reporting this bug :)

@jstedfast
Copy link
Owner

I have published a new version of MimeKit that fixes this issue to nuget

@alex-jitbit
Copy link

@jstedfast after upgrading MailKit from 2.15 to latest 3.1.0 we started getting the same `Failed to parse headers" exception when trying to access "StatusGroups"

System.FormatException: Failed to parse headers.
   at MimeKit.MimeParser.ParseHeaders(Byte* inbuf, CancellationToken cancellationToken)
   at MimeKit.MessageDeliveryStatus.get_StatusGroups()

For messages that worked fine previously.

@jstedfast jstedfast reopened this Jan 25, 2022
@jstedfast
Copy link
Owner

Okay, I'll take a look

@jstedfast
Copy link
Owner

jstedfast commented Jan 25, 2022

@jitbit oddly I'm not getting an error if I modify the MessageDeliveryStatusTests.TestMimeParser() test data (aka delivery-status.txt) to remove the blank line at the end of the message/delivery-status part (before the rfc822 part).

Can you provide a sample that breaks?

@alex-jitbit
Copy link

I'm not 100% sure it's caused by line breaks or even connected to the original issue. But here's the .eml that breaks things:
https://www.dropbox.com/s/bssh4zalgyo2dv5/bounced.eml?dl=0

It's a standard bounce message sent by Outlook 365

It has a delivery status report in it, and here's the code that breaks:

var deliveryReport = message.BodyParts.Where(p => p.ContentType?.MediaSubtype == "delivery-status").FirstOrDefault();
var deliveryStatus = deliveryReport as MessageDeliveryStatus;

//this line causes exception "failed to parse headers"
var statusheaders = deliveryStatus != null
	? deliveryStatus.StatusGroups.SelectMany(g => g).SafeToDictionary(h => h.Field, h => h.Value)
	: new Dictionary<string, string>();

@jstedfast
Copy link
Owner

@jitbit I think I see the problem. It looks like the message/delivery-status contains content other than status groups (specifically, it contains 1 set of status-group headers and base64 content).

I'll take a look tonight at the spec (in case I missed something) and at figuring out a solution. Even if it's not legal, being that it's such a widely used server, it probably needs a work-around at least.

@alex-jitbit
Copy link

@jstedfast thanks a ton! Yes, it's pretty widely used, and we're getting reports like that every hour basically.

P.S. The error was not thrown in 2.15

@jstedfast
Copy link
Owner

@alex-jitbit I've successfully confirmed the "Cannot parse headers" exception.

@jstedfast
Copy link
Owner

@alex-jitbit is it ok if I end up including your test message as a unit test in MimeKit? Or should I try to scrub anything?

The issue is that the message/delivery-status content should be multiple blocks of headers (aka status groups), but after the first status group of headers, it's base64-encoded. Turns out the base64-encoded blob is the second status group of headers.

I've got a work-around that checks if the first status group of headers contains a Content-Transfer-Encoding, and if so, passes the remainder of the data thru a base64 decoder to parse the rest.

@alex-jitbit
Copy link

@jstedfast sure, please do

jstedfast added a commit that referenced this issue Jan 27, 2022
…encoded status groups

Fixes a followup bug report in issue #250
@jstedfast
Copy link
Owner

Should be fixed now in the myget builds. If you need me to, I'll make a new release probably tomorrow night.

@alex-jitbit
Copy link

@jstedfast Thanks for the quick fix!!

Yeah, a nuget update would be much appreciated, thanks for that too

@jstedfast
Copy link
Owner

Just released 3.1.1 with this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Compatibility with existing software
Projects
None yet
Development

No branches or pull requests

3 participants