You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2026/08/24 08:51:51 UTC

(httpcomponents-client) branch 5.6.x updated: decode punycode public suffixes in PublicSuffixMatcher.verify (#876)

This is an automated email from the ASF dual-hosted git repository.

ok2c pushed a commit to branch 5.6.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git


The following commit(s) were added to refs/heads/5.6.x by this push:
     new 8e45f1761 decode punycode public suffixes in PublicSuffixMatcher.verify (#876)
8e45f1761 is described below

commit 8e45f17619dd5e7e139f11d58cbc9419ba0c3cc3
Author: Javid Khan <dx...@gmail.com>
AuthorDate: Mon Aug 24 14:13:18 2026 +0530

    decode punycode public suffixes in PublicSuffixMatcher.verify (#876)
---
 .../org/apache/hc/client5/http/psl/PublicSuffixMatcher.java  |  7 ++++++-
 .../apache/hc/client5/http/psl/TestPublicSuffixMatcher.java  | 12 ++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/psl/PublicSuffixMatcher.java b/httpclient5/src/main/java/org/apache/hc/client5/http/psl/PublicSuffixMatcher.java
index 5a5f27812..6007a08ba 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/psl/PublicSuffixMatcher.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/psl/PublicSuffixMatcher.java
@@ -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
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/psl/TestPublicSuffixMatcher.java b/httpclient5/src/test/java/org/apache/hc/client5/http/psl/TestPublicSuffixMatcher.java
index 2dce2cbdd..b0dd78388 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/psl/TestPublicSuffixMatcher.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/psl/TestPublicSuffixMatcher.java
@@ -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));
     }