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");