diff --git a/src/Symfony/Component/RateLimiter/Policy/TokenBucketLimiter.php b/src/Symfony/Component/RateLimiter/Policy/TokenBucketLimiter.php index dec472074f5e8..074c3617d9f37 100644 --- a/src/Symfony/Component/RateLimiter/Policy/TokenBucketLimiter.php +++ b/src/Symfony/Component/RateLimiter/Policy/TokenBucketLimiter.php @@ -67,6 +67,10 @@ public function reserve(int $tokens = 1, ?float $maxTime = null): Reservation $now = microtime(true); $availableTokens = $bucket->getAvailableTokens($now); + if ($availableTokens > $this->maxBurst) { + $availableTokens = $this->maxBurst; + } + if ($availableTokens >= $tokens) { // tokens are now available, update bucket $bucket->setTokens($availableTokens - $tokens); diff --git a/src/Symfony/Component/RateLimiter/Tests/Policy/TokenBucketLimiterTest.php b/src/Symfony/Component/RateLimiter/Tests/Policy/TokenBucketLimiterTest.php index ace65f61a5c6b..dcf2340d18d45 100644 --- a/src/Symfony/Component/RateLimiter/Tests/Policy/TokenBucketLimiterTest.php +++ b/src/Symfony/Component/RateLimiter/Tests/Policy/TokenBucketLimiterTest.php @@ -56,6 +56,18 @@ public function testReserveMoreTokensThanBucketSize() $limiter->reserve(15); } + public function testReduceBucketSizeWhenAlreadyExistInStorageWithBiggerBucketSize() + { + $limiter = $this->createLimiter(100); + + $limiter->consume(); + + $limiter2 = $this->createLimiter(1); + $limiter2->consume(); + + $this->assertFalse($limiter2->consume()->isAccepted()); + } + public function testReserveMaxWaitingTime() { $this->expectException(MaxWaitDurationExceededException::class);