diff options
Diffstat (limited to 'src/bytes')
-rw-r--r-- | src/bytes/buffer_test.go | 2 | ||||
-rw-r--r-- | src/bytes/bytes.go | 15 | ||||
-rw-r--r-- | src/bytes/bytes_test.go | 47 | ||||
-rw-r--r-- | src/bytes/example_test.go | 9 | ||||
-rw-r--r-- | src/bytes/reader.go | 4 |
5 files changed, 52 insertions, 25 deletions
diff --git a/src/bytes/buffer_test.go b/src/bytes/buffer_test.go index 322e7367c7..3c964fc6b9 100644 --- a/src/bytes/buffer_test.go +++ b/src/bytes/buffer_test.go @@ -7,6 +7,7 @@ package bytes_test import ( . "bytes" "fmt" + "internal/testenv" "io" "math/rand" "strconv" @@ -100,6 +101,7 @@ var buf Buffer // should not result in any allocations. // This can be used to reset the underlying []byte of an existing Buffer. func TestNewBufferShallow(t *testing.T) { + testenv.SkipIfOptimizationOff(t) n := testing.AllocsPerRun(1000, func() { buf = *NewBuffer(testBytes) }) diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go index 1871814c6e..2a07d2084e 100644 --- a/src/bytes/bytes.go +++ b/src/bytes/bytes.go @@ -10,6 +10,7 @@ import ( "internal/bytealg" "unicode" "unicode/utf8" + _ "unsafe" // for linkname ) // Equal reports whether a and b @@ -568,6 +569,18 @@ func Map(mapping func(r rune) rune, s []byte) []byte { return b } +// Despite being an exported symbol, +// Repeat is linknamed by widely used packages. +// Notable members of the hall of shame include: +// - gitee.com/quant1x/num +// +// Do not remove or change the type signature. +// See go.dev/issue/67401. +// +// Note that this comment is not part of the doc comment. +// +//go:linkname Repeat + // Repeat returns a new byte slice consisting of count copies of b. // // It panics if count is negative or if the result of (len(b) * count) @@ -583,7 +596,7 @@ func Repeat(b []byte, count int) []byte { if count < 0 { panic("bytes: negative Repeat count") } - if len(b) >= maxInt/count { + if len(b) > maxInt/count { panic("bytes: Repeat output length overflow") } n := len(b) * count diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go index 5e8cf85fd9..200a357bc0 100644 --- a/src/bytes/bytes_test.go +++ b/src/bytes/bytes_test.go @@ -1242,33 +1242,48 @@ func repeat(b []byte, count int) (err error) { // See Issue golang.org/issue/16237 func TestRepeatCatchesOverflow(t *testing.T) { - tests := [...]struct { + type testCase struct { s string count int errStr string - }{ + } + + runTestCases := func(prefix string, tests []testCase) { + for i, tt := range tests { + err := repeat([]byte(tt.s), tt.count) + if tt.errStr == "" { + if err != nil { + t.Errorf("#%d panicked %v", i, err) + } + continue + } + + if err == nil || !strings.Contains(err.Error(), tt.errStr) { + t.Errorf("%s#%d got %q want %q", prefix, i, err, tt.errStr) + } + } + } + + const maxInt = int(^uint(0) >> 1) + + runTestCases("", []testCase{ 0: {"--", -2147483647, "negative"}, - 1: {"", int(^uint(0) >> 1), ""}, + 1: {"", maxInt, ""}, 2: {"-", 10, ""}, 3: {"gopher", 0, ""}, 4: {"-", -1, "negative"}, 5: {"--", -102, "negative"}, 6: {string(make([]byte, 255)), int((^uint(0))/255 + 1), "overflow"}, - } - - for i, tt := range tests { - err := repeat([]byte(tt.s), tt.count) - if tt.errStr == "" { - if err != nil { - t.Errorf("#%d panicked %v", i, err) - } - continue - } + }) - if err == nil || !strings.Contains(err.Error(), tt.errStr) { - t.Errorf("#%d expected %q got %q", i, tt.errStr, err) - } + const is64Bit = 1<<(^uintptr(0)>>63)/2 != 0 + if !is64Bit { + return } + + runTestCases("64-bit", []testCase{ + 0: {"-", maxInt, "out of range"}, + }) } func runesEqual(a, b []rune) bool { diff --git a/src/bytes/example_test.go b/src/bytes/example_test.go index 54df5f74e5..1cc0089e41 100644 --- a/src/bytes/example_test.go +++ b/src/bytes/example_test.go @@ -10,7 +10,7 @@ import ( "fmt" "io" "os" - "sort" + "slices" "strconv" "unicode" ) @@ -165,11 +165,8 @@ func ExampleCompare_search() { // Binary search to find a matching byte slice. var needle []byte var haystack [][]byte // Assume sorted - i := sort.Search(len(haystack), func(i int) bool { - // Return haystack[i] >= needle. - return bytes.Compare(haystack[i], needle) >= 0 - }) - if i < len(haystack) && bytes.Equal(haystack[i], needle) { + _, found := slices.BinarySearchFunc(haystack, needle, bytes.Compare) + if found { // Found it! } } diff --git a/src/bytes/reader.go b/src/bytes/reader.go index 9ef49014ed..30c46fa6b3 100644 --- a/src/bytes/reader.go +++ b/src/bytes/reader.go @@ -152,8 +152,8 @@ func (r *Reader) WriteTo(w io.Writer) (n int64, err error) { return } -// Reset resets the [Reader.Reader] to be reading from b. +// Reset resets the [Reader] to be reading from b. func (r *Reader) Reset(b []byte) { *r = Reader{b, 0, -1} } -// NewReader returns a new [Reader.Reader] reading from b. +// NewReader returns a new [Reader] reading from b. func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} } |