]> Cypherpunks repositories - gostls13.git/commitdiff
io: prevent write to PipeWriter after Close
authorRick Arnold <rickarnoldjr@gmail.com>
Tue, 13 Aug 2013 18:04:09 +0000 (11:04 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 13 Aug 2013 18:04:09 +0000 (11:04 -0700)
Return an ErrClosedPipe rather than allowing the write to proceed.

Fixes #5330.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/12541053

src/pkg/io/pipe.go
src/pkg/io/pipe_test.go

index f3f0f175706ad117b6ce194421a8bd9690cdd6c9..f65354a7f253b65a4c1718b3dae1908c55229efe 100644 (file)
@@ -74,6 +74,10 @@ func (p *pipe) write(b []byte) (n int, err error) {
 
        p.l.Lock()
        defer p.l.Unlock()
+       if p.werr != nil {
+               err = ErrClosedPipe
+               return
+       }
        p.data = b
        p.rwait.Signal()
        for {
index 7718151b0e5a5b3ff845c0d57c557c3d1bf4f459..b16e6530693578680d79fe5794ef7818a141d635 100644 (file)
@@ -268,3 +268,35 @@ func TestWriteNil(t *testing.T) {
        ReadFull(r, b[0:2])
        r.Close()
 }
+
+func TestWriteAfterWriterClose(t *testing.T) {
+       r, w := Pipe()
+
+       done := make(chan bool)
+       var writeErr error
+       go func() {
+               _, err := w.Write([]byte("hello"))
+               if err != nil {
+                       t.Errorf("got error: %q; expected none", err)
+               }
+               w.Close()
+               _, writeErr = w.Write([]byte("world"))
+               done <- true
+       }()
+
+       buf := make([]byte, 100)
+       var result string
+       n, err := ReadFull(r, buf)
+       if err != nil && err != ErrUnexpectedEOF {
+               t.Fatalf("got: %q; want: %q", err, ErrUnexpectedEOF)
+       }
+       result = string(buf[0:n])
+       <-done
+
+       if result != "hello" {
+               t.Errorf("got: %q; want: %q", result, "hello")
+       }
+       if writeErr != ErrClosedPipe {
+               t.Errorf("got: %q; want: %q", writeErr, ErrClosedPipe)
+       }
+}