diff --git a/MimeKit/InternetAddress.cs b/MimeKit/InternetAddress.cs index 9bf27526a8..9f40bc2305 100644 --- a/MimeKit/InternetAddress.cs +++ b/MimeKit/InternetAddress.cs @@ -568,7 +568,7 @@ internal static bool TryParse (ParserOptions options, byte[] text, ref int index { bool strict = options.AddressParserComplianceMode == RfcComplianceMode.Strict; bool throwOnError = (flags & AddressParserFlags.ThrowOnError) != 0; - int minWordCount = options.AllowAddressesWithoutDomain ? 1 : 0; + int minWordCount = options.AllowUnquotedCommasInAddresses ? 0 : 1; address = null; @@ -662,6 +662,13 @@ internal static bool TryParse (ParserOptions options, byte[] text, ref int index return false; } + if (!options.AllowAddressesWithoutDomain) { + if (throwOnError) + throw new ParseException (string.Format ("Incomplete addr-spec token at offset {0}", startIndex), startIndex, index); + + return false; + } + // rewind back to the beginning of the local-part index = startIndex; diff --git a/MimeKit/ParserOptions.cs b/MimeKit/ParserOptions.cs index 82f4e62967..5133f83f4d 100644 --- a/MimeKit/ParserOptions.cs +++ b/MimeKit/ParserOptions.cs @@ -77,13 +77,23 @@ public class ParserOptions public RfcComplianceMode AddressParserComplianceMode { get; set; } /// - /// Gets or sets whether the rfc822 address parser should allow addresses without a domain. + /// Gets or sets whether the rfc822 address parser should ignore unquoted commas in address names. /// /// - /// In general, you'll probably want this value to be false (the default) as it allows + /// In general, you'll probably want this value to be true (the default) as it allows /// maximum interoperability with existing (broken) mail clients and other mail software such as /// sloppily written perl scripts (aka spambots) that do not properly quote the name when it /// contains a comma. + /// + /// true if the address parser should ignore unquoted commas in address names; otherwise, false. + public bool AllowUnquotedCommasInAddresses { get; set; } + + /// + /// Gets or sets whether the rfc822 address parser should allow addresses without a domain. + /// + /// + /// In general, you'll probably want this value to be true (the default) as it allows + /// maximum interoperability with older email messages that may contain local UNIX addresses. /// This option exists in order to allow parsing of mailbox addresses that do not have an /// @domain component. These types of addresses are rare and were typically only used when sending /// mail to other users on the same UNIX system. @@ -168,7 +178,8 @@ public ParserOptions () ParameterComplianceMode = RfcComplianceMode.Loose; Rfc2047ComplianceMode = RfcComplianceMode.Loose; CharsetEncoding = CharsetUtils.UTF8; - AllowAddressesWithoutDomain = false; + AllowUnquotedCommasInAddresses = true; + AllowAddressesWithoutDomain = true; RespectContentLength = false; MaxAddressGroupDepth = 3; } @@ -185,6 +196,7 @@ public ParserOptions Clone () { var options = new ParserOptions (); options.AddressParserComplianceMode = AddressParserComplianceMode; + options.AllowUnquotedCommasInAddresses = AllowUnquotedCommasInAddresses; options.AllowAddressesWithoutDomain = AllowAddressesWithoutDomain; options.ParameterComplianceMode = ParameterComplianceMode; options.Rfc2047ComplianceMode = Rfc2047ComplianceMode; diff --git a/UnitTests/InternetAddressTests.cs b/UnitTests/InternetAddressTests.cs index dc04afc7f2..34af897107 100644 --- a/UnitTests/InternetAddressTests.cs +++ b/UnitTests/InternetAddressTests.cs @@ -381,13 +381,14 @@ public void TestParseMailboxWithUnquotedCommaInName () // this should fail when we allow mailbox addresses w/o a domain var options = ParserOptions.Default.Clone (); - options.AllowAddressesWithoutDomain = true; + options.AllowUnquotedCommasInAddresses = false; + options.AllowAddressesWithoutDomain = false; try { addr = InternetAddress.Parse (options, text); - Assert.Fail ("Should not have parsed \"{0}\" with AllowAddressesWithoutDomain = true", text); + Assert.Fail ("Should not have parsed \"{0}\" with AllowUnquotedCommasInAddresses = false", text); } catch (ParseException pex) { - Assert.AreEqual (text.IndexOf (','), pex.TokenIndex, "TokenIndex"); + Assert.AreEqual (0, pex.TokenIndex, "TokenIndex"); Assert.AreEqual (text.IndexOf (','), pex.ErrorIndex, "ErrorIndex"); } catch (Exception ex) { Assert.Fail ("Should not have thrown {0}", ex.GetType ().Name); diff --git a/UnitTests/MailboxAddressTests.cs b/UnitTests/MailboxAddressTests.cs index def9193ed3..6c146f1722 100644 --- a/UnitTests/MailboxAddressTests.cs +++ b/UnitTests/MailboxAddressTests.cs @@ -472,13 +472,14 @@ public void TestParseMailboxWithUnquotedCommaInName () // this should fail when we allow mailbox addresses w/o a domain var options = ParserOptions.Default.Clone (); - options.AllowAddressesWithoutDomain = true; + options.AllowUnquotedCommasInAddresses = false; + options.AllowAddressesWithoutDomain = false; try { mailbox = MailboxAddress.Parse (options, text); - Assert.Fail ("Should not have parsed \"{0}\" with AllowAddressesWithoutDomain = true", text); + Assert.Fail ("Should not have parsed \"{0}\" with AllowUnquotedCommasInAddresses = false", text); } catch (ParseException pex) { - Assert.AreEqual (text.IndexOf (','), pex.TokenIndex, "TokenIndex"); + Assert.AreEqual (0, pex.TokenIndex, "TokenIndex"); Assert.AreEqual (text.IndexOf (','), pex.ErrorIndex, "ErrorIndex"); } catch (Exception ex) { Assert.Fail ("Should not have thrown {0}", ex.GetType ().Name);