]> Cypherpunks repositories - gostls13.git/commitdiff
compress/flate: always return uncompressed data in the event of error
authorJoe Tsai <joetsai@digital-static.net>
Tue, 30 Aug 2016 23:08:06 +0000 (16:08 -0700)
committerJoe Tsai <thebrokentoaster@gmail.com>
Wed, 31 Aug 2016 01:12:02 +0000 (01:12 +0000)
In the event of an unexpected error, we should always flush available
decompressed data to the user.

Fixes #16924

Change-Id: I0bc0824c3201f3149e84e6a26e3dbcba72a1aae5
Reviewed-on: https://go-review.googlesource.com/28216
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/compress/flate/inflate.go
src/compress/flate/inflate_test.go
src/compress/gzip/gunzip_test.go
src/compress/zlib/reader_test.go

index 68cc232052bc328c6c55165e9e49cc1241a6eacf..9a8c4fc455a4e6930f0b47e03b317898063b51b9 100644 (file)
@@ -344,6 +344,9 @@ func (f *decompressor) Read(b []byte) (int, error) {
                        return 0, f.err
                }
                f.step(f)
+               if f.err != nil && len(f.toRead) == 0 {
+                       f.toRead = f.dict.readFlush() // Flush what's left in case of error
+               }
        }
 }
 
index e0bce71d6f2d9eda8795c95dd2df93c00df0ee3f..951decd7754bb6aee7d1737bed6ada770c741e05 100644 (file)
@@ -7,6 +7,8 @@ package flate
 import (
        "bytes"
        "io"
+       "io/ioutil"
+       "strings"
        "testing"
 )
 
@@ -38,6 +40,33 @@ func TestReset(t *testing.T) {
        }
 }
 
+func TestReaderTruncated(t *testing.T) {
+       vectors := []struct{ input, output string }{
+               {"\x00", ""},
+               {"\x00\f", ""},
+               {"\x00\f\x00", ""},
+               {"\x00\f\x00\xf3\xff", ""},
+               {"\x00\f\x00\xf3\xffhello", "hello"},
+               {"\x00\f\x00\xf3\xffhello, world", "hello, world"},
+               {"\x02", ""},
+               {"\xf2H\xcd", "He"},
+               {"\xf2H͙0a\u0084\t", "Hel\x90\x90\x90\x90\x90"},
+               {"\xf2H͙0a\u0084\t\x00", "Hel\x90\x90\x90\x90\x90"},
+       }
+
+       for i, v := range vectors {
+               r := strings.NewReader(v.input)
+               zr := NewReader(r)
+               b, err := ioutil.ReadAll(zr)
+               if err != io.ErrUnexpectedEOF {
+                       t.Errorf("test %d, error mismatch: got %v, want io.ErrUnexpectedEOF", i, err)
+               }
+               if string(b) != v.output {
+                       t.Errorf("test %d, output mismatch: got %q, want %q", i, b, v.output)
+               }
+       }
+}
+
 func TestResetDict(t *testing.T) {
        dict := []byte("the lorem fox")
        ss := []string{
index fdce91989a614027bf30aab668a3a9b1f053467b..fdea0c5d5ff82a81130928061b4f674acf9dd9ba 100644 (file)
@@ -339,6 +339,26 @@ var gunzipTests = []gunzipTest{
                },
                nil,
        },
+       {
+               "",
+               "truncated gzip file amid raw-block",
+               "hello",
+               []byte{
+                       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+                       0x00, 0x0c, 0x00, 0xf3, 0xff, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
+               },
+               io.ErrUnexpectedEOF,
+       },
+       {
+               "",
+               "truncated gzip file amid fixed-block",
+               "He",
+               []byte{
+                       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+                       0xf2, 0x48, 0xcd,
+               },
+               io.ErrUnexpectedEOF,
+       },
 }
 
 func TestDecompressor(t *testing.T) {
index f74bff1f3cc6e9acce076d8eb8cd595b5b03f9b2..7e27aecb47d1b864d167bbccd4a3dd31f925e6f1 100644 (file)
@@ -121,6 +121,24 @@ var zlibTests = []zlibTest{
                },
                ErrDictionary,
        },
+       {
+               "truncated zlib stream amid raw-block",
+               "hello",
+               []byte{
+                       0x78, 0x9c, 0x00, 0x0c, 0x00, 0xf3, 0xff, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
+               },
+               nil,
+               io.ErrUnexpectedEOF,
+       },
+       {
+               "truncated zlib stream amid fixed-block",
+               "He",
+               []byte{
+                       0x78, 0x9c, 0xf2, 0x48, 0xcd,
+               },
+               nil,
+               io.ErrUnexpectedEOF,
+       },
 }
 
 func TestDecompressor(t *testing.T) {