]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: don't expose stack buffer in stringto{byte,rune}slice
authorKeith Randall <khr@golang.org>
Thu, 4 Feb 2016 21:38:38 +0000 (13:38 -0800)
committerKeith Randall <khr@golang.org>
Thu, 4 Feb 2016 23:57:10 +0000 (23:57 +0000)
When using a stack-allocated buffer for the result, don't
expose the uninitialized portion of it by restricting its
capacity to its length.

The other option is to zero the portion between len and cap.
That seems like more work, but might be worth it if the caller
then appends some stuff to the result.  But this close to 1.6,
I'm inclined to do the simplest fix possible.

Fixes #14232

Change-Id: I21c50d3cda02fd2df4d60ba5e2cfe2efe272f333
Reviewed-on: https://go-review.googlesource.com/19231
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/string.go
src/runtime/string_test.go

index f8ccd41b1d3d2cbc1121ab11eeed8a748abd7014..dd04bda04ba3cb37833d1201c3defc70ec035310 100644 (file)
@@ -139,7 +139,7 @@ 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)]
+               b = buf[:len(s):len(s)]
        } else {
                b = rawbyteslice(len(s))
        }
@@ -171,7 +171,7 @@ func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
        }
        var a []rune
        if buf != nil && n <= len(buf) {
-               a = buf[:n]
+               a = buf[:n:n]
        } else {
                a = rawruneslice(n)
        }
index 318a5532e521c07fffe17c292ec00cdef5b9b9ac..150a25520adbc3e427ca8cb7dc68e59e1a59feb4 100644 (file)
@@ -222,3 +222,18 @@ func TestRangeStringCast(t *testing.T) {
                t.Fatalf("want 0 allocs, got %v", n)
        }
 }
+
+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))
+       }
+       r := ([]rune)(s)
+       if cap(r) != 4 {
+               t.Errorf("want cap of 4, got %d", cap(r))
+       }
+}