Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.commons.validator.routines;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.Format;
import java.text.NumberFormat;
Expand Down Expand Up @@ -120,7 +121,7 @@ public BigIntegerValidator(final boolean strict, final int formatType) {
* specified range.
*/
public boolean isInRange(final BigInteger value, final long min, final long max) {
return value.longValue() >= min && value.longValue() <= max;
return value.compareTo(BigInteger.valueOf(min)) >= 0 && value.compareTo(BigInteger.valueOf(max)) <= 0;
}

/**
Expand All @@ -132,7 +133,7 @@ public boolean isInRange(final BigInteger value, final long min, final long max)
* or equal to the maximum.
*/
public boolean maxValue(final BigInteger value, final long max) {
return value.longValue() <= max;
return value.compareTo(BigInteger.valueOf(max)) <= 0;
}

/**
Expand All @@ -157,7 +158,14 @@ public boolean minValue(final BigInteger value, final long min) {
*/
@Override
protected Object processParsedValue(final Object value, final Format formatter) {
return BigInteger.valueOf(((Number) value).longValue());
if (value instanceof Long) {
return BigInteger.valueOf(((Long) value).longValue());
}
if (value instanceof Double) {
// No need to roundtrip with a string.
return BigDecimal.valueOf(((Double) value).doubleValue()).toBigInteger();
}
return new BigDecimal(value.toString()).toBigInteger();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,50 @@ protected void setUp() {

}

/**
* Test a value larger than {@link Long#MAX_VALUE} keeps its magnitude instead of being clamped to {@link Long#MAX_VALUE}.
*/
@Test
void testBigIntegerAboveLongMaxValue() {
// One past Long.MAX_VALUE, so NumberFormat parses it as a Double rather than a Long.
final BigInteger aboveLong = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
final String aboveLongStr = aboveLong.toString();
final BigIntegerValidator instance = BigIntegerValidator.getInstance();
final BigInteger resultAboveLong = instance.validate(aboveLongStr, "#");
assertTrue(resultAboveLong.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) > 0);
assertTrue(resultAboveLong.compareTo(BigInteger.ZERO) > 0);
assertTrue(resultAboveLong.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0);
assertTrue(instance.minValue(resultAboveLong, Long.MIN_VALUE));
assertFalse(instance.minValue(resultAboveLong, Long.MAX_VALUE));
assertFalse(instance.maxValue(resultAboveLong, Long.MIN_VALUE));
assertFalse(instance.maxValue(resultAboveLong, Long.MAX_VALUE));
assertFalse(instance.isInRange(resultAboveLong, Long.MIN_VALUE, Long.MAX_VALUE));
// BigDecimalValidator already preserves the magnitude, so the two must agree
assertEquals(BigDecimalValidator.getInstance().validate(aboveLongStr, "#").toBigInteger(), resultAboveLong);
}

/**
* Test a value larger than {@link Long#MAX_VALUE} keeps its magnitude instead of being clamped to {@link Long#MAX_VALUE}.
*/
@Test
void testBigIntegerBelowLongMinValue() {
// One past Long.MAX_VALUE, so NumberFormat parses it as a Double rather than a Long.
final BigInteger belowLong = BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE);
final String belowLongStr = belowLong.toString();
final BigIntegerValidator instance = BigIntegerValidator.getInstance();
final BigInteger resultBelowLong = instance.validate(belowLongStr, "#");
assertTrue(resultBelowLong.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0);
assertTrue(resultBelowLong.compareTo(BigInteger.ZERO) < 0);
assertTrue(resultBelowLong.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) < 0);
assertTrue(instance.minValue(resultBelowLong, Long.MIN_VALUE));
assertFalse(instance.minValue(resultBelowLong, Long.MAX_VALUE));
assertTrue(instance.maxValue(resultBelowLong, Long.MIN_VALUE));
assertTrue(instance.maxValue(resultBelowLong, Long.MAX_VALUE));
assertFalse(instance.isInRange(resultBelowLong, Long.MIN_VALUE, Long.MAX_VALUE));
// BigDecimalValidator already preserves the magnitude, so the two must agree
assertEquals(BigDecimalValidator.getInstance().validate(belowLongStr, "#").toBigInteger(), resultBelowLong);
}

/**
* Test BigInteger Range/Min/Max
*/
Expand Down
Loading