mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-18 18:17:03 +00:00
Completed ParseEmailAddress()
This commit is contained in:
@@ -123,9 +123,11 @@ LOOP:
|
||||
inCharQuote = false
|
||||
case '0' <= c && c <= '9':
|
||||
// Numbers are OK
|
||||
buf.WriteByte(c)
|
||||
inCharQuote = false
|
||||
case bytes.IndexByte([]byte("!#$%&'*+-/=?^_`{|}~"), c) >= 0:
|
||||
// These specials can be used unquoted
|
||||
buf.WriteByte(c)
|
||||
inCharQuote = false
|
||||
case c == '.':
|
||||
// A single period is OK
|
||||
@@ -133,10 +135,13 @@ LOOP:
|
||||
// Sequence of periods is not permitted
|
||||
return "", "", fmt.Errorf("Sequence of periods is not permitted")
|
||||
}
|
||||
buf.WriteByte(c)
|
||||
inCharQuote = false
|
||||
case c == '\\':
|
||||
inCharQuote = true
|
||||
case c == '"':
|
||||
if inCharQuote {
|
||||
buf.WriteByte(c)
|
||||
inCharQuote = false
|
||||
} else if inStringQuote {
|
||||
inStringQuote = false
|
||||
@@ -149,6 +154,7 @@ LOOP:
|
||||
}
|
||||
case c == '@':
|
||||
if inCharQuote || inStringQuote {
|
||||
buf.WriteByte(c)
|
||||
inCharQuote = false
|
||||
} else {
|
||||
// End of local-part
|
||||
@@ -165,6 +171,7 @@ LOOP:
|
||||
return "", "", fmt.Errorf("Characters outside of US-ASCII range not permitted")
|
||||
default:
|
||||
if inCharQuote || inStringQuote {
|
||||
buf.WriteByte(c)
|
||||
inCharQuote = false
|
||||
} else {
|
||||
return "", "", fmt.Errorf("Character %q must be quoted", c)
|
||||
|
||||
@@ -69,6 +69,7 @@ func TestValidateLocal(t *testing.T) {
|
||||
{"user.", false, "Cannot end with a period"},
|
||||
{"james@mail", false, "Unquoted @ not permitted"},
|
||||
{"first last", false, "Unquoted space not permitted"},
|
||||
{"tricky\\. ", false, "Unquoted space not permitted"},
|
||||
{"no,commas", false, "Unquoted comma not allowed"},
|
||||
{"t[es]t", false, "Unquoted square brackets not allowed"},
|
||||
{"james\\", false, "Cannot end with backslash quote"},
|
||||
@@ -110,10 +111,26 @@ func TestValidateLocal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseEmailAddress(t *testing.T) {
|
||||
// Test some good email addresses
|
||||
var testTable = []struct {
|
||||
input, local, domain string
|
||||
}{
|
||||
{"root@localhost", "root", "localhost"},
|
||||
{"FirstLast@domain.local", "FirstLast", "domain.local"},
|
||||
{"route66@prodigy.net", "route66", "prodigy.net"},
|
||||
{"lorbit!user@uucp", "lorbit!user", "uucp"},
|
||||
{"user+spam@gmail.com", "user+spam", "gmail.com"},
|
||||
{"first.last@domain.local", "first.last", "domain.local"},
|
||||
{"first\\ last@_key.domain.com", "first last", "_key.domain.com"},
|
||||
{"first\\\"last@a.b.c", "first\"last", "a.b.c"},
|
||||
{"user\\@internal@myhost.ca", "user@internal", "myhost.ca"},
|
||||
{"\"first last@evil\"@top-secret.gov", "first last@evil", "top-secret.gov"},
|
||||
{"\"line\nfeed\"@linenoise.co.uk", "line\nfeed", "linenoise.co.uk"},
|
||||
{"user+mailbox@host", "user+mailbox", "host"},
|
||||
{"customer/department=shipping@host", "customer/department=shipping", "host"},
|
||||
{"$A12345@host", "$A12345", "host"},
|
||||
{"!def!xyz%abc@host", "!def!xyz%abc", "host"},
|
||||
{"_somename@host", "_somename", "host"},
|
||||
}
|
||||
|
||||
for _, tt := range testTable {
|
||||
@@ -131,4 +148,27 @@ func TestParseEmailAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that validations fail correctly
|
||||
var badTable = []struct {
|
||||
input, msg string
|
||||
}{
|
||||
{"", "Empty address not permitted"},
|
||||
{"user", "Missing domain part"},
|
||||
{"@host", "Missing local part"},
|
||||
{"user\\@host", "Missing domain part"},
|
||||
{"\"user@host\"", "Missing domain part"},
|
||||
{"\"user@host", "Unterminated quoted string"},
|
||||
{"first last@host", "Unquoted space"},
|
||||
{"user@bad!domain", "Invalid domain"},
|
||||
{".user@host", "Can't lead with a ."},
|
||||
{"user.@host", "Can't end local with a dot"},
|
||||
{"user@bad domain", "No spaces in domain permitted"},
|
||||
}
|
||||
|
||||
for _, tt := range badTable {
|
||||
if _, _, err := ParseEmailAddress(tt.input); err == nil {
|
||||
t.Errorf("Did not get expected error when parsing %q: %s", tt.input, tt.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user