Skip to content

Commit 6f3f02f

Browse files
committed
runtime: zero tmpbuf between len and cap
Zero the entire buffer so we don't need to lower its capacity upon return. This lets callers do some appending without allocation. Zeroing is cheap, the byte buffer requires only 4 extra instructions. Fixes #14235 Change-Id: I970d7badcef047dafac75ac17130030181f18fe2 Reviewed-on: https://go-review.googlesource.com/22424 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 8b92397 commit 6f3f02f

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

src/runtime/string.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ func slicebytetostringtmp(b []byte) string {
139139
func stringtoslicebyte(buf *tmpBuf, s string) []byte {
140140
var b []byte
141141
if buf != nil && len(s) <= len(buf) {
142-
b = buf[:len(s):len(s)]
142+
*buf = tmpBuf{}
143+
b = buf[:len(s)]
143144
} else {
144145
b = rawbyteslice(len(s))
145146
}
@@ -171,7 +172,8 @@ func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
171172
}
172173
var a []rune
173174
if buf != nil && n <= len(buf) {
174-
a = buf[:n:n]
175+
*buf = [tmpStringBufSize]rune{}
176+
a = buf[:n]
175177
} else {
176178
a = rawruneslice(n)
177179
}

src/runtime/string_test.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,17 +238,35 @@ func TestRangeStringCast(t *testing.T) {
238238
}
239239
}
240240

241+
func isZeroed(b []byte) bool {
242+
for _, x := range b {
243+
if x != 0 {
244+
return false
245+
}
246+
}
247+
return true
248+
}
249+
250+
func isZeroedR(r []rune) bool {
251+
for _, x := range r {
252+
if x != 0 {
253+
return false
254+
}
255+
}
256+
return true
257+
}
258+
241259
func TestString2Slice(t *testing.T) {
242260
// Make sure we don't return slices that expose
243261
// an unzeroed section of stack-allocated temp buf
244262
// between len and cap. See issue 14232.
245263
s := "foož"
246264
b := ([]byte)(s)
247-
if cap(b) != 5 {
248-
t.Errorf("want cap of 5, got %d", cap(b))
265+
if !isZeroed(b[len(b):cap(b)]) {
266+
t.Errorf("extra bytes not zeroed")
249267
}
250268
r := ([]rune)(s)
251-
if cap(r) != 4 {
252-
t.Errorf("want cap of 4, got %d", cap(r))
269+
if !isZeroedR(r[len(r):cap(r)]) {
270+
t.Errorf("extra runes not zeroed")
253271
}
254272
}

0 commit comments

Comments
 (0)