Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ public class EmailValidator implements Serializable {
private static final String WORD = "((" + VALID_CHARS + "|')+|" + QUOTED_USER + ")";

private static final String EMAIL_REGEX = "^(.+)@(\\S+)$";
private static final String IP_DOMAIN_REGEX = "^\\[(.*)\\]$";

/**
* RFC 5321 section 4.1.3: an IPv6 address literal carries the "IPv6:" tag (case-insensitive), an IPv4 literal is untagged.
*/
private static final String IP_DOMAIN_REGEX = "^\\[((?i)IPv6:)?(.*)\\]$";
private static final String USER_REGEX = "^" + WORD + "(\\." + WORD + ")*$";

private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
Expand Down Expand Up @@ -195,9 +199,11 @@ protected boolean isValidDomain(final String domain) {
final Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain);

if (ipDomainMatcher.matches()) {
final InetAddressValidator inetAddressValidator =
InetAddressValidator.getInstance();
return inetAddressValidator.isValid(ipDomainMatcher.group(1));
final InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance();
if (ipDomainMatcher.group(1) != null) {
return inetAddressValidator.isValidInet6Address(ipDomainMatcher.group(2));
}
return inetAddressValidator.isValidInet4Address(ipDomainMatcher.group(2));
}
// Domain is symbolic name
if (allowTld) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,23 @@ void testEmailWithNumericAddress() {
assertTrue(validator.isValid("someone@yahoo.com"));
}

/**
* Tests IPv6 address literals in the domain, which RFC 5321 section 4.1.3 tags with "IPv6:".
*/
@Test
void testEmailWithIpv6AddressLiteral() {
// Tagged IPv6 literals are accepted; the tag is ABNF-literal text so it is case insensitive.
assertTrue(validator.isValid("someone@[IPv6:2001:db8::1]"));
assertTrue(validator.isValid("someone@[IPv6:::1]"));
assertTrue(validator.isValid("someone@[ipv6:fe80::1]"));
// A bare IPv6 literal without the tag is not a valid address literal.
assertFalse(validator.isValid("someone@[2001:db8::1]"));
assertFalse(validator.isValid("someone@[::1]"));
// The tag is IPv6 only; an IPv4 literal stays untagged.
assertTrue(validator.isValid("someone@[216.109.118.76]"));
assertFalse(validator.isValid("someone@[IPv6:216.109.118.76]"));
}

/**
* VALIDATOR-296 - A / or a ! is valid in the user part, but not in the domain part
*/
Expand Down
Loading