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

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 48532a6ed Clarify LocaleUtils ASCII validation following #1838
48532a6ed is described below

commit 48532a6ed0e5995673a3181a8eb558058d027242
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Oct 25 09:45:36 2026 -0400

    Clarify LocaleUtils ASCII validation following #1838
    
    Document ASCII language, country, and numeric area code requirements and
    note that previously accepted non-ASCII codes now throw
    IllegalArgumentException. Expand regression coverage for non-ASCII
    parsing and cache exclusion.
---
 src/changes/changes.xml                                     |  1 +
 src/main/java/org/apache/commons/lang3/LocaleUtils.java     |  5 +++--
 src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java | 10 +++++-----
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f56b09564..82d056f1c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -75,6 +75,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action                   type="fix" dev="ggregory" due-to="Aminark, Gary 
Gregory">[javadoc] Correct StringUtils example methods and overloads 
(#1836).</action>
     <action                   type="fix" dev="ggregory" due-to="alhuda, Gary 
Gregory">Stop ExceptionUtils.removeCommonFrames at the first differing frame 
(#1831).</action>
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Use StackTraceElement objects to build compact root cause stack 
traces, avoiding text parsing and preventing exception message text from being 
mistaken for stack frames.</action>
+    <action                   type="fix" dev="ggregory" due-to="alhuda, Gary 
Gregory">Restrict LocaleUtils.toLocale to ASCII language, country, and numeric 
area codes; previously accepted non-ASCII codes now cause 
IllegalArgumentException (#1838).</action>
     <!-- ADD -->
     <!-- UPDATE -->
     <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
org.apache.commons:commons-parent from 105 to 106.</action>
diff --git a/src/main/java/org/apache/commons/lang3/LocaleUtils.java 
b/src/main/java/org/apache/commons/lang3/LocaleUtils.java
index cbc721c09..2845e8732 100644
--- a/src/main/java/org/apache/commons/lang3/LocaleUtils.java
+++ b/src/main/java/org/apache/commons/lang3/LocaleUtils.java
@@ -416,8 +416,9 @@ public static Locale toLocale(final Locale locale) {
      * </p>
      *
      * <p>
-     * This method validates the input strictly. The language code must be 
lowercase. The country code must be uppercase. The separator must be an 
underscore or
-     * a dash. The length must be correct.
+     * This method validates the input strictly. A nonempty language code must 
consist of two or three lowercase ASCII letters. A nonempty country code must
+     * consist of two uppercase ASCII letters or, when a language code is 
present, three ASCII digits representing a numeric area code. The separator 
must be
+     * an underscore or a dash. The length must be correct.
      * </p>
      *
      * @param str The locale String to convert, null returns null.
diff --git a/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java
index cb665f882..71d3d21c1 100644
--- a/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java
@@ -261,7 +261,7 @@ void testCountriesByLanguage() {
     }
 
     @ParameterizedTest
-    @ValueSource(strings = {"x", "abcd", "EN", "e1", "en-US", " "})
+    @ValueSource(strings = {"x", "abcd", "EN", "e1", "en-US", " ", "en", "éé", 
"ééé", "eé"})
     void testCountriesByLanguageDoesNotCacheInvalidLanguageCode(final String 
languageCode) {
         final ConcurrentMap<String, List<Locale>> map = 
LocaleUtils.getLcToLocalesMap();
         assertFalse(map.containsKey(languageCode));
@@ -371,7 +371,7 @@ void testLanguagesByCountry() {
     }
 
     @ParameterizedTest
-    @ValueSource(strings = {"x", "abcd", "English", "e1", "en-US", " "})
+    @ValueSource(strings = {"x", "abcd", "English", "e1", "en-US", " ", "GB", 
"ÉÉ", "GÉ", "ÉB", "١٢٣", "1٢3"})
     void testLanguagesByCountryDoesNotCacheInvalidLanguageCode(final String 
languageCode) {
         final ConcurrentMap<String, List<Locale>> map = 
LocaleUtils.getCcToLocalesMap();
         assertFalse(map.containsKey(languageCode));
@@ -546,11 +546,11 @@ void testToLocale_2Part() {
     @ParameterizedTest
     @ValueSource(strings = {
             // FULLWIDTH LATIN SMALL LETTER E and N
-            "en", "éé", "éé_GB",
+            "en", "éé", "ééé", "eé", "éé_GB", "éé-GB", "éé_GB_POSIX",
             // FULLWIDTH LATIN CAPITAL LETTER G and B
-            "en_GB", "en_ÉÉ", "en_ÉÉ_POSIX", "_ÉÉ", "_ÉÉ_POSIX",
+            "en_GB", "en_ÉÉ", "en-ÉÉ", "en_ÉÉ_POSIX", "_ÉÉ", "_ÉÉ_POSIX", 
"-ÉÉ", "_GÉ", "_ÉB",
             // ARABIC-INDIC DIGIT ONE, TWO and THREE
-            "en_١٢٣" })
+            "en_١٢٣", "en-١٢٣", "en_1٢3", "en_١٢٣_POSIX" })
     void testToLocaleNonAsciiCodes(final String localeString) {
         assertIllegalArgumentException(() -> 
LocaleUtils.toLocale(localeString), "Should fail code not ASCII: " + 
localeString);
     }

Reply via email to