From 85f892898fe257b2a9c0d6c15d7d171d5fc6caa2 Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Thu, 24 Oct 2019 13:10:44 +0200 Subject: [PATCH 1/2] huff0: Return compression error. When reusing, errors returned from the compressor was not forwarded correctly. --- huff0/compress.go | 3 +++ huff0/testdata/regression.zip | Bin 137611 -> 137774 bytes 2 files changed, 3 insertions(+) diff --git a/huff0/compress.go b/huff0/compress.go index dd4f7fefb9..61c6ede080 100644 --- a/huff0/compress.go +++ b/huff0/compress.go @@ -105,6 +105,9 @@ func compress(in []byte, s *Scratch, compressor func(src []byte) ([]byte, error) keepTable := s.cTable s.cTable = s.prevTable s.Out, err = compressor(in) + if err != nil { + return nil, false, err + } s.cTable = keepTable if len(s.Out) >= len(in) { return nil, false, ErrIncompressible diff --git a/huff0/testdata/regression.zip b/huff0/testdata/regression.zip index 9cbbfe9ff82d38bb7f593de5609480aabe064027..9d33c4e917ecbbd7ee17ac392d3175c56991863a 100644 GIT binary patch delta 199 zcmeC)%&~3@N5dAzUr)T4Swt9^7&sUNG9vsXjrJ*VI Date: Thu, 24 Oct 2019 13:40:16 +0200 Subject: [PATCH 2/2] Add test that matches the fuzz test. --- huff0/compress_test.go | 114 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/huff0/compress_test.go b/huff0/compress_test.go index 300ec78005..f8d6cfeaa7 100644 --- a/huff0/compress_test.go +++ b/huff0/compress_test.go @@ -88,6 +88,120 @@ func init() { } } +func TestCompressRegression(t *testing.T) { + // Match the fuzz function + var testInput = func(data []byte) int { + var sc Scratch + comp, _, err := Compress1X(data, &sc) + if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig { + return 0 + } + if err != nil { + panic(err) + } + s, remain, err := ReadTable(comp, nil) + if err != nil { + panic(err) + } + out, err := s.Decompress1X(remain) + if err != nil { + panic(err) + } + if !bytes.Equal(out, data) { + panic("decompression 1x mismatch") + } + // Reuse as 4X + sc.Reuse = ReusePolicyAllow + comp, reUsed, err := Compress4X(data, &sc) + if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig { + return 0 + } + if err != nil { + panic(err) + } + remain = comp + if !reUsed { + s, remain, err = ReadTable(comp, s) + if err != nil { + panic(err) + } + } + out, err = s.Decompress4X(remain, len(data)) + if err != nil { + panic(err) + } + if !bytes.Equal(out, data) { + panic("decompression 4x with reuse mismatch") + } + + s.Reuse = ReusePolicyNone + comp, reUsed, err = Compress4X(data, s) + if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig { + return 0 + } + if err != nil { + panic(err) + } + if reUsed { + panic("reused when asked not to") + } + s, remain, err = ReadTable(comp, nil) + if err != nil { + panic(err) + } + out, err = s.Decompress4X(remain, len(data)) + if err != nil { + panic(err) + } + if !bytes.Equal(out, data) { + panic("decompression 4x mismatch") + } + + // Reuse as 1X + s.Reuse = ReusePolicyAllow + comp, reUsed, err = Compress1X(data, &sc) + if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig { + return 0 + } + if err != nil { + panic(err) + } + remain = comp + if !reUsed { + s, remain, err = ReadTable(comp, s) + if err != nil { + panic(err) + } + } + out, err = s.Decompress1X(remain) + if err != nil { + panic(err) + } + if !bytes.Equal(out, data) { + panic("decompression 1x with reuse mismatch") + } + return 1 + } + for _, test := range testfiles { + t.Run(test.name, func(t *testing.T) { + buf0, err := test.fn() + if err != nil { + t.Fatal(err) + } + testInput(buf0) + }) + } + for _, test := range testfilesExtended { + t.Run(test.name, func(t *testing.T) { + buf0, err := test.fn() + if err != nil { + t.Fatal(err) + } + testInput(buf0) + }) + } +} + func TestCompress1X(t *testing.T) { for _, test := range testfiles { t.Run(test.name, func(t *testing.T) {