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 @@ -249,7 +249,12 @@ public boolean verify(final String domain) {
if (domain == null) {
return false;
}
return verifyInternal(domain.startsWith(".") ? domain.substring(1) : domain);
// Normalise here so that verifyInternal can assume its input is already lowercase and in
// Unicode form. The rules are held that way, so an ACE-encoded (xn--) or mixed-case public
// suffix has to be decoded first; otherwise it fails to match a rule and is mistaken for a
// registrable domain.
final String normalized = DnsUtils.normalizeUnicode(domain.startsWith(".") ? domain.substring(1) : domain);
return verifyInternal(normalized);
}

@Internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,18 @@ void testMatchUnicode() {
Assertions.assertTrue(matcher.matches(".xn--h-2fa.no"));
}

@Test
void testVerifyUnicode() {
// A public suffix must be rejected by verify() whether it is given in Unicode or in its
// ACE (xn--) form; matches() already recognises both, so verify() must agree.
Assertions.assertTrue(matcher.matches(".xn--h-2fa.no"));
Assertions.assertFalse(matcher.verify("hå.no")); // å is <aring>
Assertions.assertFalse(matcher.verify("xn--h-2fa.no"));
// A genuine registrable domain under the IDN suffix is still allowed, in either form.
Assertions.assertTrue(matcher.verify("foo.hå.no"));
Assertions.assertTrue(matcher.verify("foo.xn--h-2fa.no"));
}

private void checkPublicSuffix(final String input, final String expected) {
Assertions.assertEquals(expected, pslMatcher.getDomainRoot(input));
}
Expand Down
Loading