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",