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 79380dba9 DurationUtils.toMillisInt() throws ArithmeticException on
long overflows before clamping (#1657)
79380dba9 is described below
commit 79380dba919716065f5e16465671782119449a36
Author: Gary Gregory <[email protected]>
AuthorDate: Mon May 18 10:22:15 2026 -0400
DurationUtils.toMillisInt() throws ArithmeticException on long overflows
before clamping (#1657)
DurationUtils.toMillisInt() throws ArithmeticException when
Duration.toMillis() overflows long before clamping (#1657)
---
.../java/org/apache/commons/lang3/time/DurationUtils.java | 10 ++++++++--
src/main/java/org/apache/commons/lang3/time/StopWatch.java | 2 +-
.../java/org/apache/commons/lang3/time/DurationUtilsTest.java | 11 +++++++++++
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/apache/commons/lang3/time/DurationUtils.java
b/src/main/java/org/apache/commons/lang3/time/DurationUtils.java
index 547680609..f13dcbc8a 100644
--- a/src/main/java/org/apache/commons/lang3/time/DurationUtils.java
+++ b/src/main/java/org/apache/commons/lang3/time/DurationUtils.java
@@ -235,7 +235,7 @@ public static Duration toDuration(final long amount, final
TimeUnit timeUnit) {
}
/**
- * Converts a Duration to milliseconds bound to an int (instead of a long).
+ * Converts a Duration to milliseconds bound to an {@code int} (instead of
a {@code long}).
* <p>
* Handy for low-level APIs that take millisecond timeouts in ints rather
than longs.
* </p>
@@ -252,7 +252,13 @@ public static Duration toDuration(final long amount, final
TimeUnit timeUnit) {
public static int toMillisInt(final Duration duration) {
Objects.requireNonNull(duration, "duration");
// intValue() does not do a narrowing conversion here
- return
LONG_TO_INT_RANGE.fit(Long.valueOf(duration.toMillis())).intValue();
+ final long millis;
+ try {
+ millis = duration.toMillis();
+ } catch (final ArithmeticException e) {
+ return duration.isNegative() ? Integer.MIN_VALUE :
Integer.MAX_VALUE;
+ }
+ return LONG_TO_INT_RANGE.fit(Long.valueOf(millis)).intValue();
}
/**
diff --git a/src/main/java/org/apache/commons/lang3/time/StopWatch.java
b/src/main/java/org/apache/commons/lang3/time/StopWatch.java
index a899896a9..ed6bce31d 100644
--- a/src/main/java/org/apache/commons/lang3/time/StopWatch.java
+++ b/src/main/java/org/apache/commons/lang3/time/StopWatch.java
@@ -327,7 +327,7 @@ public StopWatch(final String message) {
* @since 3.10
*/
public String formatSplitTime() {
- return
DurationFormatUtils.formatDurationHMS(getSplitDuration().toMillis());
+ return
DurationFormatUtils.formatDurationHMS(DurationUtils.toMillisInt(getSplitDuration()));
}
/**
diff --git a/src/test/java/org/apache/commons/lang3/time/DurationUtilsTest.java
b/src/test/java/org/apache/commons/lang3/time/DurationUtilsTest.java
index 12b86adb5..016d1f02c 100644
--- a/src/test/java/org/apache/commons/lang3/time/DurationUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/DurationUtilsTest.java
@@ -193,6 +193,17 @@ void testToMillisIntNullDuration() {
assertNullPointerException(() -> DurationUtils.toMillisInt(null));
}
+ @Test
+ void testToMillisIntOverflowToMaxInteger() {
+ // Duration.ofSeconds(Long.MAX_VALUE / 1000 + 1) will overflow when
toMillis() is called
+ assertEquals(Integer.MAX_VALUE,
DurationUtils.toMillisInt(Duration.ofSeconds(Long.MAX_VALUE / 1000 + 1)));
+ }
+
+ @Test
+ void testToMillisIntUnderflowToMinInteger() {
+ assertEquals(Integer.MIN_VALUE,
DurationUtils.toMillisInt(Duration.ofSeconds(Long.MIN_VALUE / 1000 - 1)));
+ }
+
@Test
void testZeroIfNull() {
assertEquals(Duration.ZERO, DurationUtils.zeroIfNull(null));