From d33fdd86a3de75500fe554d6547cf5ad43e006bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 25 Apr 2024 08:02:11 +0100 Subject: [PATCH] time: check for overflow in `Interval::poll_tick` (#6487) --- tokio/src/time/interval.rs | 4 +++- tokio/tests/time_interval.rs | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tokio/src/time/interval.rs b/tokio/src/time/interval.rs index dee28793a32..2b5246acfa4 100644 --- a/tokio/src/time/interval.rs +++ b/tokio/src/time/interval.rs @@ -480,7 +480,9 @@ impl Interval { self.missed_tick_behavior .next_timeout(timeout, now, self.period) } else { - timeout + self.period + timeout + .checked_add(self.period) + .unwrap_or_else(Instant::far_future) }; // When we arrive here, the internal delay returned `Poll::Ready`. diff --git a/tokio/tests/time_interval.rs b/tokio/tests/time_interval.rs index 4f3e95b0d2a..7472a37123c 100644 --- a/tokio/tests/time_interval.rs +++ b/tokio/tests/time_interval.rs @@ -6,7 +6,7 @@ use std::task::{Context, Poll}; use futures::{Stream, StreamExt}; use tokio::time::{self, Duration, Instant, Interval, MissedTickBehavior}; -use tokio_test::{assert_pending, assert_ready_eq, task}; +use tokio_test::{assert_pending, assert_ready, assert_ready_eq, task}; // Takes the `Interval` task, `start` variable, and optional time deltas // For each time delta, it polls the `Interval` and asserts that the result is @@ -469,3 +469,9 @@ async fn stream_with_interval_poll_tick_no_waking() { // task when returning `Poll::Ready`. assert_eq!(items, vec![]); } + +#[tokio::test(start_paused = true)] +async fn interval_doesnt_panic_max_duration_when_polling() { + let mut timer = task::spawn(time::interval(Duration::MAX)); + assert_ready!(timer.enter(|cx, mut timer| timer.poll_tick(cx))); +}