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

MimePart.FileName is null #106

Closed
michaeldtaylor opened this issue Mar 10, 2015 · 14 comments
Closed

MimePart.FileName is null #106

michaeldtaylor opened this issue Mar 10, 2015 · 14 comments
Labels
enhancement New feature or request

Comments

@michaeldtaylor
Copy link

Hi,

We're building an e-mail scanning tool and have had a few emails come to us with MIME attachments in the format:

--001a11c2a080ffa4f305100f379e
Content-Type: application/pdf; name=Test;
Content-Disposition: attachment; filename=Test;
Content-Transfer-Encoding: base64;

When we load the email payload using MimeKit 1.0.9.0:

MimeMessage.Load(...); // Load sample EML from embedded resource etc

The attachment is present, but the file name is null. If you add quotes:

--001a11c2a080ffa4f305100f379e
Content-Type: application/pdf; name="Test";
Content-Disposition: attachment; filename="Test";
Content-Transfer-Encoding: base64;

Then the file name is "Test". I tried setting the various ParserOptions to Loose and nothing worked. Obviously we can work around this in our code, but clients like Thunderbird and Outlook show the attachments with their file names correctly without needing the quotes. I'm not sure if this is strictly a bug as I haven't studied to spec in depth, but seems like it can happen in the Wild (our example email was an document sent as attachment using Google Docs). We believe it might happen with the OS X mail client in certain situations too.

Is this something you know about? Any plans to fix it?

Thanks,

Michael Taylor

@jstedfast
Copy link
Owner

I'm not able to replicate this bug and I've added a unit test to verify my findings...

Can you send me a test case?

@jstedfast
Copy link
Owner

btw, this is invalid:

Content-Transfer-Encoding: base64;

The trailing ; is not allowed. I don't think that has any relation to the bug you are seeing, but it's something you may want to look into (if you code is generating these messages).

@jstedfast
Copy link
Owner

Here's a simple test case I used to try and reproduce this bug:

using System;
using System.IO;
using System.Text;

using MimeKit;

namespace FileNameTest {
    class Program {
        static void Main ()
        {
            const string mime = @"Content-Type: application/pdf; name=Test;
Content-Disposition: attachment; filename=Test;
Content-Transfer-Encoding: base64;

This is the content.
";

            using (var stream = new MemoryStream (Encoding.ASCII.GetBytes (mime), false)) {
                var entity = (MimePart) MimeEntity.Load (stream);

                Console.WriteLine ("FileName = {0}", entity.FileName);
            }
        }
    }
}

Here's the output:

[fejj@localhost net40]$ mcs filename.cs -r:MimeKit
[fejj@localhost net40]$ mono ./filename.exe 
FileName = Test

@michaeldtaylor
Copy link
Author

Hi Jeff,

I’m not sure why your test is working and mine isn’t. It must be something to do with the rest of the payload.

Mine fails when parsing the attached email with the following test:

public class MimeKitTests
    {
        [Test]
        public void When_Loading_GoogleDocs_Email_Then_Can_Parse_Attachments()
        {
            // Arrange
            const string emailFileName = "GoogleDocsWithFileNameProblem.eml";

            // Act
            var email = EmbeddedResourceTemplateLoader.LoadTemplate(emailFileName);

            MimeMessage mimeMessage;

            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(email)))
            {
                mimeMessage = MimeMessage.Load(stream);
            }

            // Assert
            mimeMessage.BodyParts.Any(b => b.FileName == "Test Glasswall").Should().BeTrue();
        }
   }

This test uses NUnit/FluentAssertions.

The file: “Updating to Windows 8.pdf” has a FileName, but “Test Glasswall” attachment has a null file name.

The resource loader doesn’t really do anything special. The meat of it is:

            using (var stream = assembly.GetManifestResourceStream(name))
            {
                if (stream == null)
                {
                    throw new MissingTemplateException(templateName);
                }

                using (var streamReader = new StreamReader(stream))
                {
                    return streamReader.ReadToEnd();
                }
            }

Your previous email:

btw, this is invalid:

Content-Transfer-Encoding: base64;

The trailing ; is not allowed. I don't think that has any relation to the bug you are seeing, but it's something you may want to look into (if you code is generating these messages).

Unfortunately, that wasn’t up to me – the email was sent through Google Docs. All we do is use MimeKit to look at the attachments and process them. FileName is null in this case – I tried various things like removing ‘;’ but the only thing that makes it work is adding the quotes around ‘filename’ and ‘name’.

@jstedfast
Copy link
Owner

Unfortunately your email reply did not post the sample messages to GitHub so I'm not sure how to get them (assuming you didn't forget to attach them).

@michaeldtaylor
Copy link
Author

I replied to your email - hence the formatting wasn't very good. I tried to apply markdown after the fact to no avail. No idea how to add a file so I added it here: http://chopapp.com/#rgqqcxay

@jstedfast
Copy link
Owner

Does the header look something more like this?

Content-Type: application/pdf; name=filename with spaces.pdf;
Content-Disposition: attachment; filename=filename with spaces.pdf;
Content-Transfer-Encoding: base64;

If so, the problem is because of the spaces which are strictly not allowed.

@michaeldtaylor
Copy link
Author

Yes, there are spaces so my original example was bad (I was trying to anonymise somewhat). I don't know how the email got created in this way by Google Docs - it was a payload submitted by our customer.

Opening this email in Outlook shows both files with file names (it even appends .pdf), so I'm guessing that Outlook is being less strict about spaces and quotes. As I say, I changed the ParserOptions to Loose and I still get this problem.

I can (and have) worked around it, but if this does work in Outlook and other clients, should it not work in Loose mode?

@michaeldtaylor
Copy link
Author

Here is another example generated by the Mac Mail client. Notice that the file name has spaces but no quotes: http://chopapp.com/#hamwf7uf

PS - don't worry, its not a real virus attached

@jstedfast
Copy link
Owner

For future reference to myself, I'm going to paste the relevant header block from your link:

Content-Type: application/pdf; name=Test Glasswall;
Content-Disposition: attachment; filename=Test Glasswall;
Content-Transfer-Encoding: base64;
X-Attachment-Id: 1494254752197797452-local0;

I'm working on a patch to add a ParserOptions.ParameterParserComplianceMode such that Loose will handle this (and I'll be making Loose the default like I do for the others).

jstedfast added a commit that referenced this issue Mar 10, 2015
@michaeldtaylor
Copy link
Author

Great, thanks.

jstedfast added a commit that referenced this issue Mar 10, 2015
They shouldn't be there in the first place, but the joys of working
with messages generated by broken mailers is the like a gift that
keeps on giving.

See issue #106 for details.
@jstedfast
Copy link
Owner

I committed a fix that will deal with the trailing ; after the base64 value as well.

BTW, ended up calling it ParameterComplianceMode instead of ParameterParserComplianceMode - I figured 'Parser' was redundant and also because it's shorter :-)

@jstedfast jstedfast added the enhancement New feature or request label Mar 10, 2015
@jstedfast
Copy link
Owner

I just released MimeKit 1.0.10 to NuGet.

@michaeldtaylor
Copy link
Author

Great thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants