]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: zero tmpbuf between len and cap
authorKeith Randall <khr@golang.org>
Mon, 25 Apr 2016 00:04:32 +0000 (17:04 -0700)
committerKeith Randall <khr@golang.org>
Mon, 25 Apr 2016 21:16:52 +0000 (21:16 +0000)
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 <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/string.go
src/runtime/string_test.go

index 112ce5d588dec141caa59d4a2ab799a9d55175fc..ef28ba98284959bd735df2df33982af0c7feb19b 100644 (file)
@@ -139,7 +139,8 @@ func slicebytetostringtmp(b []byte) string {
 func stringtoslicebyte(buf *tmpBuf, s string) []byte {
        var b []byte
        if buf != nil && len(s) <= len(buf) {
-               b = buf[:len(s):len(s)]
+               *buf = tmpBuf{}
+               b = buf[:len(s)]
        } else {
                b = rawbyteslice(len(s))
        }
@@ -171,7 +172,8 @@ func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
        }
        var a []rune
        if buf != nil && n <= len(buf) {
-               a = buf[:n:n]
+               *buf = [tmpStringBufSize]rune{}
+               a = buf[:n]
        } else {
                a = rawruneslice(n)
        }
index ee9709e87d497fd6bb62e0051f59e1a87cd06142..0f1d82a481e3f5f7cbb6e70888bb6fca353b8745 100644 (file)
@@ -238,17 +238,35 @@ func TestRangeStringCast(t *testing.T) {
        }
 }
 
+func isZeroed(b []byte) bool {
+       for _, x := range b {
+               if x != 0 {
+                       return false
+               }
+       }
+       return true
+}
+
+func isZeroedR(r []rune) bool {
+       for _, x := range r {
+               if x != 0 {
+                       return false
+               }
+       }
+       return true
+}
+
 func TestString2Slice(t *testing.T) {
        // Make sure we don't return slices that expose
        // an unzeroed section of stack-allocated temp buf
        // between len and cap. See issue 14232.
        s := "foož"
        b := ([]byte)(s)
-       if cap(b) != 5 {
-               t.Errorf("want cap of 5, got %d", cap(b))
+       if !isZeroed(b[len(b):cap(b)]) {
+               t.Errorf("extra bytes not zeroed")
        }
        r := ([]rune)(s)
-       if cap(r) != 4 {
-               t.Errorf("want cap of 4, got %d", cap(r))
+       if !isZeroedR(r[len(r):cap(r)]) {
+               t.Errorf("extra runes not zeroed")
        }
 }