Skip to content

Commit

Permalink
gunzip: handle io.EOF errors correctly in WriteTo
Browse files Browse the repository at this point in the history
WriteTo should not return io.EOF because it is assumed to have io.Copy
semantics (namely, on success you return no error -- even if there were
no bytes copied). Several parts of WriteTo would return io.EOF -- all of
which need to be switched to special-case io.EOF.

In addition, Read would save io.EOF in z.err in some specific corner
cases -- these appear to be oversights and thus are fixed to not store
io.EOF in z.err.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
  • Loading branch information
cyphar committed Feb 19, 2021
1 parent d6725aa commit 6e433a6
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions gunzip.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,9 @@ func (z *Reader) Read(p []byte) (n int, err error) {

// Is there another?
if err = z.readHeader(false); err != nil {
z.err = err
if err != io.EOF {
z.err = err
}
return
}

Expand All @@ -492,8 +494,11 @@ func (z *Reader) Read(p []byte) (n int, err error) {
func (z *Reader) WriteTo(w io.Writer) (n int64, err error) {
total := int64(0)
for {
if z.err != nil {
return total, z.err
if err = z.err; err != nil {
if err == io.EOF {
err = nil
}
return
}
// We write both to output and digest.
for {
Expand Down Expand Up @@ -530,8 +535,12 @@ func (z *Reader) WriteTo(w io.Writer) (n int64, err error) {

// Finished file; check checksum + size.
if _, err := io.ReadFull(z.r, z.buf[0:8]); err != nil {
z.err = err
return total, err
if total == 0 && err == io.EOF {
err = nil
} else {
z.err = err
return total, err
}
}
crc32, isize := get4(z.buf[0:4]), get4(z.buf[4:8])
sum := z.digest.Sum32()
Expand Down

0 comments on commit 6e433a6

Please sign in to comment.