]> Cypherpunks repositories - gostls13.git/commitdiff
bytes: set cap of slices returned by Split and Fields and friends
authorIan Lance Taylor <iant@golang.org>
Mon, 30 Oct 2017 23:05:18 +0000 (16:05 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 3 Nov 2017 19:06:15 +0000 (19:06 +0000)
This avoids the problem in which appending to a slice returned by
Split can affect subsequent slices.

Fixes #21149.

Change-Id: Ie3df2b9ceeb9605d4625f47d49073c5f348cf0a1
Reviewed-on: https://go-review.googlesource.com/74510
Reviewed-by: Jelte Fennema <github-tech@jeltef.nl>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/bytes/bytes.go
src/bytes/bytes_test.go

index 40d76be0945126aff781cf8183b6d3f15f681ea0..68ed8e1b437fe898816c2e153450bbd1cf4c997f 100644 (file)
@@ -39,7 +39,7 @@ func explode(s []byte, n int) [][]byte {
                        break
                }
                _, size = utf8.DecodeRune(s)
-               a[na] = s[0:size]
+               a[na] = s[0:size:size]
                s = s[size:]
                na++
        }
@@ -219,7 +219,7 @@ func genSplit(s, sep []byte, sepSave, n int) [][]byte {
                if m < 0 {
                        break
                }
-               a[i] = s[:m+sepSave]
+               a[i] = s[: m+sepSave : m+sepSave]
                s = s[m+len(sep):]
                i++
        }
@@ -302,7 +302,7 @@ func Fields(s []byte) [][]byte {
                        i++
                        continue
                }
-               a[na] = s[fieldStart:i]
+               a[na] = s[fieldStart:i:i]
                na++
                i++
                // Skip spaces in between fields.
@@ -312,7 +312,7 @@ func Fields(s []byte) [][]byte {
                fieldStart = i
        }
        if fieldStart < len(s) { // Last field might end at EOF.
-               a[na] = s[fieldStart:]
+               a[na] = s[fieldStart:len(s):len(s)]
        }
        return a
 }
@@ -363,7 +363,7 @@ func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
        // Create subslices from recorded field indices.
        a := make([][]byte, len(spans))
        for i, span := range spans {
-               a[i] = s[span.start:span.end]
+               a[i] = s[span.start:span.end:span.end]
        }
 
        return a
index db28497e39e4d16a713c3daa7982694759c20558..78eca2064a83d7dbd942cbabefd87a3ebb76b6cf 100644 (file)
@@ -736,6 +736,13 @@ var splittests = []SplitTest{
 func TestSplit(t *testing.T) {
        for _, tt := range splittests {
                a := SplitN([]byte(tt.s), []byte(tt.sep), tt.n)
+
+               // Appending to the results should not change future results.
+               var x []byte
+               for _, v := range a {
+                       x = append(v, 'z')
+               }
+
                result := sliceOfString(a)
                if !eq(result, tt.a) {
                        t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
@@ -744,6 +751,11 @@ func TestSplit(t *testing.T) {
                if tt.n == 0 {
                        continue
                }
+
+               if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+                       t.Errorf("last appended result was %s; want %s", x, want)
+               }
+
                s := Join(a, []byte(tt.sep))
                if string(s) != tt.s {
                        t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
@@ -782,11 +794,23 @@ var splitaftertests = []SplitTest{
 func TestSplitAfter(t *testing.T) {
        for _, tt := range splitaftertests {
                a := SplitAfterN([]byte(tt.s), []byte(tt.sep), tt.n)
+
+               // Appending to the results should not change future results.
+               var x []byte
+               for _, v := range a {
+                       x = append(v, 'z')
+               }
+
                result := sliceOfString(a)
                if !eq(result, tt.a) {
                        t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
                        continue
                }
+
+               if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+                       t.Errorf("last appended result was %s; want %s", x, want)
+               }
+
                s := Join(a, nil)
                if string(s) != tt.s {
                        t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
@@ -821,12 +845,29 @@ var fieldstests = []FieldsTest{
 
 func TestFields(t *testing.T) {
        for _, tt := range fieldstests {
-               a := Fields([]byte(tt.s))
+               b := []byte(tt.s)
+               a := Fields(b)
+
+               // Appending to the results should not change future results.
+               var x []byte
+               for _, v := range a {
+                       x = append(v, 'z')
+               }
+
                result := sliceOfString(a)
                if !eq(result, tt.a) {
                        t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
                        continue
                }
+
+               if string(b) != tt.s {
+                       t.Errorf("slice changed to %s; want %s", string(b), tt.s)
+               }
+               if len(tt.a) > 0 {
+                       if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+                               t.Errorf("last appended result was %s; want %s", x, want)
+                       }
+               }
        }
 }
 
@@ -847,11 +888,28 @@ func TestFieldsFunc(t *testing.T) {
                {"aXXbXXXcX", []string{"a", "b", "c"}},
        }
        for _, tt := range fieldsFuncTests {
-               a := FieldsFunc([]byte(tt.s), pred)
+               b := []byte(tt.s)
+               a := FieldsFunc(b, pred)
+
+               // Appending to the results should not change future results.
+               var x []byte
+               for _, v := range a {
+                       x = append(v, 'z')
+               }
+
                result := sliceOfString(a)
                if !eq(result, tt.a) {
                        t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
                }
+
+               if string(b) != tt.s {
+                       t.Errorf("slice changed to %s; want %s", b, tt.s)
+               }
+               if len(tt.a) > 0 {
+                       if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
+                               t.Errorf("last appended result was %s; want %s", x, want)
+                       }
+               }
        }
 }