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 8d92fa642 Reject leading whitespace in NumberUtils.createNumber (#1833)
8d92fa642 is described below

commit 8d92fa6421e5446ff831f0f77975e2d05d8ae17c
Author: Gary Gregory <[email protected]>
AuthorDate: Sat Oct 24 08:09:49 2026 -0400

    Reject leading whitespace in NumberUtils.createNumber (#1833)
    
    Simplify NumberUtils.createNumber empty-input validation.
    
    Follow up to #1833. Replace the redundant blank check with an
    empty-string
    check now that leading ASCII whitespace and control characters are
    rejected explicitly.
    
    Add tests for empty and Unicode-whitespace inputs and all leading
    characters from U+0000 through U+0020 across numeric formats.
---
 src/changes/changes.xml                               |  1 +
 .../org/apache/commons/lang3/math/NumberUtils.java    |  4 ++--
 .../apache/commons/lang3/math/NumberUtilsTest.java    | 19 +++++++++++++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 27c1dd418..4b79c74da 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -69,6 +69,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action                   type="fix" dev="ggregory" due-to="alhuda, Gary 
Gregory">Reject varargs candidates with too few arguments in MemberUtils 
(#1828).</action>
     <action issue="LANG-1323" type="fix" dev="ggregory" due-to="Aryan R. 
Ganjoo, Gary Gregory">Align built type hashes with JDK reflection 
(#1826).</action>
     <action                   type="fix" dev="ggregory" due-to="alhuda, Gary 
Gregory">Keep array encoding intact in ClassUtils.getAbbreviatedName 
(#1829).</action>
+    <action                   type="fix" dev="ggregory" due-to="alhuda, Gary 
Gregory">Reject leading whitespace in NumberUtils.createNumber (#1833).</action>
     <!-- ADD -->
     <!-- UPDATE -->
     <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
org.apache.commons:commons-parent from 105 to 106.</action>
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 1e9fc9d99..4f813303b 100644
--- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
+++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
@@ -356,8 +356,8 @@ public static Number createNumber(final String str) {
         if (str == null) {
             return null;
         }
-        if (StringUtils.isBlank(str)) {
-            throw new NumberFormatException("A blank string is not a valid 
number");
+        if (str.isEmpty()) {
+            throw new NumberFormatException("An empty string is not a valid 
number");
         }
         // Float.valueOf(String) and Double.valueOf(String) trim leading 
characters up to U+0020, the integral parsers do not.
         if (str.charAt(0) <= ' ') {
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 3c36b3c7c..2c0726d2f 100644
--- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
@@ -690,6 +690,14 @@ void testCreateNumber() {
         assertEquals(new BigDecimal("0.100000001490116121"), 
NumberUtils.createNumber("0.100000001490116121"));
     }
 
+    @ParameterizedTest
+    @ValueSource(strings = { "", " ", "\t", "\r\n", "\u2003", "\u2003 \u2003", 
"\u00a0" })
+    void testCreateNumberBlank(final String str) {
+        assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber(str));
+        compareIsCreatableWithCreateNumber(str, false);
+        compareIsNumberWithCreateNumber(str, false);
+    }
+
     @Test
     // Check that the code fails to create a valid number when preceded by -- 
rather than -
     void testCreateNumberFailure_1() {
@@ -753,6 +761,17 @@ void testCreateNumberFailure_9() {
         assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber("-L"));
     }
 
+    @ParameterizedTest
+    @ValueSource(strings = { "1.5", ".5", "1e5", "1.5f", "1.5F", "1.5d", 
"1.5D", "+1.5", "-1.5" })
+    void testCreateNumberLeadingControlCharacters(final String str) {
+        for (char ch = 0; ch <= ' '; ch++) {
+            final String input = ch + str;
+            assertThrows(NumberFormatException.class, () -> 
NumberUtils.createNumber(input), () -> "Leading character: " + (int) 
input.charAt(0));
+            compareIsCreatableWithCreateNumber(input, false);
+            compareIsNumberWithCreateNumber(input, false);
+        }
+    }
+
     // 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

Reply via email to