From bfda38f0388ca7fe0c9743d5f4694b159f38da51 Mon Sep 17 00:00:00 2001 From: hanzhe-one <200491821+hanzhe-one@users.noreply.github.com> Date: Mon, 2 Nov 2026 18:55:32 +0800 Subject: [PATCH 1/2] fix: align unicode case folding with String.regionMatches --- .../org/apache/fesod/common/util/StringUtils.java | 5 +++-- .../apache/fesod/common/util/StringUtilsTest.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/fesod-common/src/main/java/org/apache/fesod/common/util/StringUtils.java b/fesod-common/src/main/java/org/apache/fesod/common/util/StringUtils.java index abd801601b..ba71176c5f 100644 --- a/fesod-common/src/main/java/org/apache/fesod/common/util/StringUtils.java +++ b/fesod-common/src/main/java/org/apache/fesod/common/util/StringUtils.java @@ -198,8 +198,9 @@ public static boolean regionMatches( } // The same check as in String.regionMatches(): - if (Character.toUpperCase(c1) != Character.toUpperCase(c2) - && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { + final char upper1 = Character.toUpperCase(c1); + final char upper2 = Character.toUpperCase(c2); + if (upper1 != upper2 && Character.toLowerCase(upper1) != Character.toLowerCase(upper2)) { return false; } } diff --git a/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java b/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java index 0f4ec3d0a4..2358198a95 100644 --- a/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java +++ b/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java @@ -211,6 +211,20 @@ boolean invoke() { } } + @Test + void test_regionMatches_unicodeIgnoreCase() { + final CharSequence[] dottedI = {"İ", new StringBuilder("İ")}; + final CharSequence[] dotlessI = {"ı", new StringBuilder("ı")}; + for (final CharSequence source : dottedI) { + for (final CharSequence other : dotlessI) { + Assertions.assertTrue(StringUtils.regionMatches(source, true, 0, other, 0, 1)); + Assertions.assertTrue(StringUtils.regionMatches(other, true, 0, source, 0, 1)); + Assertions.assertFalse(StringUtils.regionMatches(source, false, 0, other, 0, 1)); + Assertions.assertFalse(StringUtils.regionMatches(other, false, 0, source, 0, 1)); + } + } + } + @Test void stripTest() { Assertions.assertNull(StringUtils.strip(null)); From a7b9077082931e1eb79af25aabe9d30163db7c3d Mon Sep 17 00:00:00 2001 From: hanzhe-one <200491821+hanzhe-one@users.noreply.github.com> Date: Thu, 5 Nov 2026 20:42:54 +0800 Subject: [PATCH 2/2] test: compare unicode region matches against the JDK --- .../fesod/common/util/StringUtilsTest.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java b/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java index 2358198a95..52432b99c9 100644 --- a/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java +++ b/fesod-common/src/test/java/org/apache/fesod/common/util/StringUtilsTest.java @@ -217,10 +217,18 @@ void test_regionMatches_unicodeIgnoreCase() { final CharSequence[] dotlessI = {"ı", new StringBuilder("ı")}; for (final CharSequence source : dottedI) { for (final CharSequence other : dotlessI) { - Assertions.assertTrue(StringUtils.regionMatches(source, true, 0, other, 0, 1)); - Assertions.assertTrue(StringUtils.regionMatches(other, true, 0, source, 0, 1)); - Assertions.assertFalse(StringUtils.regionMatches(source, false, 0, other, 0, 1)); - Assertions.assertFalse(StringUtils.regionMatches(other, false, 0, source, 0, 1)); + Assertions.assertEquals( + source.toString().regionMatches(true, 0, other.toString(), 0, 1), + StringUtils.regionMatches(source, true, 0, other, 0, 1)); + Assertions.assertEquals( + other.toString().regionMatches(true, 0, source.toString(), 0, 1), + StringUtils.regionMatches(other, true, 0, source, 0, 1)); + Assertions.assertEquals( + source.toString().regionMatches(false, 0, other.toString(), 0, 1), + StringUtils.regionMatches(source, false, 0, other, 0, 1)); + Assertions.assertEquals( + other.toString().regionMatches(false, 0, source.toString(), 0, 1), + StringUtils.regionMatches(other, false, 0, source, 0, 1)); } } }