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

Reply via email to