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-beanutils.git


The following commit(s) were added to refs/heads/master by this push:
     new b23c7cd8 Reject out-of-range long and float values in NumberConverter 
(#404)
b23c7cd8 is described below

commit b23c7cd8de88b74cb4a7942cbe7a93b08f22525b
Author: Dexter.k <[email protected]>
AuthorDate: Fri Jun 26 11:33:37 2026 +0000

    Reject out-of-range long and float values in NumberConverter (#404)
    
    The Long branch had no bounds check and the Float branch checked only the 
upper bound, so out-of-range input was silently clamped to Long.MAX_VALUE or to 
-Infinity instead of throwing. Add the missing checks mirroring the 
byte/short/int branches.
---
 .../beanutils2/converters/NumberConverter.java     |  9 ++++++
 .../beanutils2/converters/FloatConverterTest.java  |  6 ++++
 .../beanutils2/converters/LongConverterTest.java   | 33 ++++++++++++++++++++++
 3 files changed, 48 insertions(+)

diff --git 
a/src/main/java/org/apache/commons/beanutils2/converters/NumberConverter.java 
b/src/main/java/org/apache/commons/beanutils2/converters/NumberConverter.java
index 5e60b1ca..87344ca8 100644
--- 
a/src/main/java/org/apache/commons/beanutils2/converters/NumberConverter.java
+++ 
b/src/main/java/org/apache/commons/beanutils2/converters/NumberConverter.java
@@ -449,6 +449,12 @@ public abstract class NumberConverter<N extends Number> 
extends AbstractConverte
 
         // Long
         if (targetType.equals(Long.class)) {
+            if (value.doubleValue() > Long.MAX_VALUE) {
+                throw ConversionException.format("%s value '%s' is too large 
for %s", toString(sourceType), value, toString(targetType));
+            }
+            if (value.doubleValue() < Long.MIN_VALUE) {
+                throw ConversionException.format("%s value '%s' is too small 
%s", toString(sourceType), value, toString(targetType));
+            }
             return targetType.cast(Long.valueOf(value.longValue()));
         }
 
@@ -457,6 +463,9 @@ public abstract class NumberConverter<N extends Number> 
extends AbstractConverte
             if (value.doubleValue() > Float.MAX_VALUE) {
                 throw ConversionException.format("%s value '%s' is too large 
for %s", toString(sourceType), value, toString(targetType));
             }
+            if (value.doubleValue() < -Float.MAX_VALUE) {
+                throw ConversionException.format("%s value '%s' is too small 
%s", toString(sourceType), value, toString(targetType));
+            }
             return targetType.cast(Float.valueOf(value.floatValue()));
         }
 
diff --git 
a/src/test/java/org/apache/commons/beanutils2/converters/FloatConverterTest.java
 
b/src/test/java/org/apache/commons/beanutils2/converters/FloatConverterTest.java
index e7c4b97a..683b37f5 100644
--- 
a/src/test/java/org/apache/commons/beanutils2/converters/FloatConverterTest.java
+++ 
b/src/test/java/org/apache/commons/beanutils2/converters/FloatConverterTest.java
@@ -70,11 +70,17 @@ class FloatConverterTest extends 
AbstractNumberConverterTest<Float> {
         final Converter<Float> converter = makeConverter();
         final Class<?> clazz = Float.class;
         final Double max = Double.valueOf(Float.MAX_VALUE);
+        final Double min = Double.valueOf(-Float.MAX_VALUE);
         final Double tooBig = Double.valueOf(Double.MAX_VALUE);
+        final Double tooSmall = Double.valueOf(-Double.MAX_VALUE);
         // Maximum
         assertEquals(Float.valueOf(Float.MAX_VALUE), converter.convert(clazz, 
max), "Maximum");
+        // Minimum
+        assertEquals(Float.valueOf(-Float.MAX_VALUE), converter.convert(clazz, 
min), "Minimum");
         // Too Large
         assertThrows(ConversionException.class, () -> converter.convert(clazz, 
tooBig), "More than maximum, expected ConversionException");
+        // Too Small
+        assertThrows(ConversionException.class, () -> converter.convert(clazz, 
tooSmall), "Less than minimum, expected ConversionException");
     }
 
     @Test
diff --git 
a/src/test/java/org/apache/commons/beanutils2/converters/LongConverterTest.java 
b/src/test/java/org/apache/commons/beanutils2/converters/LongConverterTest.java
index a6b8811a..c4c82813 100644
--- 
a/src/test/java/org/apache/commons/beanutils2/converters/LongConverterTest.java
+++ 
b/src/test/java/org/apache/commons/beanutils2/converters/LongConverterTest.java
@@ -18,7 +18,12 @@
 package org.apache.commons.beanutils2.converters;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
+import java.math.BigInteger;
+import java.util.Locale;
+
+import org.apache.commons.beanutils2.ConversionException;
 import org.apache.commons.beanutils2.Converter;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -60,6 +65,34 @@ class LongConverterTest extends 
AbstractNumberConverterTest<Long> {
         converter = null;
     }
 
+    /**
+     * Test Invalid Amounts (too big/small)
+     */
+    @Test
+    void testInvalidAmount() {
+        final Converter<Long> converter = makeConverter();
+        final Class<?> clazz = Long.class;
+        // Boundaries still convert
+        assertEquals(Long.valueOf(Long.MIN_VALUE), converter.convert(clazz, 
Long.valueOf(Long.MIN_VALUE)), "Minimum");
+        assertEquals(Long.valueOf(Long.MAX_VALUE), converter.convert(clazz, 
Long.valueOf(Long.MAX_VALUE)), "Maximum");
+        // Out of range Number values must be rejected, not silently 
truncated/clamped
+        final BigInteger tooSmall = 
BigInteger.valueOf(Long.MIN_VALUE).multiply(BigInteger.TEN);
+        final BigInteger tooBig = 
BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.TEN);
+        assertThrows(ConversionException.class, () -> converter.convert(clazz, 
tooSmall), "Less than minimum, expected ConversionException");
+        assertThrows(ConversionException.class, () -> converter.convert(clazz, 
tooBig), "More than maximum, expected ConversionException");
+    }
+
+    /**
+     * A locale-parsed String beyond long range comes back from {@link 
java.text.DecimalFormat} as a {@link Double} and must be rejected rather than 
clamped to
+     * {@link Long#MAX_VALUE}.
+     */
+    @Test
+    void testLocaleStringOutOfRange() {
+        final LongConverter converter = makeConverter();
+        converter.setLocale(Locale.US);
+        assertThrows(ConversionException.class, () -> 
converter.convert(Long.class, "99999999999999999999"), "More than maximum, 
expected ConversionException");
+    }
+
     @Test
     void testSimpleConversion() throws Exception {
         final String[] message = { "from String", "from String", "from 
String", "from String", "from String", "from String", "from String", "from 
Byte",

Reply via email to