From 0a4df3791951eaa876db8046a7caca258afa693e Mon Sep 17 00:00:00 2001 From: Tom Clegg Date: Tue, 19 Sep 2017 10:37:43 -0400 Subject: [PATCH] 12247: Propagate write errors, don't hide them with "bad checksum". Arvados-DCO-1.1-Signed-off-by: Tom Clegg --- sdk/go/keepclient/hashcheck.go | 14 +++++++++----- sdk/go/keepclient/hashcheck_test.go | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/sdk/go/keepclient/hashcheck.go b/sdk/go/keepclient/hashcheck.go index 4a5c09ba79..9b13eda771 100644 --- a/sdk/go/keepclient/hashcheck.go +++ b/sdk/go/keepclient/hashcheck.go @@ -43,8 +43,9 @@ func (this HashCheckingReader) Read(p []byte) (n int, err error) { return n, err } -// WriteTo writes the entire contents of this.Reader to dest. Returns -// BadChecksum if the checksum doesn't match. +// WriteTo writes the entire contents of this.Reader to dest. Returns +// BadChecksum if writing is successful but the checksum doesn't +// match. func (this HashCheckingReader) WriteTo(dest io.Writer) (written int64, err error) { if writeto, ok := this.Reader.(io.WriterTo); ok { written, err = writeto.WriteTo(io.MultiWriter(dest, this.Hash)) @@ -52,13 +53,16 @@ func (this HashCheckingReader) WriteTo(dest io.Writer) (written int64, err error written, err = io.Copy(io.MultiWriter(dest, this.Hash), this.Reader) } - sum := this.Hash.Sum(make([]byte, 0, this.Hash.Size())) + if err != nil { + return written, err + } + sum := this.Hash.Sum(make([]byte, 0, this.Hash.Size())) if fmt.Sprintf("%x", sum) != this.Check { - err = BadChecksum + return written, BadChecksum } - return written, err + return written, nil } // Close reads all remaining data from the underlying Reader and diff --git a/sdk/go/keepclient/hashcheck_test.go b/sdk/go/keepclient/hashcheck_test.go index db748ee98e..44345afda6 100644 --- a/sdk/go/keepclient/hashcheck_test.go +++ b/sdk/go/keepclient/hashcheck_test.go @@ -8,9 +8,10 @@ import ( "bytes" "crypto/md5" "fmt" - . "gopkg.in/check.v1" "io" "io/ioutil" + + . "gopkg.in/check.v1" ) type HashcheckSuiteSuite struct{} @@ -86,4 +87,17 @@ func (h *HashcheckSuiteSuite) TestWriteTo(c *C) { c.Check(err, Equals, BadChecksum) <-done } + + // If WriteTo stops early due to a write error, return the + // write error (not "bad checksum"). + { + input := bytes.NewBuffer(make([]byte, 1<<26)) + hcr := HashCheckingReader{input, md5.New(), hash} + r, w := io.Pipe() + r.Close() + n, err := hcr.WriteTo(w) + c.Check(n, Equals, int64(0)) + c.Check(err, NotNil) + c.Check(err, Not(Equals), BadChecksum) + } } -- 2.30.2