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 a0ffef035 fix silent int overflow in Fraction.getFraction(double)
(#1717)
a0ffef035 is described below
commit a0ffef035d6a0e7803da8405ebceacb011efbaa0
Author: alhuda <[email protected]>
AuthorDate: Fri Jun 19 17:34:28 2026 +0530
fix silent int overflow in Fraction.getFraction(double) (#1717)
---
src/main/java/org/apache/commons/lang3/math/Fraction.java | 5 ++++-
src/test/java/org/apache/commons/lang3/math/FractionTest.java | 4 ++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/apache/commons/lang3/math/Fraction.java
b/src/main/java/org/apache/commons/lang3/math/Fraction.java
index a2a45ac83..5864a5d74 100644
--- a/src/main/java/org/apache/commons/lang3/math/Fraction.java
+++ b/src/main/java/org/apache/commons/lang3/math/Fraction.java
@@ -174,7 +174,10 @@ public static Fraction getFraction(double value) {
if (i == 25) {
throw new ArithmeticException("Unable to convert double to
fraction");
}
- return getReducedFraction((numer0 + wholeNumber * denom0) * sign,
denom0);
+ // wholeNumber can be up to Integer.MAX_VALUE while denom0 > 1 for any
non-integer value,
+ // so the int product overflows for values near the limit; check it
instead of wrapping silently.
+ final int numerator = Math.addExact(numer0, mulAndCheck(wholeNumber,
denom0));
+ return getReducedFraction(numerator * sign, denom0);
}
/**
diff --git a/src/test/java/org/apache/commons/lang3/math/FractionTest.java
b/src/test/java/org/apache/commons/lang3/math/FractionTest.java
index 862e383b1..f068402c7 100644
--- a/src/test/java/org/apache/commons/lang3/math/FractionTest.java
+++ b/src/test/java/org/apache/commons/lang3/math/FractionTest.java
@@ -334,6 +334,10 @@ void testFactory_double() {
assertThrows(ArithmeticException.class, () ->
Fraction.getFraction(Double.POSITIVE_INFINITY));
assertThrows(ArithmeticException.class, () ->
Fraction.getFraction(Double.NEGATIVE_INFINITY));
assertThrows(ArithmeticException.class, () ->
Fraction.getFraction((double) Integer.MAX_VALUE + 1));
+ // near Integer.MAX_VALUE with a fractional part: numerator overflows
an int, so it must throw
+ // rather than silently return a wrong fraction (previously -3/2 and
-2147483647/2 respectively)
+ assertThrows(ArithmeticException.class, () ->
Fraction.getFraction(2147483646.5d));
+ assertThrows(ArithmeticException.class, () ->
Fraction.getFraction(1073741824.5d));
// zero
Fraction f = Fraction.getFraction(0.0d);