Permalink
Browse files

[LANG-865] LocaleUtils.toLocale does not parse strings starting with …

…an underscore.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1428174 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent 379151b commit 75944e541d358d5b06ebbba3098a919fbf2539d4 @garydgregory garydgregory committed Jan 3, 2013
View
@@ -22,6 +22,7 @@
<body>
<release version="3.2" date="TBA" description="Next release">
+ <action issue="LANG-865" type="fix">LocaleUtils.toLocale does not parse strings starting with an underscore</action>
<action issue="LANG-835" type="add">StrBuilder should support StringBuilder as an input parameter</action>
<action issue="LANG-858" type="fix">StringEscapeUtils.escapeJava() and escapeEcmaScript() do not output the escaped surrogate pairs that are Java parsable</action>
<action issue="LANG-857" type="add">StringIndexOutOfBoundsException in CharSequenceTranslator</action>
@@ -85,41 +85,66 @@ public LocaleUtils() {
* @return a Locale, null if null input
* @throws IllegalArgumentException if the string is an invalid format
*/
- public static Locale toLocale(String str) {
+ public static Locale toLocale(final String str) {
if (str == null) {
return null;
}
- int len = str.length();
- if (len != 2 && len != 5 && len < 7) {
+ final int len = str.length();
+ if (len < 2) {
throw new IllegalArgumentException("Invalid locale format: " + str);
}
- char ch0 = str.charAt(0);
- char ch1 = str.charAt(1);
- if (ch0 < 'a' || ch0 > 'z' || ch1 < 'a' || ch1 > 'z') {
- throw new IllegalArgumentException("Invalid locale format: " + str);
- }
- if (len == 2) {
- return new Locale(str, "");
+ final char ch0 = str.charAt(0);
+ if (ch0 == '_') {
+ if (len < 3) {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
+ final char ch1 = str.charAt(1);
+ final char ch2 = str.charAt(2);
+ if (!Character.isUpperCase(ch1) || !Character.isUpperCase(ch2)) {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
+ if (len == 3) {
+ return new Locale("", str.substring(1, 3));
+ }
+ if (len < 5) {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
+ if (str.charAt(3) != '_') {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
+ return new Locale("", str.substring(1, 3), str.substring(4));
} else {
+ final char ch1 = str.charAt(1);
+ if (!Character.isLowerCase(ch0) || !Character.isLowerCase(ch1)) {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
+ if (len == 2) {
+ return new Locale(str);
+ }
+ if (len < 5) {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
if (str.charAt(2) != '_') {
throw new IllegalArgumentException("Invalid locale format: " + str);
}
- char ch3 = str.charAt(3);
+ final char ch3 = str.charAt(3);
if (ch3 == '_') {
return new Locale(str.substring(0, 2), "", str.substring(4));
}
- char ch4 = str.charAt(4);
- if (ch3 < 'A' || ch3 > 'Z' || ch4 < 'A' || ch4 > 'Z') {
+ final char ch4 = str.charAt(4);
+ if (!Character.isUpperCase(ch3) || !Character.isUpperCase(ch4)) {
throw new IllegalArgumentException("Invalid locale format: " + str);
}
if (len == 5) {
return new Locale(str.substring(0, 2), str.substring(3, 5));
- } else {
- if (str.charAt(5) != '_') {
- throw new IllegalArgumentException("Invalid locale format: " + str);
- }
- return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
}
+ if (len < 7) {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
+ if (str.charAt(5) != '_') {
+ throw new IllegalArgumentException("Invalid locale format: " + str);
+ }
+ return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
}
}
@@ -493,7 +493,53 @@ private static void assertUnmodifiableCollection(Collection<?> coll) {
*/
@Test
public void testLang328() {
+ assertValidToLocale("fr__P", "fr", "", "P");
assertValidToLocale("fr__POSIX", "fr", "", "POSIX");
}
+ /**
+ * Tests #LANG-865, strings starting with an underscore.
+ */
+ @Test
+ public void testLang865() {
+ assertValidToLocale("_GB", "", "GB", "");
+ assertValidToLocale("_GB_P", "", "GB", "P");
+ assertValidToLocale("_GB_POSIX", "", "GB", "POSIX");
+ try {
+ LocaleUtils.toLocale("_G");
+ fail("Must be at least 3 chars if starts with underscore");
+ } catch (final IllegalArgumentException iae) {
+ }
+ try {
+ LocaleUtils.toLocale("_Gb");
+ fail("Must be uppercase if starts with underscore");
+ } catch (final IllegalArgumentException iae) {
+ }
+ try {
+ LocaleUtils.toLocale("_gB");
+ fail("Must be uppercase if starts with underscore");
+ } catch (final IllegalArgumentException iae) {
+ }
+ try {
+ LocaleUtils.toLocale("_1B");
+ fail("Must be letter if starts with underscore");
+ } catch (final IllegalArgumentException iae) {
+ }
+ try {
+ LocaleUtils.toLocale("_G1");
+ fail("Must be letter if starts with underscore");
+ } catch (final IllegalArgumentException iae) {
+ }
+ try {
+ LocaleUtils.toLocale("_GB_");
+ fail("Must be at least 5 chars if starts with underscore");
+ } catch (final IllegalArgumentException iae) {
+ }
+ try {
+ LocaleUtils.toLocale("_GBAP");
+ fail("Must have underscore after the country if starts with underscore and is at least 5 chars");
+ } catch (final IllegalArgumentException iae) {
+ }
+ }
+
}

0 comments on commit 75944e5

Please sign in to comment.