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

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

commit 0f4dee8451df2ec68a1f201a859f3955a7abd504
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Jul 19 11:35:33 2024 -0400

    LocaleUtils.toLocale(String) cannot parse four segments
---
 src/changes/changes.xml                            |  1 +
 .../java/org/apache/commons/lang3/LocaleUtils.java | 22 ++++++++++++----------
 .../org/apache/commons/lang3/LocaleUtilsTest.java  |  3 ++-
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 02208f3de..9438361e8 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -49,6 +49,7 @@ The <action> type attribute can be add,update,fix,remove.
     <!-- FIX -->
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Reimplement StopWatch internals to use java.time.</action>
     <action issue="LANG-1745" type="fix" dev="ggregory" due-to="Wang Hailong, 
Gary Gregory">RandomStringUtils.random() with a negative character index should 
throw IllegalArgumentException.</action>
+    <action issue="LANG-1741" type="fix" dev="ggregory" due-to="Wang Hailong, 
Gary Gregory">LocaleUtils.toLocale(String) cannot parse four segments.</action>
     <!-- ADD -->
     <action                   type="add" dev="ggregory" due-to="Gary 
Gregory">Add StopWatch.getSplitDuration() and deprecate getSplitTime().</action>
     <action                   type="add" dev="ggregory" due-to="Gary 
Gregory">Add StopWatch.getStartInstant() and deprecate getStartTime().</action>
diff --git a/src/main/java/org/apache/commons/lang3/LocaleUtils.java 
b/src/main/java/org/apache/commons/lang3/LocaleUtils.java
index 8548ba4ee..39b81a490 100644
--- a/src/main/java/org/apache/commons/lang3/LocaleUtils.java
+++ b/src/main/java/org/apache/commons/lang3/LocaleUtils.java
@@ -249,28 +249,30 @@ public class LocaleUtils {
     }
 
     /**
-     * Tries to parse a locale from the given String.
+     * Tries to parse a Locale from the given String.
+     * <p>
+     * See {@Link Locale} for the format.
+     * </p>
      *
-     * @param str the String to parse a locale from.
-     * @return a Locale instance parsed from the given String.
+     * @param str the String to parse as a Locale.
+     * @return a Locale parsed from the given String.
      * @throws IllegalArgumentException if the given String can not be parsed.
+     * @see Locale
      */
     private static Locale parseLocale(final String str) {
         if (isISO639LanguageCode(str)) {
             return new Locale(str);
         }
-
-        final String[] segments = str.indexOf(UNDERSCORE) != -1
-            ? str.split(String.valueOf(UNDERSCORE), -1)
-            : str.split(String.valueOf(DASH), -1);
+        final int limit = 3;
+        final char separator = str.indexOf(UNDERSCORE) != -1 ? UNDERSCORE : 
DASH;
+        final String[] segments = str.split(String.valueOf(separator), 3);
         final String language = segments[0];
         if (segments.length == 2) {
             final String country = segments[1];
-            if (isISO639LanguageCode(language) && 
isISO3166CountryCode(country) ||
-                    isNumericAreaCode(country)) {
+            if (isISO639LanguageCode(language) && 
isISO3166CountryCode(country) || isNumericAreaCode(country)) {
                 return new Locale(language, country);
             }
-        } else if (segments.length == 3) {
+        } else if (segments.length == limit) {
             final String country = segments[1];
             final String variant = segments[2];
             if (isISO639LanguageCode(language) &&
diff --git a/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java
index 6205283f5..dc9e3969d 100644
--- a/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/LocaleUtilsTest.java
@@ -538,9 +538,10 @@ public class LocaleUtilsTest extends AbstractLangTest {
             assertValidToLocale("us_EN_a", "us", "EN", "A");
             assertValidToLocale("us_EN_SFsafdFDsdfF", "us", "EN", 
"SFSAFDFDSDFF");
         }
-
         assertThrows(IllegalArgumentException.class, () -> 
LocaleUtils.toLocale("us_EN-a"), "Should fail as no consistent delimiter");
         assertThrows(IllegalArgumentException.class, () -> 
LocaleUtils.toLocale("uu_UU_"), "Must be 3, 5 or 7+ in length");
+        // LANG-1741
+        assertEquals(new Locale("en", "001", "US_POSIX"), 
LocaleUtils.toLocale("en_001_US_POSIX"));
     }
 
     /**

Reply via email to