From: Joe Tsai Date: Mon, 2 May 2022 18:40:57 +0000 (-0700) Subject: compress/flate: move idempotent close logic to compressor X-Git-Tag: go1.19beta1~486 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a887579976c0f581ca0eb52094b2c5c63893dcdf;p=gostls13.git compress/flate: move idempotent close logic to compressor The compressor methods already have logic for handling a sticky error. Merge the logic from CL 136475 into that. This slightly changes the error message to be more sensible in the situation where it's returned by Flush. Updates #27741 Change-Id: Ie34cf3164d0fa6bd0811175ca467dbbcb3be1395 Reviewed-on: https://go-review.googlesource.com/c/go/+/403514 Reviewed-by: Dmitri Shuralyov TryBot-Result: Gopher Robot Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Auto-Submit: Ian Lance Taylor --- diff --git a/src/compress/flate/deflate.go b/src/compress/flate/deflate.go index ccf03d74eb..4ca20b87ba 100644 --- a/src/compress/flate/deflate.go +++ b/src/compress/flate/deflate.go @@ -640,6 +640,9 @@ func (d *compressor) reset(w io.Writer) { } func (d *compressor) close() error { + if d.err == errWriterClosed { + return nil + } if d.err != nil { return d.err } @@ -652,7 +655,11 @@ func (d *compressor) close() error { return d.w.err } d.w.flush() - return d.w.err + if d.w.err != nil { + return d.w.err + } + d.err = errWriterClosed + return nil } // NewWriter returns a new Writer compressing data at the given level. @@ -700,27 +707,19 @@ func (w *dictWriter) Write(b []byte) (n int, err error) { return w.w.Write(b) } -var errWriteAfterClose = errors.New("compress/flate: write after close") +var errWriterClosed = errors.New("flate: closed writer") // A Writer takes data written to it and writes the compressed // form of that data to an underlying writer (see NewWriter). type Writer struct { d compressor dict []byte - err error } // Write writes data to w, which will eventually write the // compressed form of data to its underlying writer. func (w *Writer) Write(data []byte) (n int, err error) { - if w.err != nil { - return 0, w.err - } - n, err = w.d.write(data) - if err != nil { - w.err = err - } - return n, err + return w.d.write(data) } // Flush flushes any pending data to the underlying writer. @@ -735,37 +734,18 @@ func (w *Writer) Write(data []byte) (n int, err error) { func (w *Writer) Flush() error { // For more about flushing: // https://www.bolet.org/~pornin/deflate-flush.html - if w.err != nil { - return w.err - } - if err := w.d.syncFlush(); err != nil { - w.err = err - return err - } - return nil + return w.d.syncFlush() } // Close flushes and closes the writer. func (w *Writer) Close() error { - if w.err == errWriteAfterClose { - return nil - } - if w.err != nil { - return w.err - } - if err := w.d.close(); err != nil { - w.err = err - return err - } - w.err = errWriteAfterClose - return nil + return w.d.close() } // Reset discards the writer's state and makes it equivalent to // the result of NewWriter or NewWriterDict called with dst // and w's level and dictionary. func (w *Writer) Reset(dst io.Writer) { - w.err = nil if dw, ok := w.d.w.writer.(*dictWriter); ok { // w was created with NewWriterDict dw.w = dst diff --git a/src/compress/flate/deflate_test.go b/src/compress/flate/deflate_test.go index 8c9ee72feb..6d2043091a 100644 --- a/src/compress/flate/deflate_test.go +++ b/src/compress/flate/deflate_test.go @@ -143,7 +143,7 @@ func TestWriterClose(t *testing.T) { afterClose := b.Len() if c, err := zw.Write([]byte("Test")); err == nil || c != 0 { - t.Fatalf("Write to closed writer: %s, %d", err, c) + t.Fatalf("Write to closed writer: %v, %d", err, c) } if err := zw.Flush(); err == nil { @@ -794,7 +794,7 @@ func TestWriterPersistentCloseError(t *testing.T) { flushErr = zw.Flush() _, writeErr = zw.Write([]byte("Test")) - checkErrors([]error{flushErr, writeErr}, errWriteAfterClose, t) + checkErrors([]error{flushErr, writeErr}, errWriterClosed, t) } func checkErrors(got []error, want error, t *testing.T) {