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

AttachmentCollection.Add() needs to handle message/rfc822 parsing exceptions #1001

Closed
Sicos1977 opened this issue Feb 5, 2024 · 3 comments
Closed
Labels
bug Something isn't working

Comments

@Sicos1977
Copy link

Sicos1977 commented Feb 5, 2024

Using the latest MimeKit version,

When our system receives a e-mail it will try to process it. When this for whatever reason fails it forwards the message to another mailbox.

In this case I load the MimeMessage from Exchange Web Services and strip it apart in pieces... the body and attachments gets stored in a database. When I try to forward this message again I reassemble the message but this fails in the folowing case.

When the e-mail has another .EML file as an attachment and this attachment is corrupt (for whatever reason) then MimeKit throws the exception "Failed to parse message headers" ... this is correct because the file is corrupt. I can't prevent customers from sending corrupt attachments.

I debuged mimekit and tracked down the place where the exception is thrown.

at MimeKit.MimeParser.ParseMessage(Byte* inbuf, CancellationToken cancellationToken) at MimeKit.MimeParser.ParseMessage(CancellationToken cancellationToken) at MimeKit.MimeMessage.Load(ParserOptions options, Stream stream, Boolean persistent, CancellationToken cancellationToken) at MimeKit.AttachmentCollection.CreateAttachment(ContentType contentType, String path, Stream stream, Boolean copyStream, CancellationToken cancellationToken) at MimeKit.AttachmentCollection.Add(String fileName, Stream stream, CancellationToken cancellationToken) at Email2Storage.Server.BusinessLogic.Email.ToListOfMimeMessage(Boolean includeForwardReasons, Boolean includeForwardHeader, String forwardReasonsFileName, Int64 splitEmailMaxSize, Int32 splitEmailMaxMimeParts, String splitEmailSubjectPrefix, String splitEmailReason, String invalidEmailAddressReplacement, List1 headersToInclude, String referenceId) at Email2Storage.Services.Forwarding.ForwardingEmailWorker.d__31.MoveNext() | Failed to parse m
`

The attachment is called Declaratie [24.01.0071] [DUDOK_23.0364.01] 20240109_105801.eml

bodyBuilder.Attachments.Add(attachment.FileName, attachment.FileData);

This goes to

		public MimeEntity Add (string fileName, Stream stream, CancellationToken cancellationToken = default)
		{
			if (fileName is null)
				throw new ArgumentNullException (nameof (fileName));

			if (fileName.Length == 0)
				throw new ArgumentException ("The specified file path is empty.", nameof (fileName));

			if (stream is null)
				throw new ArgumentNullException (nameof (stream));

			var attachment = CreateAttachment (GetMimeType (fileName), fileName, stream, true, cancellationToken);

			attachments.Add (attachment);

			return attachment;
		}

That calls CreateAttachment

That triggers this if statement

if (contentType.IsMimeType ("message", "rfc822"))

That calls this

		public static MimeMessage Load (Stream stream, CancellationToken cancellationToken = default)
		{
			return Load (ParserOptions.Default, stream, false, cancellationToken);
		}

And in the end throws the exception because the EML file is just giberisch because it is corrupt.

@Sicos1977
Copy link
Author

Nevermind... I fixed it like this

                try
                {
                    bodyBuilder.Attachments.Add(attachment.FileName, attachment.FileData);
                }
                catch (FormatException)
                {
                    bodyBuilder.Attachments.Add(attachment.FileName, attachment.FileData, new MimeKit.ContentType("application", "octet-stream"));
                }

@jstedfast
Copy link
Owner

Interesting...

Arguably, MimeKit's AttachmentCollection code should better handle this scenario.

I'm going to reopen.

@jstedfast jstedfast reopened this Feb 5, 2024
@jstedfast jstedfast added the bug Something isn't working label Feb 5, 2024
@jstedfast
Copy link
Owner

I think that MimeKit should probably more-or-less handle this situation the way you've handled it.

@jstedfast jstedfast changed the title Failed to parse message headers AttachmentCollection.Add() needs to handle message/rfc822 parsing exceptions Feb 5, 2024
jstedfast added a commit that referenced this issue Feb 7, 2024
When adding a message/rfc822 stream, if the content fails to parse
as a MimeMessage, then fall back to attaching the content as
application/octet-stream.

This is only possible if the stream is seekable and if the mime-type
was auto-detected. If the user has specifically requested that we
attach as a message/rfc822, allow the FormatException to bubble back up
to our caller.

Fixes issue #1001
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants