]> Cypherpunks repositories - gostls13.git/commitdiff
io: copy slice argument in MultiReader and MultiWriter
authorRuss Cox <rsc@golang.org>
Tue, 13 May 2014 03:38:35 +0000 (23:38 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 13 May 2014 03:38:35 +0000 (23:38 -0400)
Replaces CL 91240045.
Fixes #7809.

LGTM=bradfitz
R=golang-codereviews, minux.ma
CC=adg, bradfitz, golang-codereviews, iant, r
https://golang.org/cl/94380043

src/pkg/io/multi.go
src/pkg/io/multi_test.go

index ab8dd5d3b40534e2354846b814d42d3a173ad004..e26cc53e9eeb7cc8477a00247b177ffd9cea3a36 100644 (file)
@@ -29,7 +29,9 @@ func (mr *multiReader) Read(p []byte) (n int, err error) {
 // inputs have returned EOF, Read will return EOF.  If any of the readers
 // return a non-nil, non-EOF error, Read will return that error.
 func MultiReader(readers ...Reader) Reader {
-       return &multiReader{readers}
+       r := make([]Reader, len(readers))
+       copy(r, readers)
+       return &multiReader{r}
 }
 
 type multiWriter struct {
@@ -53,5 +55,7 @@ func (t *multiWriter) Write(p []byte) (n int, err error) {
 // MultiWriter creates a writer that duplicates its writes to all the
 // provided writers, similar to the Unix tee(1) command.
 func MultiWriter(writers ...Writer) Writer {
-       return &multiWriter{writers}
+       w := make([]Writer, len(writers))
+       copy(w, writers)
+       return &multiWriter{w}
 }
index eb717f7bc21c7405bf1716aa100b06a21d9f22b1..56c6769a9eb598cc8e1671c88848eb5eb2f85245 100644 (file)
@@ -9,6 +9,7 @@ import (
        "crypto/sha1"
        "fmt"
        . "io"
+       "io/ioutil"
        "strings"
        "testing"
 )
@@ -86,3 +87,29 @@ func TestMultiWriter(t *testing.T) {
                t.Errorf("expected %q; got %q", sourceString, sink.String())
        }
 }
+
+// Test that MultiReader copies the input slice and is insulated from future modification.
+func TestMultiReaderCopy(t *testing.T) {
+       slice := []Reader{strings.NewReader("hello world")}
+       r := MultiReader(slice...)
+       slice[0] = nil
+       data, err := ioutil.ReadAll(r)
+       if err != nil || string(data) != "hello world" {
+               t.Errorf("ReadAll() = %q, %v, want %q, nil", data, err, "hello world")
+       }
+}
+
+// Test that MultiWriter copies the input slice and is insulated from future modification.
+func TestMultiWriterCopy(t *testing.T) {
+       var buf bytes.Buffer
+       slice := []Writer{&buf}
+       w := MultiWriter(slice...)
+       slice[0] = nil
+       n, err := w.Write([]byte("hello world"))
+       if err != nil || n != 11 {
+               t.Errorf("Write(`hello world`) = %d, %v, want 11, nil", n, err)
+       }
+       if buf.String() != "hello world" {
+               t.Errorf("buf.String() = %q, want %q", buf.String(), "hello world")
+       }
+}