diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go index 45d8d07475..5c03e54d78 100644 --- a/src/bytes/bytes.go +++ b/src/bytes/bytes.go @@ -8,6 +8,7 @@ package bytes import ( "internal/bytealg" + "math/bits" "unicode" "unicode/utf8" _ "unsafe" // for linkname @@ -594,10 +595,11 @@ func Repeat(b []byte, count int) []byte { if count < 0 { panic("bytes: negative Repeat count") } - if len(b) > maxInt/count { + hi, lo := bits.Mul(uint(len(b)), uint(count)) + if hi > 0 || lo > uint(maxInt) { panic("bytes: Repeat output length overflow") } - n := len(b) * count + n := int(lo) // lo = len(b) * count if len(b) == 0 { return []byte{} @@ -624,10 +626,7 @@ func Repeat(b []byte, count int) []byte { nb := bytealg.MakeNoZero(n)[:n:n] bp := copy(nb, b) for bp < n { - chunk := bp - if chunk > chunkMax { - chunk = chunkMax - } + chunk := min(bp, chunkMax) bp += copy(nb[bp:], nb[:chunk]) } return nb diff --git a/src/slices/slices.go b/src/slices/slices.go index b3cd4e2c05..200e653dde 100644 --- a/src/slices/slices.go +++ b/src/slices/slices.go @@ -496,11 +496,12 @@ func Repeat[S ~[]E, E any](x S, count int) S { } const maxInt = ^uint(0) >> 1 - if hi, lo := bits.Mul(uint(len(x)), uint(count)); hi > 0 || lo > maxInt { + hi, lo := bits.Mul(uint(len(x)), uint(count)) + if hi > 0 || lo > maxInt { panic("the result of (len(x) * count) overflows") } - newslice := make(S, len(x)*count) + newslice := make(S, int(lo)) // lo = len(x) * count n := copy(newslice, x) for n < len(newslice) { n += copy(newslice[n:], newslice[:n]) diff --git a/src/strings/strings.go b/src/strings/strings.go index 0bd3c1c233..0729c4ad42 100644 --- a/src/strings/strings.go +++ b/src/strings/strings.go @@ -10,6 +10,7 @@ package strings import ( "internal/bytealg" "internal/stringslite" + "math/bits" "unicode" "unicode/utf8" ) @@ -568,10 +569,11 @@ func Repeat(s string, count int) string { if count < 0 { panic("strings: negative Repeat count") } - if len(s) > maxInt/count { + hi, lo := bits.Mul(uint(len(s)), uint(count)) + if hi > 0 || lo > uint(maxInt) { panic("strings: Repeat output length overflow") } - n := len(s) * count + n := int(lo) // lo = len(s) * count if len(s) == 0 { return "" @@ -617,13 +619,7 @@ func Repeat(s string, count int) string { b.Grow(n) b.WriteString(s) for b.Len() < n { - chunk := n - b.Len() - if chunk > b.Len() { - chunk = b.Len() - } - if chunk > chunkMax { - chunk = chunkMax - } + chunk := min(n-b.Len(), b.Len(), chunkMax) b.WriteString(b.String()[:chunk]) } return b.String()