From a001c19cfd1c655bf5cdbc3066538410ee1cea06 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 19 Jul 2024 08:26:07 -0400 Subject: [PATCH 1/3] Add testLang1641() --- .../commons/lang3/time/FastDateFormatTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java index aa13e28453b..3007c515ef6 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java @@ -47,6 +47,9 @@ * 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; @@ -269,6 +272,20 @@ public void testLANG_954() { FastDateFormat.getInstance(pattern); } + @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"))); + } + @Test public void testParseSync() throws InterruptedException { final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS"; From abb0ca487cefc6d6df66600769655b3527a7f63e Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 19 Jul 2024 08:27:03 -0400 Subject: [PATCH 2/3] Rename some test methods --- .../lang3/time/FastDateFormatTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java index 3007c515ef6..698dd1ade4c 100644 --- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java +++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java @@ -248,7 +248,7 @@ public void testDateDefaults() { } @Test - public void testLANG_1152() { + public void testLang1152() { final TimeZone utc = FastTimeZone.getGmtTimeZone(); final Date date = new Date(Long.MAX_VALUE); @@ -259,19 +259,10 @@ public void testLANG_1152() { assertEquals("17/08/292278994", dateAsString); } @Test - public void testLANG_1267() { + public void testLang1267() { FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); } - /** - * According to LANG-954 (https://issues.apache.org/jira/browse/LANG-954) this is broken in Android 2.1. - */ - @Test - public void testLANG_954() { - final String pattern = "yyyy-MM-dd'T'"; - FastDateFormat.getInstance(pattern); - } - @Test public void testLang1641() { assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT), FastDateFormat.getInstance(ISO_8601_DATE_FORMAT)); @@ -286,6 +277,15 @@ public void testLang1641() { 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 testLang954() { + final String pattern = "yyyy-MM-dd'T'"; + FastDateFormat.getInstance(pattern); + } + @Test public void testParseSync() throws InterruptedException { final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS"; From 36bcd9a5f8d147ceaeb5aeb97ae11f67db6b1a0d Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 25 Apr 2026 12:03:22 +0000 Subject: [PATCH 3/3] [LANG-1821] NumberUtils.isCreatable fails for hexadecimal numbers with long type qualifier --- .../commons/lang3/math/NumberUtils.java | 11 ++++++-- .../commons/lang3/math/NumberUtilsTest.java | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java index 7327fac06b3..92b363a7233 100644 --- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -365,6 +365,7 @@ public static Number createNumber(final String str) { break; } } + final char lastChar = str.charAt(length - 1); if (pfxLen > 0) { // we have a hex number char firstSigDigit = 0; // strip leading zeroes for (int i = pfxLen; i < length; i++) { @@ -374,16 +375,22 @@ public static Number createNumber(final String str) { } pfxLen++; } - final int hexDigits = length - pfxLen; + final boolean isLongCh = lastChar == 'l' || lastChar == 'L'; + int hexDigits = length - pfxLen; + if (isLongCh) { + hexDigits--; + } if (hexDigits > 16 || hexDigits == 16 && firstSigDigit > '7') { // too many for Long return createBigInteger(str); } + if (isLongCh) { + return createLong(str.substring(0, str.length() - 1)); + } if (hexDigits > 8 || hexDigits == 8 && firstSigDigit > '7') { // too many for an int return createLong(str); } return createInteger(str); } - final char lastChar = str.charAt(length - 1); final String mant; final String dec; final String exp; diff --git a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java index 49b89422c22..16bdca67a2c 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -1232,6 +1232,31 @@ void testLang1729IsParsableShort() { assertFalse(isParsableShort("1 2 3")); } + /** + * Tests LANG-1821. + */ + @Test + void testLang1821() { + compareIsCreatableWithCreateNumber("123L", true); + compareIsCreatableWithCreateNumber("0xdef", true); + compareIsCreatableWithCreateNumber("0xdefL", true); + compareIsCreatableWithCreateNumber("0XDEFl", true); + // Integer.MAX_VALUE + compareIsCreatableWithCreateNumber("0x" + Integer.toHexString(Integer.MAX_VALUE), true); + compareIsCreatableWithCreateNumber("0x" + Integer.toHexString(Integer.MAX_VALUE) + "l", true); + compareIsCreatableWithCreateNumber("0x" + Integer.toHexString(Integer.MAX_VALUE) + "L", true); + compareIsCreatableWithCreateNumber("0X" + Integer.toHexString(Integer.MAX_VALUE), true); + compareIsCreatableWithCreateNumber("0X" + Integer.toHexString(Integer.MAX_VALUE) + "l", true); + compareIsCreatableWithCreateNumber("0X" + Integer.toHexString(Integer.MAX_VALUE) + "L", true); + // Long.MAX_VALUE + compareIsCreatableWithCreateNumber("0x" + Long.toHexString(Long.MAX_VALUE), true); + compareIsCreatableWithCreateNumber("0x" + Long.toHexString(Long.MAX_VALUE) + "l", true); + compareIsCreatableWithCreateNumber("0x" + Long.toHexString(Long.MAX_VALUE) + "L", true); + compareIsCreatableWithCreateNumber("0X" + Long.toHexString(Long.MAX_VALUE), true); + compareIsCreatableWithCreateNumber("0X" + Long.toHexString(Long.MAX_VALUE) + "l", true); + compareIsCreatableWithCreateNumber("0X" + Long.toHexString(Long.MAX_VALUE) + "L", true); + } + @Test void testLang300() { NumberUtils.createNumber("-1l");