diff options
author | Russ Cox <rsc@golang.org> | 2013-10-09 08:37:06 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2013-10-09 08:37:06 -0400 |
commit | 8ba6deb1ec6cc48b54e98cb97de5e907e7901c58 (patch) | |
tree | c99811b563d0706d095cb77d8a1861781ad8d9d8 | |
parent | 158c56ef8a7149d863fda4726094978d0562eea2 (diff) | |
download | go-8ba6deb1ec6cc48b54e98cb97de5e907e7901c58.tar.gz go-8ba6deb1ec6cc48b54e98cb97de5e907e7901c58.zip |
compress/flate: fix infinite loop on malformed data
Test using compress/gzip, because that's how the
data arrived.
Fixes #6550.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/14441051
-rw-r--r-- | src/pkg/compress/flate/inflate.go | 4 | ||||
-rw-r--r-- | src/pkg/compress/gzip/gunzip_test.go | 31 | ||||
-rw-r--r-- | src/pkg/compress/gzip/testdata/issue6550.gz | bin | 0 -> 65536 bytes |
3 files changed, 35 insertions, 0 deletions
diff --git a/src/pkg/compress/flate/inflate.go b/src/pkg/compress/flate/inflate.go index 34ba00d5af..3eb3b2b83e 100644 --- a/src/pkg/compress/flate/inflate.go +++ b/src/pkg/compress/flate/inflate.go @@ -644,6 +644,10 @@ func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) { if n > huffmanChunkBits { chunk = h.links[chunk>>huffmanValueShift][(f.b>>huffmanChunkBits)&h.linkMask] n = uint(chunk & huffmanCountMask) + if n == 0 { + f.err = CorruptInputError(f.roffset) + return 0, f.err + } } if n <= f.nb { f.b >>= n diff --git a/src/pkg/compress/gzip/gunzip_test.go b/src/pkg/compress/gzip/gunzip_test.go index a1333580dc..572fb58488 100644 --- a/src/pkg/compress/gzip/gunzip_test.go +++ b/src/pkg/compress/gzip/gunzip_test.go @@ -7,7 +7,10 @@ package gzip import ( "bytes" "io" + "io/ioutil" + "os" "testing" + "time" ) type gunzipTest struct { @@ -302,3 +305,31 @@ func TestDecompressor(t *testing.T) { } } } + +func TestIssue6550(t *testing.T) { + f, err := os.Open("testdata/issue6550.gz") + if err != nil { + t.Fatal(err) + } + gzip, err := NewReader(f) + if err != nil { + t.Fatalf("NewReader(testdata/issue6550.gz): %v", err) + } + defer gzip.Close() + done := make(chan bool, 1) + go func() { + _, err := io.Copy(ioutil.Discard, gzip) + if err == nil { + t.Errorf("Copy succeeded") + } else { + t.Logf("Copy failed (correctly): %v", err) + } + done <- true + }() + select { + case <-time.After(1 * time.Second): + t.Errorf("Copy hung") + case <-done: + // ok + } +} diff --git a/src/pkg/compress/gzip/testdata/issue6550.gz b/src/pkg/compress/gzip/testdata/issue6550.gz Binary files differnew file mode 100644 index 0000000000..57972b6366 --- /dev/null +++ b/src/pkg/compress/gzip/testdata/issue6550.gz |