Fix issue where fib function overflows

This commit is contained in:
ionutboangiu
2022-08-01 18:05:14 +03:00
committed by Dan Christian Bogos
parent 6a17ed8c99
commit 09c6261903
3 changed files with 44 additions and 3 deletions

View File

@@ -2669,6 +2669,15 @@ const (
ToNearestTowardZero = "*toNearestTowardZero"
)
// Go type limits
const (
AbsoluteMaxUint = ^uint(0)
AbsoluteMinUint = 0
AbsoluteMaxInt = int(AbsoluteMaxUint >> 1)
AbsoluteMinInt = -AbsoluteMaxInt - 1
AbsoluteMaxDuration = time.Duration(AbsoluteMaxInt)
)
func buildCacheInstRevPrefixes() {
CachePrefixToInstance = make(map[string]string)
for k, v := range CacheInstanceToPrefix {

View File

@@ -424,11 +424,13 @@ func copyFile(rc io.ReadCloser, path string, fm os.FileMode) (err error) {
return
}
// Fib returns successive Fibonacci numbers
// Fib returns successive Fibonacci numbers.
func Fib() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
if b > 0 {
a, b = b, a+b // only increment Fibonacci numbers while b doesn't overflow
}
return a
}
}
@@ -438,7 +440,12 @@ func Fib() func() int {
func FibDuration(durationUnit, maxDuration time.Duration) func() time.Duration {
fib := Fib()
return func() time.Duration {
fibNrAsDuration := time.Duration(fib()) * durationUnit
fibNrAsDuration := time.Duration(fib())
if fibNrAsDuration > (AbsoluteMaxDuration / durationUnit) { // check if the current fibonacci nr. in the sequence would exceed the absolute maximum duration if multiplied by the duration unit value
fibNrAsDuration = AbsoluteMaxDuration
} else {
fibNrAsDuration *= durationUnit
}
if maxDuration > 0 && maxDuration < fibNrAsDuration {
return maxDuration
}

View File

@@ -1661,3 +1661,28 @@ func TestAPITPDataGetPaginateOpts(t *testing.T) {
t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err)
}
}
func TestCoreUtilsFibSeqNrOverflow(t *testing.T) {
fib := Fib()
for i := 0; i < 92; i++ { // the 93rd fibonacci number in the sequence would normally overflow
fib()
}
exp := fib()
for i := 0; i < 100; i++ {
if rcv := fib(); rcv != exp {
t.Errorf("expected: <%+v>, \nreceived: <%+v>", exp, rcv)
}
}
}
func TestCoreUtilsFibDurationSeqNrOverflow(t *testing.T) {
fib := FibDuration(time.Second, 0)
for i := 0; i < 49; i++ { // the 50th fibonacci number in the sequence would normally overflow when multiplied with time.Second
fib()
}
for i := 0; i < 100; i++ {
if rcv := fib(); rcv != AbsoluteMaxDuration {
t.Errorf("expected: <%+v>, \nreceived: <%+v>", AbsoluteMaxDuration, rcv)
}
}
}