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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Update
- fix: add stricter validation for Ed25519 Signed Payload.
- fix: replace assert statements with explicit null checks in `Federation` class to ensure validation is not bypassed when assertions are disabled.
- fix: add overflow check in `TimeBounds.expiresAfter()` to prevent integer overflow when timeout is too large.

## 2.2.1

Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/stellar/sdk/TimeBounds.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,16 @@ public TimeBounds(long minTime, long maxTime) {
*
* @param timeout Timeout in seconds.
* @return TimeBounds
* @throws IllegalArgumentException if timeout is negative or would cause overflow
*/
public static TimeBounds expiresAfter(long timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout cannot be negative");
}
long now = System.currentTimeMillis() / 1000L;
if (timeout > Long.MAX_VALUE - now) {
throw new IllegalArgumentException("timeout is too large, would cause overflow");
}
long endTime = now + timeout;
return new TimeBounds(0, endTime);
}
Expand Down
22 changes: 22 additions & 0 deletions src/test/kotlin/org/stellar/sdk/TimeBoundsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@ class TimeBoundsTest :
actualMaxTime shouldBeInRange (now + timeout - 1)..(now + timeout + 1)
}

test("expiresAfter should throw IllegalArgumentException for negative timeout") {
val exception = shouldThrow<IllegalArgumentException> { TimeBounds.expiresAfter(-1) }
exception.message shouldBe "timeout cannot be negative"
}

test("expiresAfter should throw IllegalArgumentException for overflow") {
val exception =
shouldThrow<IllegalArgumentException> { TimeBounds.expiresAfter(Long.MAX_VALUE) }
exception.message shouldBe "timeout is too large, would cause overflow"
}

test("expiresAfter should handle large valid timeout") {
// 100 years in seconds
val hundredYearsInSeconds = 100L * 365 * 24 * 60 * 60
val timeBounds = TimeBounds.expiresAfter(hundredYearsInSeconds)
val now = System.currentTimeMillis() / 1000L

timeBounds.minTime.toLong() shouldBe 0
timeBounds.maxTime.toLong() shouldBeInRange
(now + hundredYearsInSeconds - 1)..(now + hundredYearsInSeconds + 1)
}

test("should handle large time values") {
val largeTime = Long.MAX_VALUE - 1
val timeBounds = TimeBounds(0, largeTime)
Expand Down
Loading