From a7a1edc92ea2c40ddaacf804c268e31f383816c5 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Sun, 8 Dec 2024 09:22:38 -0500 Subject: [PATCH] fix NaN from extremely high rate limits --- .../backend/src/server/api/SkRateLimiterService.ts | 2 +- .../unit/server/api/SkRateLimiterServiceTests.ts | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/SkRateLimiterService.ts b/packages/backend/src/server/api/SkRateLimiterService.ts index fb100be286..7726edfb31 100644 --- a/packages/backend/src/server/api/SkRateLimiterService.ts +++ b/packages/backend/src/server/api/SkRateLimiterService.ts @@ -155,7 +155,7 @@ export class SkRateLimiterService { type: 'bucket', key: limit.key, size: limit.max, - dripRate: Math.round(limit.duration / limit.max), + dripRate: Math.max(Math.round(limit.duration / limit.max), 1), }, actor, factor), ); } diff --git a/packages/backend/test/unit/server/api/SkRateLimiterServiceTests.ts b/packages/backend/test/unit/server/api/SkRateLimiterServiceTests.ts index 07bcfb6309..7e0c01f849 100644 --- a/packages/backend/test/unit/server/api/SkRateLimiterServiceTests.ts +++ b/packages/backend/test/unit/server/api/SkRateLimiterServiceTests.ts @@ -564,6 +564,20 @@ describe(SkRateLimiterService, () => { expect(counter?.c).toBe(1); expect(counter?.t).toBe(0); }); + + it('should not allow dripRate to be lower than 0', async () => { + // real-world case; taken from StreamingApiServerService + limit.max = 4096; + limit.duration = 2000; + counter = { c: 4096, t: 0 }; + + const i1 = await serviceUnderTest().limit(limit, actor); + mockTimeService.now = 1; + const i2 = await serviceUnderTest().limit(limit, actor); + + expect(i1.blocked).toBeTruthy(); + expect(i2.blocked).toBeFalsy(); + }); }); describe('with legacy limit and min interval', () => {