Skip to content
Open
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,15 @@ 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, mirroring getDomainRoot; otherwise it fails to match a
// rule and is mistaken for a registrable domain.
String normalized = DnsUtils.normalize(domain.startsWith(".") ? domain.substring(1) : domain);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dxbjavid Could not we use DnsUtils#normalizeUnicode here?

if (normalized.contains("xn-")) {
normalized = IDN.toUnicode(normalized);
}
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