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);

Reply via email to