This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 4fe0dff2bc11e07736d9a5c947b61310d3d0f7e4 Author: opencode <[email protected]> AuthorDate: Sun Oct 11 22:24:19 2026 +0200 Stop truncating the time bucket index to an int in TimeBucketCounterBase getCurrentBucketPrefix() narrowed the long value returned by getBucketIndex() to an int. periodicEvict() builds the current and next bucket prefixes from that value to decide which keys survive. Bucket keys are generated from the full long index, so once the index exceeds Integer.MAX_VALUE the truncated prefix no longer matches any key, every entry is evicted on each maintenance run and the RateLimitFilter silently stops enforcing limits. With one-second buckets the shift based TimeBucketCounter reaches that point when System.currentTimeMillis() hits 2^41 ms, i.e. in 2039, and the division based ExactTimeBucketCounter even earlier, in 2038. Buckets of a minute or more overflow only millennia out, which is why the bug survived unnoticed. Return the full long index from getCurrentBucketPrefix(). This widens the return type of a public method, but the method is part of the recently added rate limiting support classes, has no callers outside TimeBucketCounterBase and its own unit test, and is not referenced in the documentation. The only production caller, periodicEvict(), already stored the result in a long local, and the remaining int casts in TimeBucketCounter operate on durations, which are range-checked separately. Widen the two test locals to match; a regression test for the pre-2038 truncation would require injecting a fake clock, and re-narrowing is now prevented by the compiler. --- java/org/apache/catalina/util/TimeBucketCounterBase.java | 4 ++-- test/org/apache/catalina/util/TestTimeBucketCounter.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/org/apache/catalina/util/TimeBucketCounterBase.java b/java/org/apache/catalina/util/TimeBucketCounterBase.java index 01a51b1ec0..7aec8de153 100644 --- a/java/org/apache/catalina/util/TimeBucketCounterBase.java +++ b/java/org/apache/catalina/util/TimeBucketCounterBase.java @@ -151,8 +151,8 @@ public abstract class TimeBucketCounterBase { * * @return bucket index */ - public int getCurrentBucketPrefix() { - return (int) getBucketIndex(System.currentTimeMillis()); + public long getCurrentBucketPrefix() { + return getBucketIndex(System.currentTimeMillis()); } diff --git a/test/org/apache/catalina/util/TestTimeBucketCounter.java b/test/org/apache/catalina/util/TestTimeBucketCounter.java index 4a2d66c996..ed385a900f 100644 --- a/test/org/apache/catalina/util/TestTimeBucketCounter.java +++ b/test/org/apache/catalina/util/TestTimeBucketCounter.java @@ -80,7 +80,7 @@ public class TestTimeBucketCounter { @Test public void testGetMillisUntilNextBucket() throws InterruptedException { long millis; - int tb1, tb2; + long tb1, tb2; TimeBucketCounter tbc = new TimeBucketCounter(2, new java.util.concurrent.ScheduledThreadPoolExecutor(1)); tb1 = tbc.getCurrentBucketPrefix(); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
