Merge branch 'master' of https://gitbox.apache.org/repos/asf/commons-lang.git
This commit is contained in:
commit
69e3ba4188
|
@ -57,7 +57,7 @@ jobs:
|
|||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # 3.25.12
|
||||
uses: github/codeql-action/init@2d790406f505036ef40ecba973cc774a50395aac # 3.25.13
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
|
@ -68,7 +68,7 @@ jobs:
|
|||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # 3.25.12
|
||||
uses: github/codeql-action/autobuild@2d790406f505036ef40ecba973cc774a50395aac # 3.25.13
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
@ -82,4 +82,4 @@ jobs:
|
|||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # 3.25.12
|
||||
uses: github/codeql-action/analyze@2d790406f505036ef40ecba973cc774a50395aac # 3.25.13
|
||||
|
|
|
@ -64,6 +64,6 @@ jobs:
|
|||
retention-days: 5
|
||||
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # 3.25.12
|
||||
uses: github/codeql-action/upload-sarif@2d790406f505036ef40ecba973cc774a50395aac # 3.25.13
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
@ -46,14 +46,16 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
</properties>
|
||||
<body>
|
||||
<release version="3.16.0" date="YYYY-MM-DD" description="This is a feature and maintenance release. Java 8 or later is required.">
|
||||
<!-- FIX -->
|
||||
<action type="fix" dev="ggregory" due-to="Gary Gregory">Reimplement StopWatch internals to use java.time.</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>
|
||||
<action type="add" dev="ggregory" due-to="Gary Gregory">Add StopWatch.getStopInstant() and deprecate getStopTime().</action>
|
||||
<action type="add" dev="ggregory" due-to="Gary Gregory">Add StopWatch.getDuration() and deprecate getTime().</action>
|
||||
<!-- UPDATE -->
|
||||
<!-- 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>
|
||||
<action type="add" dev="ggregory" due-to="Gary Gregory">Add StopWatch.getStopInstant() and deprecate getStopTime().</action>
|
||||
<action type="add" dev="ggregory" due-to="Gary Gregory">Add StopWatch.getDuration() and deprecate getTime().</action>
|
||||
<!-- UPDATE -->
|
||||
</release>
|
||||
<release version="3.15.0" date="2024-07-13" description="New features and bug fixes (Java 8 or above).">
|
||||
<!-- ADD -->
|
||||
|
|
|
@ -52,18 +52,31 @@ public class LocaleUtils {
|
|||
AVAILABLE_LOCALE_SET = Collections.unmodifiableSet(new HashSet<>(list));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The underscore character {@code '}{@value}{@code '}.
|
||||
*/
|
||||
private static final char UNDERSCORE = '_';
|
||||
|
||||
/**
|
||||
* The undetermined language {@value}.
|
||||
*/
|
||||
private static final String UNDETERMINED = "und";
|
||||
|
||||
/**
|
||||
* The dash character {@code '}{@value}{@code '}.
|
||||
*/
|
||||
private static final char DASH = '-';
|
||||
|
||||
/** Concurrent map of language locales by country. */
|
||||
private static final ConcurrentMap<String, List<Locale>> cLanguagesByCountry =
|
||||
new ConcurrentHashMap<>();
|
||||
/**
|
||||
* Concurrent map of language locales by country.
|
||||
*/
|
||||
private static final ConcurrentMap<String, List<Locale>> cLanguagesByCountry = new ConcurrentHashMap<>();
|
||||
|
||||
/** Concurrent map of country locales by language. */
|
||||
private static final ConcurrentMap<String, List<Locale>> cCountriesByLanguage =
|
||||
new ConcurrentHashMap<>();
|
||||
/**
|
||||
* Concurrent map of country locales by language.
|
||||
*/
|
||||
private static final ConcurrentMap<String, List<Locale>> cCountriesByLanguage = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Obtains an unmodifiable list of installed locales.
|
||||
|
@ -236,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) &&
|
||||
|
|
|
@ -232,6 +232,8 @@ public class RandomStringUtils {
|
|||
}
|
||||
} else if (end <= start) {
|
||||
throw new IllegalArgumentException("Parameter end (" + end + ") must be greater than start (" + start + ")");
|
||||
} else if (start < 0 || end < 0) {
|
||||
throw new IllegalArgumentException("Character positions MUST be >= 0");
|
||||
}
|
||||
|
||||
if (end > Character.MAX_CODE_POINT) {
|
||||
|
|
|
@ -538,11 +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");
|
||||
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"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,23 +93,43 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testExceptions() {
|
||||
final char[] DUMMY = { 'a' }; // valid char array
|
||||
public void testExceptionsRandom() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, true, true));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, DUMMY));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, new char[] { 'a' }));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(1, new char[0]));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, ""));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, (String) null));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, 'a', 'z', false, false));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, 'a', 'z', false, false, DUMMY));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, 'a', 'z', false, false, DUMMY, new Random()));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, 'a', 'z', false, false, new char[] { 'a' }));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, 'a', 'z', false, false, new char[] { 'a' }, new Random()));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(8, 32, 48, false, true));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(8, 32, 65, true, false));
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(1, Integer.MIN_VALUE, -10, false, false, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomAlphabetic() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomAlphabetic(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomAscii() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomAscii(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomGraph() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomGraph(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomNumeric() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomNumeric(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomPrint() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomPrint(-1));
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ import org.junitpioneer.jupiter.DefaultTimeZone;
|
|||
* Unit tests {@link org.apache.commons.lang3.time.FastDateFormat}.
|
||||
*/
|
||||
public class FastDateFormatTest extends AbstractLangTest {
|
||||
|
||||
private static final String ISO_8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZZ";
|
||||
|
||||
private static final int NTHREADS = 10;
|
||||
|
||||
private static final int NROUNDS = 10000;
|
||||
|
@ -245,7 +248,7 @@ public class FastDateFormatTest extends AbstractLangTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testLANG_1152() {
|
||||
public void testLang1152() {
|
||||
final TimeZone utc = FastTimeZone.getGmtTimeZone();
|
||||
final Date date = new Date(Long.MAX_VALUE);
|
||||
|
||||
|
@ -256,15 +259,29 @@ public class FastDateFormatTest extends AbstractLangTest {
|
|||
assertEquals("17/08/292278994", dateAsString);
|
||||
}
|
||||
@Test
|
||||
public void testLANG_1267() {
|
||||
public void testLang1267() {
|
||||
FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLang1641() {
|
||||
assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT), FastDateFormat.getInstance(ISO_8601_DATE_FORMAT));
|
||||
// commons-lang's GMT TimeZone
|
||||
assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, FastTimeZone.getGmtTimeZone()),
|
||||
FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, FastTimeZone.getGmtTimeZone()));
|
||||
// default TimeZone
|
||||
assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault()),
|
||||
FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault()));
|
||||
// TimeZones that are identical in every way except ID
|
||||
assertNotSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Broken_Hill")),
|
||||
FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Yancowinna")));
|
||||
}
|
||||
|
||||
/**
|
||||
* According to LANG-954 (https://issues.apache.org/jira/browse/LANG-954) this is broken in Android 2.1.
|
||||
*/
|
||||
@Test
|
||||
public void testLANG_954() {
|
||||
public void testLang954() {
|
||||
final String pattern = "yyyy-MM-dd'T'";
|
||||
FastDateFormat.getInstance(pattern);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue