Upgrading MimeKit broke our email address parser

This article is intended for software developers or those interested in the code behind GMass.

GMass is written mostly in C# and JavaScript, and the C# backend makes heavy use of a popular email parsing component called MimeKit. In face, MimeKit, has become so popular that Microsoft is now recommending that developers use it as the standard instead of Microsoft’s own SmtpClient library.

Over the weekend, we updated some of the software components that GMass is built on in preparation for a big feature launch, and in doing so, we updated MimeKit from version 1.12 to the latest release 1.18. That upgrade unfortunately broke some of our email address validation code, and many users saw a “token offset” error as a result.

Here’s what happened. Previously, in version 1.12, the following scenarios would pass without throwing an exception:

MimeKit Sample 1
MimeKit Code Sample: These scenarios pass, and no exception is thrown.

After updating to version 1.18, the top two of the three scenarios do throw an exception:

MimeKit Sample 2
MimeKit Code Sample: After updating to version 1.18, these throw a parsing exception.

The impact on GMass is such that if you’re connecting to a Google Sheets spreadsheet, and your column containing email addresses has a bad data value that is an invalid email address, such as “test@test.com;test@test.com”, whereas before our code would handle this appropriately and eventually filter the bad entry out, now all of a sudden, our code was throwing an exception.

Making matters more complex was that the MimeKit TryParse didn’t always catch a string that could not be converted into a MimeKit.MailboxAddress object. For example:

MimeKit Sample 3
MimeKit Code Sample: TryParse returns true, but the string still can’t be converted to a MailboxAddress object.

In the above samples, TryParse returns false for “test@test.com;test@test.com” but returns true for “test<test@test.com>”. It returns true for the latter because it assumes that the part outside the angle brackets is the Name, and so Name=test and Address=test@test.com. Our code though attempts to create a MailboxAddress object from the whole string, and in this case, the parse into Name and Address doesn’t happen, as the constructor assumes that the entire string represents just the Address portion of the object.

We did check the Release Notes for MimeKit before deploying the update, but there was nothing indicating the change in email parsing rules. Still however, we are eternally grateful to Jeffrey Stedfast for building and maintaining the MimeKit library for the .NET framework. Without it, my job as a software developer parsing and assembling email messages would be far more difficult.


Leave a Reply

Your email address will not be published. Required fields are marked *