This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a92df9fa Fix NumberUtils.createNumber() and isCreatable() for 
positive Long literals with explicit '+' sign (#1796)
9a92df9fa is described below

commit 9a92df9fa33d2f84a7c2037c52ca37e9cb647be1
Author: gaurav kumar pandey <[email protected]>
AuthorDate: Tue Sep 22 03:10:30 2026 +0530

    Fix NumberUtils.createNumber() and isCreatable() for positive Long literals 
with explicit '+' sign (#1796)
    
    * Fix NumberUtils.createNumber() and isCreatable() for positive Long 
literals with explicit '+' sign
    
    - Support positive Long and BigInteger literals with explicit '+' prefix 
and 'l'/'L' qualifier in NumberUtils.createNumber()
    
    - Replace strict '-' check with isSign() to recognize '+'
    
    - Add unit tests for +L and +l in NumberUtilsTest
    
    * Add regression tests for malformed signs and Long boundary cases
    
    * Fix comment
    
    ---------
    
    Co-authored-by: Gary Gregory <[email protected]>
---
 .../org/apache/commons/lang3/math/NumberUtils.java |  2 +-
 .../apache/commons/lang3/math/NumberUtilsTest.java | 54 ++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)

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 f9c6b3956..c2a1673a1 100644
--- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
+++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
@@ -439,7 +439,7 @@ public static Number createNumber(final String str) {
             switch (lastChar) {
             case 'l':
             case 'L':
-                if (dec == null && exp == null && (!numeric.isEmpty() && 
numeric.charAt(0) == '-' && isDigits(numeric.substring(1)) || 
isDigits(numeric))) {
+                if (dec == null && exp == null && (!numeric.isEmpty() && 
isSign(numeric.charAt(0)) && isDigits(numeric.substring(1)) || 
isDigits(numeric))) {
                     try {
                         return createLong(numeric);
                     } catch (final NumberFormatException ignored) {
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 5753d81a2..5e1ea8358 100644
--- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
@@ -609,6 +609,18 @@ void testCreateNumber() {
         assertEquals(Long.valueOf(Integer.MAX_VALUE + 1L), 
NumberUtils.createNumber("" + (Integer.MAX_VALUE + 1L)), "createNumber(String) 
5 failed");
         assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345L"), 
"createNumber(String) 6 failed");
         assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345l"), 
"createNumber(String) 6 failed");
+        assertEquals(Long.valueOf(12345), NumberUtils.createNumber("+12345L"), 
"createNumber(String) +L failed");
+        assertEquals(Long.valueOf(12345), NumberUtils.createNumber("+12345l"), 
"createNumber(String) +l failed");
+        assertEquals(Long.valueOf(-12345), 
NumberUtils.createNumber("-12345L"), "createNumber(String) -L failed");
+        assertEquals(Long.valueOf(-12345), 
NumberUtils.createNumber("-12345l"), "createNumber(String) -l failed");
+        assertEquals(Long.valueOf(0), NumberUtils.createNumber("+0L"), 
"createNumber(String) +0L failed");
+        assertEquals(Long.valueOf(0), NumberUtils.createNumber("+0l"), 
"createNumber(String) +0l failed");
+        assertEquals(Long.valueOf(Long.MAX_VALUE), 
NumberUtils.createNumber("+" + Long.MAX_VALUE + "L"), "createNumber(String) 
+Long.MAX_VALUE L failed");
+        assertEquals(Long.valueOf(Long.MAX_VALUE), 
NumberUtils.createNumber("+" + Long.MAX_VALUE + "l"), "createNumber(String) 
+Long.MAX_VALUE l failed");
+        assertEquals(Long.valueOf(Long.MAX_VALUE), 
NumberUtils.createNumber(Long.MAX_VALUE + "L"), "createNumber(String) 
Long.MAX_VALUE L failed");
+        assertEquals(Long.valueOf(Long.MAX_VALUE), 
NumberUtils.createNumber(Long.MAX_VALUE + "l"), "createNumber(String) 
Long.MAX_VALUE l failed");
+        assertEquals(Long.valueOf(Long.MIN_VALUE), 
NumberUtils.createNumber(Long.MIN_VALUE + "L"), "createNumber(String) 
Long.MIN_VALUE L failed");
+        assertEquals(Long.valueOf(Long.MIN_VALUE), 
NumberUtils.createNumber(Long.MIN_VALUE + "l"), "createNumber(String) 
Long.MIN_VALUE l failed");
         assertEquals(Float.valueOf("-1234.5"), 
NumberUtils.createNumber("-1234.5"), "createNumber(String) 7 failed");
         assertEquals(Integer.valueOf("-12345"), 
NumberUtils.createNumber("-12345"), "createNumber(String) 8 failed");
         assertEquals(0xFADE, NumberUtils.createNumber("0xFADE").intValue(), 
"createNumber(String) 9a failed");
@@ -621,6 +633,12 @@ void testCreateNumber() {
         assertEquals(Double.valueOf("1.1E-200"), 
NumberUtils.createNumber("1.1E-200"), "createNumber(String) 14 failed");
         assertNull(NumberUtils.createNumber(null), "createNumber(null) 
failed");
         assertEquals(new BigInteger("12345678901234567890"), 
NumberUtils.createNumber("12345678901234567890L"), "createNumber(String) 
failed");
+        assertEquals(new BigInteger("12345678901234567890"), 
NumberUtils.createNumber("+12345678901234567890L"), "createNumber(String) 
failed");
+        assertEquals(new BigInteger("12345678901234567890"), 
NumberUtils.createNumber("+12345678901234567890l"), "createNumber(String) 
failed");
+        final BigInteger overMaxLong = 
BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
+        assertEquals(overMaxLong, NumberUtils.createNumber("+" + overMaxLong + 
"L"), "createNumber(String) +overMaxLong L failed");
+        assertEquals(overMaxLong, NumberUtils.createNumber("+" + overMaxLong + 
"l"), "createNumber(String) +overMaxLong l failed");
+        assertEquals(overMaxLong, NumberUtils.createNumber(overMaxLong + "L"), 
"createNumber(String) overMaxLong L failed");
         assertEquals(new BigDecimal("1.1E-700"), 
NumberUtils.createNumber("1.1E-700F"), "createNumber(String) 15 failed");
         assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), 
NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"), "createNumber(String) 
16 failed");
         assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), 
NumberUtils.createNumber("10" + Integer.MAX_VALUE), "createNumber(String) 17 
failed");
@@ -720,6 +738,21 @@ void testCreateNumberFailure_8() {
         assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("1234.5DD"));
     }
 
+    /**
+     * Reject malformed signs in Long-suffixed numbers.
+     */
+    @Test
+    void testCreateNumberFailure_9() {
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("++1L"));
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("++1l"));
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("--1L"));
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("--1l"));
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("+-1L"));
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("-+1L"));
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("+L"));
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("-L"));
+    }
+
     // Tests to show when magnitude causes switch to next Number type
     // Will probably need to be adjusted if code is changed to check precision 
(LANG-693)
     @Test
@@ -833,6 +866,19 @@ void testIsCreatable() {
         compareIsCreatableWithCreateNumber("123.4E21D", true);
         compareIsCreatableWithCreateNumber("-221.23F", true);
         compareIsCreatableWithCreateNumber("22338L", true);
+        compareIsCreatableWithCreateNumber("+22338L", true);
+        compareIsCreatableWithCreateNumber("+22338l", true);
+        compareIsCreatableWithCreateNumber("+0L", true);
+        compareIsCreatableWithCreateNumber("+0l", true);
+        compareIsCreatableWithCreateNumber("+" + Long.MAX_VALUE + "L", true);
+        compareIsCreatableWithCreateNumber("+" + Long.MAX_VALUE + "l", true);
+        compareIsCreatableWithCreateNumber(Long.MAX_VALUE + "L", true);
+        compareIsCreatableWithCreateNumber(Long.MAX_VALUE + "l", true);
+        compareIsCreatableWithCreateNumber(Long.MIN_VALUE + "L", true);
+        compareIsCreatableWithCreateNumber(Long.MIN_VALUE + "l", true);
+        compareIsCreatableWithCreateNumber("+" + 
BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE) + "L", true);
+        compareIsCreatableWithCreateNumber("+" + 
BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE) + "l", true);
+        compareIsCreatableWithCreateNumber("+12345678901234567890L", true);
         compareIsCreatableWithCreateNumber(null, false);
         compareIsCreatableWithCreateNumber("", false);
         compareIsCreatableWithCreateNumber(" ", false);
@@ -842,6 +888,14 @@ void testIsCreatable() {
         compareIsCreatableWithCreateNumber("-+2", false);
         compareIsCreatableWithCreateNumber("+-2", false);
         compareIsCreatableWithCreateNumber("++2", false);
+        compareIsCreatableWithCreateNumber("++1L", false);
+        compareIsCreatableWithCreateNumber("++1l", false);
+        compareIsCreatableWithCreateNumber("--1L", false);
+        compareIsCreatableWithCreateNumber("--1l", false);
+        compareIsCreatableWithCreateNumber("+-1L", false);
+        compareIsCreatableWithCreateNumber("-+1L", false);
+        compareIsCreatableWithCreateNumber("+L", false);
+        compareIsCreatableWithCreateNumber("-L", false);
         compareIsCreatableWithCreateNumber(".12.3", false);
         compareIsCreatableWithCreateNumber("-123E", false);
         compareIsCreatableWithCreateNumber("-123E+-212", false);

Reply via email to