This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-lang.git
commit dde6790a88d8a2ec438568a4513d7d359d3602cc Author: aherbert <aherb...@apache.org> AuthorDate: Thu Mar 4 15:12:35 2021 +0000 [LANG-1645] NumberUtils to recognise hex integers prefixed with + Closes #728 --- src/changes/changes.xml | 2 ++ .../org/apache/commons/lang3/math/NumberUtils.java | 15 +++++++++++---- .../apache/commons/lang3/math/NumberUtilsTest.java | 21 +++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 9b6419b..08fdbb6 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -46,6 +46,8 @@ The <action> type attribute can be add,update,fix,remove. <body> <release version="3.12.1" date="2021-MM-DD" description="New features and bug fixes (Java 8)."> + <!-- FIX --> + <action issue="LANG-1645" type="fix" dev="aherbert" due-to="Alex Herbert">NumberUtils to recognise hex integers prefixed with +</action> </release> <release version="3.12.0" date="2021-02-26" description="New features and bug fixes (Java 8)."> 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 45c5dbf..50c0923 100644 --- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -668,12 +668,13 @@ public class NumberUtils { throw new NumberFormatException("A blank string is not a valid number"); } // Need to deal with all possible hex prefixes here - final String[] hex_prefixes = {"0x", "0X", "-0x", "-0X", "#", "-#"}; + final String[] hex_prefixes = {"0x", "0X", "#"}; final int length = str.length(); + final int offset = str.charAt(0) == '+' || str.charAt(0) == '-' ? 1 : 0; int pfxLen = 0; for (final String pfx : hex_prefixes) { - if (str.startsWith(pfx)) { - pfxLen += pfx.length(); + if (str.startsWith(pfx, offset)) { + pfxLen += pfx.length() + offset; break; } } @@ -962,12 +963,18 @@ public class NumberUtils { if (str == null) { return null; } + if (str.isEmpty()) { + throw new NumberFormatException("An empty string is not a valid number"); + } int pos = 0; // offset within string int radix = 10; boolean negate = false; // need to negate later? - if (str.startsWith("-")) { + final char char0 = str.charAt(0); + if (char0 == '-') { negate = true; pos = 1; + } else if (char0 == '+') { + pos = 1; } if (str.startsWith("0x", pos) || str.startsWith("0X", pos)) { // hex radix = 16; 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 ec62278..db3d5d2 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -396,6 +396,10 @@ public class NumberUtilsTest { testCreateBigIntegerFailure("-#"); testCreateBigIntegerFailure("0x"); testCreateBigIntegerFailure("-0x"); + // LANG-1645 + assertEquals(new BigInteger("+FFFFFFFFFFFFFFFF", 16), NumberUtils.createBigInteger("+0xFFFFFFFFFFFFFFFF")); + assertEquals(new BigInteger("+FFFFFFFFFFFFFFFF", 16), NumberUtils.createBigInteger("+#FFFFFFFFFFFFFFFF")); + assertEquals(new BigInteger("+1234567", 8), NumberUtils.createBigInteger("+01234567")); } protected void testCreateBigIntegerFailure(final String str) { @@ -444,6 +448,8 @@ public class NumberUtilsTest { this.testCreateIntegerFailure("\b\t\n\f\r"); // Funky whitespaces this.testCreateIntegerFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F"); + // LANG-1645 + assertEquals(Integer.decode("+0xF"), NumberUtils.createInteger("+0xF")); } protected void testCreateIntegerFailure(final String str) { @@ -460,6 +466,8 @@ public class NumberUtilsTest { this.testCreateLongFailure("\b\t\n\f\r"); // Funky whitespaces this.testCreateLongFailure("\u00A0\uFEFF\u000B\u000C\u001C\u001D\u001E\u001F"); + // LANG-1645 + assertEquals(Long.decode("+0xFFFFFFFF"), NumberUtils.createLong("+0xFFFFFFFF")); } protected void testCreateLongFailure(final String str) { @@ -560,6 +568,13 @@ public class NumberUtilsTest { "createNumber(String) LANG-1060m failed"); assertEquals(Double.valueOf("-001.1E200"), NumberUtils.createNumber("-001.1E200"), "createNumber(String) LANG-1060n failed"); + // LANG-1645 + assertEquals(Integer.decode("+0xF"), NumberUtils.createNumber("+0xF"), + "createNumber(String) LANG-1645a failed"); + assertEquals(Long.decode("+0xFFFFFFFF"), NumberUtils.createNumber("+0xFFFFFFFF"), + "createNumber(String) LANG-1645b failed"); + assertEquals(new BigInteger("+FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("+0xFFFFFFFFFFFFFFFF"), + "createNumber(String) LANG-1645c failed"); } @Test @@ -699,6 +714,9 @@ public class NumberUtilsTest { compareIsCreatableWithCreateNumber("2.", true); // LANG-521 compareIsCreatableWithCreateNumber("1.1L", false); // LANG-664 + compareIsCreatableWithCreateNumber("+0xF", true); // LANG-1645 + compareIsCreatableWithCreateNumber("+0xFFFFFFFF", true); // LANG-1645 + compareIsCreatableWithCreateNumber("+0xFFFFFFFFFFFFFFFF", true); // LANG-1645 } @Test @@ -774,6 +792,9 @@ public class NumberUtilsTest { compareIsNumberWithCreateNumber("2.", true); // LANG-521 compareIsNumberWithCreateNumber("1.1L", false); // LANG-664 + compareIsNumberWithCreateNumber("+0xF", true); // LANG-1645 + compareIsNumberWithCreateNumber("+0xFFFFFFFF", true); // LANG-1645 + compareIsNumberWithCreateNumber("+0xFFFFFFFFFFFFFFFF", true); // LANG-1645 } @Test