Fixes #64833
Change-Id: Ice3f5dfab65f5525bc7a6f57ddeaabda8d64dfa3
GitHub-Last-Rev:
38f1d6c19d8ec29ae5645ce677839a301f798df3
GitHub-Pull-Request: golang/go#64835
Reviewed-on: https://go-review.googlesource.com/c/go/+/552135
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
n += len(v)
}
- b := bytealg.MakeNoZero(n)
+ b := bytealg.MakeNoZero(n)[:n:n]
bp := copy(b, s[0])
for _, v := range s[1:] {
bp += copy(b[bp:], sep)
chunkMax = len(b)
}
}
- nb := bytealg.MakeNoZero(n)
+ nb := bytealg.MakeNoZero(n)[:n:n]
bp := copy(nb, b)
for bp < n {
chunk := bp
// Just return a copy.
return append([]byte(""), s...)
}
- b := bytealg.MakeNoZero(len(s))
+ b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
for i := 0; i < len(s); i++ {
c := s[i]
if 'a' <= c && c <= 'z' {
if !hasUpper {
return append([]byte(""), s...)
}
- b := bytealg.MakeNoZero(len(s))
+ b := bytealg.MakeNoZero(len(s))[:len(s):len(s)]
for i := 0; i < len(s); i++ {
c := s[i]
if 'A' <= c && c <= 'Z' {
return -1
}
-// MakeNoZero makes a slice of length and capacity n without zeroing the bytes.
+// MakeNoZero makes a slice of length n and capacity of at least n Bytes
+// without zeroing the bytes (including the bytes between len and cap).
// It is the caller's responsibility to ensure uninitialized bytes
// do not leak to the end user.
func MakeNoZero(n int) []byte
if uintptr(len) > maxAlloc {
panicmakeslicelen()
}
- return unsafe.Slice((*byte)(mallocgc(uintptr(len), nil, false)), len)
+ cap := roundupsize(uintptr(len), true)
+ return unsafe.Slice((*byte)(mallocgc(uintptr(cap), nil, false)), cap)[:len]
}
// Do not copy a non-zero Builder.
type Builder struct {
addr *Builder // of receiver, to detect copies by value
- buf []byte
+
+ // External users should never get direct access to this buffer, since
+ // the slice at some point will be converted to a string using unsafe, also
+ // data between len(buf) and cap(buf) might be uninitialized.
+ buf []byte
}
// noescape hides a pointer from escape analysis. It is the identity function
}
})
}
+
+func TestBuilderGrowSizeclasses(t *testing.T) {
+ s := Repeat("a", 19)
+ allocs := testing.AllocsPerRun(100, func() {
+ var b Builder
+ b.Grow(18)
+ b.WriteString(s)
+ _ = b.String()
+ })
+ if allocs > 1 {
+ t.Fatalf("unexpected amount of allocations: %v, want: 1", allocs)
+ }
+}