Skip to content

Commit

Permalink
[Add] Allow illegal address #COS-125
Browse files Browse the repository at this point in the history
  • Loading branch information
PhucNV9 committed Mar 12, 2018
1 parent 4e3611e commit d35d17f
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 62 deletions.
17 changes: 16 additions & 1 deletion MimeKit/InternetAddress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ internal static bool TryParseLocalPart (byte[] text, ref int index, int endIndex

localpart = null;

var start = index;
do {
if (!text[index].IsAtom () && text[index] != '"' && text[index] != '.') {
if (throwOnError)
Expand All @@ -301,10 +302,16 @@ internal static bool TryParseLocalPart (byte[] text, ref int index, int endIndex
return false;
}

int start = index;
if (!ParseUtils.SkipWordAndPeriod (text, ref index, endIndex, throwOnError))
return false;

if (index < endIndex && text[index] == (byte) '"')
{
ParseUtils.SkipQuoted (text, ref index, endIndex, throwOnError);
if (index < endIndex && text[index].IsAtom() && text[index] != (byte) '@' && text[index] != (byte) '(')
continue;
}

try {
token.Append (CharsetUtils.UTF8.GetString (text, start, index - start));
} catch (DecoderFallbackException ex) {
Expand All @@ -317,6 +324,12 @@ internal static bool TryParseLocalPart (byte[] text, ref int index, int endIndex
if (!ParseUtils.SkipCommentsAndWhiteSpace (text, ref index, endIndex, throwOnError))
return false;

if (index < endIndex && text[index] != (byte) '"' && text[index].IsAtom())
{
start = index;
continue;
}

if (index >= endIndex || text[index] != (byte) '.')
break;

Expand All @@ -336,6 +349,8 @@ internal static bool TryParseLocalPart (byte[] text, ref int index, int endIndex
if (text[index] == '@')
break;

start = index;

} while (true);

localpart = token.ToString ();
Expand Down
5 changes: 1 addition & 4 deletions MimeKit/Utils/ParseUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,7 @@ public static bool SkipQuoted (byte[] text, ref int index, int endIndex, bool th
}

if (index >= endIndex) {
if (throwOnError)
throw new ParseException (string.Format ("Incomplete quoted-string token at offset {0}", startIndex), startIndex, index);

return false;
index = startIndex;
}

// skip over the closing '"'
Expand Down
22 changes: 4 additions & 18 deletions UnitTests/InternetAddressTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,8 @@ public void TestParseMailboxWithIncompleteLocalPart ()
public void TestParseIncompleteQuotedString ()
{
const string text = "\"This quoted string never ends... oh no!";
const int tokenIndex = 0;
int errorIndex = text.Length;

AssertParseFailure (text, false, tokenIndex, errorIndex);
AssertParse (text);
}

[Test]
Expand Down Expand Up @@ -279,20 +277,6 @@ public void TestParseMailboxWithUnquotedCommaInName ()
// default options should parse this as a single mailbox address
addr = InternetAddress.Parse (text);
Assert.AreEqual ("Worthington, Warren", addr.Name);

// this should fail when we allow mailbox addresses w/o a domain
var options = ParserOptions.Default.Clone ();
options.AllowAddressesWithoutDomain = true;

try {
addr = InternetAddress.Parse (options, text);
Assert.Fail ("Should not have parsed \"{0}\" with AllowAddressesWithoutDomain = true", text);
} catch (ParseException pex) {
Assert.AreEqual (text.IndexOf (','), pex.TokenIndex, "TokenIndex");
Assert.AreEqual (text.IndexOf (','), pex.ErrorIndex, "ErrorIndex");
} catch (Exception ex) {
Assert.Fail ("Should not have thrown {0}", ex.GetType ().Name);
}
}

[Test]
Expand Down Expand Up @@ -534,7 +518,9 @@ TestCaseData[] LegacyAddressNotCompliantWithRFC ()
new TestCaseData ("[email protected]"),
new TestCaseData ("[email protected]"),
new TestCaseData ("[email protected]"),

new TestCaseData ("!\"#$%&'()[email protected]"),
new TestCaseData ("!\"#$%&'\"()[email protected]"),
new TestCaseData ("!\"#$%&'\"=\"@amimap.access.co.jp"),
// More not compliant with RFC
// Does not correspond now.
//new TestCaseData ("アドレス <aa\"[email protected]>"),
Expand Down
27 changes: 4 additions & 23 deletions UnitTests/MailboxAddressTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,8 @@ public void TestParseMailboxWithIncompleteLocalPart ()
public void TestParseIncompleteQuotedString ()
{
const string text = "\"This quoted string never ends... oh no!";
const int tokenIndex = 0;
int errorIndex = text.Length;

AssertParseFailure (text, false, tokenIndex, errorIndex);
AssertParse (text);
}

[Test]
Expand Down Expand Up @@ -360,20 +358,6 @@ public void TestParseMailboxWithUnquotedCommaInName ()
// default options should parse this as a single mailbox address
mailbox = MailboxAddress.Parse (text);
Assert.AreEqual ("Worthington, Warren", mailbox.Name);

// this should fail when we allow mailbox addresses w/o a domain
var options = ParserOptions.Default.Clone ();
options.AllowAddressesWithoutDomain = true;

try {
mailbox = MailboxAddress.Parse (options, text);
Assert.Fail ("Should not have parsed \"{0}\" with AllowAddressesWithoutDomain = true", text);
} catch (ParseException pex) {
Assert.AreEqual (text.IndexOf (','), pex.TokenIndex, "TokenIndex");
Assert.AreEqual (text.IndexOf (','), pex.ErrorIndex, "ErrorIndex");
} catch (Exception ex) {
Assert.Fail ("Should not have thrown {0}", ex.GetType ().Name);
}
}

[Test]
Expand Down Expand Up @@ -565,11 +549,6 @@ public void TestParseMailboxWithUnbalancedQuotes ()
const string text = "\"Joe <[email protected]>";

AssertParse (text);

AssertParseFailure (text, false, 0, text.Length, RfcComplianceMode.Strict);

// for coverage
AssertParseFailure (" \"", false, 1, 2, RfcComplianceMode.Loose);
}

[Test]
Expand Down Expand Up @@ -695,7 +674,9 @@ TestCaseData[] LegacyAddressNotCompliantWithRFC ()
new TestCaseData ("[email protected]"),
new TestCaseData ("[email protected]"),
new TestCaseData ("[email protected]"),

new TestCaseData ("!\"#$%&'()[email protected]"),
new TestCaseData ("!\"#$%&'\"()[email protected]"),
new TestCaseData ("!\"#$%&'\"=\"@amimap.access.co.jp"),
// More not compliant with RFC
// Does not correspond now.
//new TestCaseData ("アドレス <aa\"[email protected]>"),
Expand Down
16 changes: 0 additions & 16 deletions UnitTests/ParseUtilsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,6 @@ public void TestTryParseInt32 ()
Assert.IsFalse (ParseUtils.TryParseInt32 (buffer, ref index, buffer.Length, out value), "Parsing MaxValue*10 should result in overflow.");
}

[Test]
public void TestSkipBadlyQuoted ()
{
var buffer = Encoding.ASCII.GetBytes ("\"This is missing the end quote.");
int index = 0;

Assert.False (ParseUtils.SkipQuoted (buffer, ref index, buffer.Length, false), "Skipping an unterminated qstring should have failed.");
Assert.AreEqual (buffer.Length, index, "The index should be at the end of the buffer.");

index = 0;

var ex = Assert.Throws<ParseException> (() => ParseUtils.SkipQuoted (buffer, ref index, buffer.Length, true), "An exception should have been thrown.");
Assert.AreEqual (0, ex.TokenIndex, "The token index should be 0.");
Assert.AreEqual (buffer.Length, ex.ErrorIndex, "The error index should be at the end of the buffer.");
}

static readonly string[] GoodDomains = {
"[127.0.0.1]", "[127.0.0.1]",
"amazon (comment) . (comment) com (comment)", "amazon.com",
Expand Down

0 comments on commit d35d17f

Please sign in to comment.