Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 00e4188

Browse files
committed
Fixed integer overflow bug in rate limiter.
1 parent 1952986 commit 00e4188

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

pkg/util/workqueue/default_rate_limiters.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,16 @@ func (r *ItemExponentialFailureRateLimiter) When(item interface{}) time.Duration
9090
r.failuresLock.Lock()
9191
defer r.failuresLock.Unlock()
9292

93+
exp := r.failures[item]
9394
r.failures[item] = r.failures[item] + 1
9495

95-
calculated := r.baseDelay * time.Duration(math.Pow10(r.failures[item]-1))
96+
// The backoff is capped such that 'calculated' value never overflows.
97+
backoff := float64(r.baseDelay.Nanoseconds()) * math.Pow10(exp)
98+
if backoff > math.MaxInt64 {
99+
return r.maxDelay
100+
}
101+
102+
calculated := time.Duration(backoff)
96103
if calculated > r.maxDelay {
97104
return r.maxDelay
98105
}

pkg/util/workqueue/default_rate_limiters_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,39 @@ func TestItemExponentialFailureRateLimiter(t *testing.T) {
6363

6464
}
6565

66+
func TestItemExponentialFailureRateLimiterOverFlow(t *testing.T) {
67+
limiter := NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1000*time.Second)
68+
for i := 0; i < 5; i++ {
69+
limiter.When("one")
70+
}
71+
if e, a := 100000*time.Millisecond, limiter.When("one"); e != a {
72+
t.Errorf("expected %v, got %v", e, a)
73+
}
74+
75+
for i := 0; i < 1000; i++ {
76+
limiter.When("overflow1")
77+
}
78+
if e, a := 1000*time.Second, limiter.When("overflow1"); e != a {
79+
t.Errorf("expected %v, got %v", e, a)
80+
}
81+
82+
limiter = NewItemExponentialFailureRateLimiter(1*time.Minute, 1000*time.Hour)
83+
for i := 0; i < 2; i++ {
84+
limiter.When("two")
85+
}
86+
if e, a := 100*time.Minute, limiter.When("two"); e != a {
87+
t.Errorf("expected %v, got %v", e, a)
88+
}
89+
90+
for i := 0; i < 1000; i++ {
91+
limiter.When("overflow2")
92+
}
93+
if e, a := 1000*time.Hour, limiter.When("overflow2"); e != a {
94+
t.Errorf("expected %v, got %v", e, a)
95+
}
96+
97+
}
98+
6699
func TestItemFastSlowRateLimiter(t *testing.T) {
67100
limiter := NewItemFastSlowRateLimiter(5*time.Millisecond, 10*time.Second, 3)
68101

0 commit comments

Comments
 (0)