Skip to content

Commit

Permalink
LANG-747 NumberUtils does not handle Long Hex numbers
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1507169 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
sebbASF committed Jul 26, 2013
1 parent 396afc3 commit d1a45e9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/main/java/org/apache/commons/lang3/math/NumberUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,20 @@ public static Number createNumber(final String str) throws NumberFormatException
}
}
if (pfxLen > 0) { // we have a hex number
char firstSigDigit = 0; // strip leading zeroes
for(int i = pfxLen; i < str.length(); i++) {
firstSigDigit = str.charAt(i);
if (firstSigDigit == '0') { // count leading zeroes
pfxLen++;
} else {
break;
}
}
final int hexDigits = str.length() - pfxLen;
if (hexDigits > 16) { // too many for Long
if (hexDigits > 16 || (hexDigits == 16 && firstSigDigit > '7')) { // too many for Long
return createBigInteger(str);
}
if (hexDigits > 8) { // too many for an int
if (hexDigits > 8 || (hexDigits == 8 && firstSigDigit > '7')) { // too many for an int
return createLong(str);
}
return createInteger(str);
Expand Down
37 changes: 37 additions & 0 deletions src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,43 @@ public void testCreateNumber() {
assertEquals(BigDecimal.class, bigNum.getClass());
}

@Test
public void TestLang747() {
assertEquals(Integer.valueOf(0x8000), NumberUtils.createNumber("0x8000"));
assertEquals(Integer.valueOf(0x80000), NumberUtils.createNumber("0x80000"));
assertEquals(Integer.valueOf(0x800000), NumberUtils.createNumber("0x800000"));
assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x8000000"));
assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x7FFFFFFF"));
assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x80000000"));
assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0xFFFFFFFF"));

// Leading zero tests
assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x08000000"));
assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x007FFFFFFF"));
assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x080000000"));
assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0x00FFFFFFFF"));

assertEquals(Long.valueOf(0x800000000L), NumberUtils.createNumber("0x800000000"));
assertEquals(Long.valueOf(0x8000000000L), NumberUtils.createNumber("0x8000000000"));
assertEquals(Long.valueOf(0x80000000000L), NumberUtils.createNumber("0x80000000000"));
assertEquals(Long.valueOf(0x800000000000L), NumberUtils.createNumber("0x800000000000"));
assertEquals(Long.valueOf(0x8000000000000L), NumberUtils.createNumber("0x8000000000000"));
assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x80000000000000"));
assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x800000000000000"));
assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x7FFFFFFFFFFFFFFF"));
// N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x8000000000000000"));
assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0xFFFFFFFFFFFFFFFF"));

// Leading zero tests
assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x00080000000000000"));
assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x0800000000000000"));
assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x07FFFFFFFFFFFFFFF"));
// N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x00008000000000000000"));
assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0x0FFFFFFFFFFFFFFFF"));
}

@Test(expected=NumberFormatException.class)
// Check that the code fails to create a valid number when preceeded by -- rather than -
public void testCreateNumberFailure_1() {
Expand Down

0 comments on commit d1a45e9

Please sign in to comment.