don't "domain block" address literals
[ghsmtp.git] / Mailbox-test.cpp
blob9dfadf7c0beddbea2d7577c479fe3019ac47e704
1 #include "Mailbox.hpp"
3 #include <iostream>
5 #include <glog/logging.h>
7 int main(int argc, char* argv[])
9 Mailbox postmaster("postmaster@[127.0.0.1]");
11 Mailbox mb;
12 CHECK(mb.empty());
14 Mailbox dg0{"gene@digilicious.com"};
15 Mailbox dg1{"gene", "digilicious.com"};
17 CHECK_EQ(dg0, dg1);
19 CHECK_EQ(std::string("digilicious.com"), dg0.domain().ascii());
21 auto dgstr = static_cast<std::string>(dg0);
23 CHECK_EQ(dgstr, "gene@digilicious.com");
25 dg0.clear();
26 CHECK(dg0.empty());
28 auto threw = false;
29 try {
30 Mailbox bad("should throw@example.com");
32 catch (std::exception& e) {
33 threw = true;
35 CHECK(threw);
37 CHECK(Mailbox::validate("simple@example.com"));
38 CHECK(Mailbox::validate("very.common@example.com"));
39 CHECK(Mailbox::validate("disposable.style.email.with+symbol@example.com"));
40 CHECK(Mailbox::validate("other.email-with-hyphen@example.com"));
41 CHECK(Mailbox::validate("fully-qualified-domain@example.com"));
43 // (may go to user.name@example.com inbox depending on mail server)
44 CHECK(Mailbox::validate("user.name+tag+sorting@example.com"));
46 CHECK(Mailbox::validate("x@example.com"));
47 CHECK(Mailbox::validate("example-indeed@strange-example.com"));
49 // (see the List of Internet top-level domains)
50 CHECK(Mailbox::validate("example@s.example"));
52 // (space between the quotes)
53 CHECK(Mailbox::validate("\" \"@example.org"));
55 // (quoted angle brackets)
56 CHECK(Mailbox::validate("\"\\<foo-bar\\>\"@example.org"));
58 // (quoted double dot)
59 CHECK(Mailbox::validate("\"john..doe\"@example.org"));
61 // (bangified host route used for uucp mailers)
62 CHECK(Mailbox::validate("mailhost!username@example.org"));
64 // (% escaped mail route to user@example.com via example.org)
65 CHECK(Mailbox::validate("user%example.com@example.org"));
67 // Invalid email addresses
69 CHECK(!Mailbox::validate("Abc.example.com")); // (no @ character)
71 CHECK(!Mailbox::validate("A@b@c@example.com")); // (only one @ is allowed)
73 // (none of the special characters in this local-part are allowed
74 // outside quotation marks)
75 CHECK(!Mailbox::validate("a\"b(c)d,e:f;g<h>i[j\\k]l@example.com"));
77 // (quoted strings must be dot separated or the only element making
78 // up the local-part)
79 CHECK(!Mailbox::validate("just\"not\"right@example.com"));
81 // (spaces, quotes, and backslashes may only exist when within
82 // quoted strings and preceded by a backslash)
83 CHECK(!Mailbox::validate("this is\"not\\allowed@example.com"));
85 // (even if escaped (preceded by a backslash), spaces, quotes, and
86 // backslashes must still be contained by quotes)
87 CHECK(!Mailbox::validate("this\\ still\\\"not\\\\allowed@example.com"));
89 // (local part is longer than 64 characters)
90 // Real world local-parts often longer than "offical" limit.
91 // CHECK(!Mailbox::validate(
92 // "1234567890123456789012345678901234567890123456789012345"
93 // "678901234+x@example.com"));
95 // Not fully qualified.
96 CHECK(!Mailbox::validate("foo@bar"));
98 // TLD too short.
99 CHECK(!Mailbox::validate("foo@bar.x"));
101 // Label longer than 64 octets.
102 CHECK(!Mailbox::validate(
103 "foo@"
104 "1234567890123456789012345678901234567890123456789012345678901234X."
105 "com"));
107 // Total domain length longer than 255 octets.
108 CHECK(!Mailbox::validate(
109 "foo@"
110 "1234567890123456789012345678901234567890123456789012345678901234."
111 "1234567890123456789012345678901234567890123456789012345678901234."
112 "1234567890123456789012345678901234567890123456789012345678901234."
113 "1234567890123456789012345678901234567890123456789012345678901234."
114 "1234567890123456789012345678901234567890123456789012345678901234."
115 "1234567890123456789012345678901234567890123456789012345678901234."
116 "com"));
118 CHECK(Mailbox::validate("gene@digilicious.com"));
119 CHECK(Mailbox::validate("gene@[127.0.0.1]"));
120 CHECK(!Mailbox::validate("gene@[127.999.0.1]"));
121 CHECK(!Mailbox::validate("allen@bad_d0main.com"));
124 auto const res = Mailbox::parse("gene@[127.0.0.1]");
125 CHECK(res && res->local_type == Mailbox::local_types::dot_string);
126 CHECK(res && res->domain_type == Mailbox::domain_types::address_literal);
129 auto const res = Mailbox::parse("\"some string\"@example.com");
130 CHECK(res && res->local_type == Mailbox::local_types::quoted_string);
131 CHECK(res && res->domain_type == Mailbox::domain_types::domain);
134 CHECK(!Mailbox::validate("2962"));
135 CHECK(Mailbox::validate("실례@실례.테스트"));
137 // <https://docs.microsoft.com/en-us/archive/blogs/testing123/email-address-test-cases>
139 // Valid email addresses:
140 CHECK(Mailbox::validate("email@domain.com"));
142 // Email contains dot in the local part, a dot-atom-string.
143 CHECK(Mailbox::validate("firstname.lastname@domain.com"));
145 // Multiple labels in domain.
146 CHECK(Mailbox::validate("email@subdomain.domain.com"));
148 // Plus sign is a valid character.
149 CHECK(Mailbox::validate("firstname+lastname@domain.com"));
151 // Domain is valid IP address, but this is matched as a domain.
152 CHECK(Mailbox::validate("email@123.123.123.123"));
154 // Square bracket around IP address is a "address literal."
155 CHECK(Mailbox::validate("email@[123.123.123.123]"));
157 // Quotes around local part is valid.
158 CHECK(Mailbox::validate("\"email\"@domain.com"));
160 // Digits in address are valid.
161 CHECK(Mailbox::validate("1234567890@domain.com"));
163 // Dash in domain name is valid.
164 CHECK(Mailbox::validate("email@domain-one.com"));
166 // Underscore in the address field is valid.
167 CHECK(Mailbox::validate("_______@domain.com"));
169 CHECK(Mailbox::validate("email@domain.name"));
170 CHECK(Mailbox::validate("email@domain.co.jp"));
172 // Dash in local part is valid.
173 CHECK(Mailbox::validate("firstname-lastname@domain.com"));
175 CHECK(!Mailbox::validate("plainaddress")); // Missing @ sign and domain
176 CHECK(!Mailbox::validate("#@%^%#$@#$@#.com")); // Garbage
177 CHECK(!Mailbox::validate("@domain.com")); // Missing username
179 CHECK(!Mailbox::validate("Joe Smith <email@domain.com>"));
181 CHECK(!Mailbox::validate("email.domain.com")); // Missing @
182 CHECK(!Mailbox::validate("email@domain@domain.com")); // Two @ sign
184 // Leading dot in address is not allowed
185 CHECK(!Mailbox::validate(".email@domain.com"));
187 // Trailing dot in address is not allowed
188 CHECK(!Mailbox::validate("email.@domain.com"));
190 // Multiple dots
191 CHECK(!Mailbox::validate("email..email@domain.com"));
193 // OK! Unicode char as address
194 CHECK(Mailbox::validate("あいうえお@domain.com"));
196 // Comment not allowed in 5321 mailbox.
197 CHECK(!Mailbox::validate("email@domain.com (Joe Smith)"));
199 // Missing top level domain (.com/.net/.org/etc).
200 CHECK(!Mailbox::validate("email@domain"));
202 // Leading dash in front of domain is invalid.
203 CHECK(!Mailbox::validate("email@-domain.com"));
205 // .web is not a valid top level domain, oh yeah? says who?
206 CHECK(Mailbox::validate("email@domain.web"));
208 // Invalid IP address.
209 CHECK(!Mailbox::validate("email@[111.222.333.44444]"));
211 // Invalid IP address, but valid domain name as it turns out.
212 CHECK(Mailbox::validate("email@111.222.333.44444"));
214 // Not a valid domain name.
215 CHECK(!Mailbox::validate("email@domain..com"));
217 // general_address_literal
218 CHECK(!Mailbox::validate("email@[x:~Foo_Bar_Baz<\?\?>]"));
220 std::cout << "sizeof(Mailbox) == " << sizeof(Mailbox) << '\n';