123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- // Copyright 2009 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // This test tests some internals of the flate package.
- // The tests in package compress/gzip serve as the
- // end-to-end test of the decompressor.
- package flate
- import (
- "archive/zip"
- "bytes"
- "compress/flate"
- "encoding/hex"
- "fmt"
- "io/ioutil"
- "testing"
- )
- // The following test should not panic.
- func TestIssue5915(t *testing.T) {
- bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0, 5, 5, 6,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 0, 11, 0, 8, 0, 6, 6, 10, 8}
- var h huffmanDecoder
- if h.init(bits) {
- t.Fatalf("Given sequence of bits is bad, and should not succeed.")
- }
- }
- // The following test should not panic.
- func TestIssue5962(t *testing.T) {
- bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0,
- 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11}
- var h huffmanDecoder
- if h.init(bits) {
- t.Fatalf("Given sequence of bits is bad, and should not succeed.")
- }
- }
- // The following test should not panic.
- func TestIssue6255(t *testing.T) {
- bits1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11}
- bits2 := []int{11, 13}
- var h huffmanDecoder
- if !h.init(bits1) {
- t.Fatalf("Given sequence of bits is good and should succeed.")
- }
- if h.init(bits2) {
- t.Fatalf("Given sequence of bits is bad and should not succeed.")
- }
- }
- func TestInvalidEncoding(t *testing.T) {
- // Initialize Huffman decoder to recognize "0".
- var h huffmanDecoder
- if !h.init([]int{1}) {
- t.Fatal("Failed to initialize Huffman decoder")
- }
- // Initialize decompressor with invalid Huffman coding.
- var f decompressor
- f.r = bytes.NewReader([]byte{0xff})
- _, err := f.huffSym(&h)
- if err == nil {
- t.Fatal("Should have rejected invalid bit sequence")
- }
- }
- func TestRegressions(t *testing.T) {
- // Test fuzzer regressions
- data, err := ioutil.ReadFile("testdata/regression.zip")
- if err != nil {
- t.Fatal(err)
- }
- zr, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
- if err != nil {
- t.Fatal(err)
- }
- for _, tt := range zr.File {
- data, err := tt.Open()
- if err != nil {
- t.Fatal(err)
- }
- data1, err := ioutil.ReadAll(data)
- if err != nil {
- t.Fatal(err)
- }
- for level := 0; level <= 9; level++ {
- t.Run(fmt.Sprint(tt.Name+"-level", 1), func(t *testing.T) {
- buf := new(bytes.Buffer)
- fw, err := NewWriter(buf, level)
- if err != nil {
- t.Error(err)
- }
- n, err := fw.Write(data1)
- if n != len(data1) {
- t.Error("short write")
- }
- if err != nil {
- t.Error(err)
- }
- err = fw.Close()
- if err != nil {
- t.Error(err)
- }
- fr1 := NewReader(buf)
- data2, err := ioutil.ReadAll(fr1)
- if err != nil {
- t.Error(err)
- }
- if bytes.Compare(data1, data2) != 0 {
- t.Error("not equal")
- }
- // Do it again...
- buf.Reset()
- fw.Reset(buf)
- n, err = fw.Write(data1)
- if n != len(data1) {
- t.Error("short write")
- }
- if err != nil {
- t.Error(err)
- }
- err = fw.Close()
- if err != nil {
- t.Error(err)
- }
- fr1 = flate.NewReader(buf)
- data2, err = ioutil.ReadAll(fr1)
- if err != nil {
- t.Error(err)
- }
- if bytes.Compare(data1, data2) != 0 {
- t.Error("not equal")
- }
- })
- }
- t.Run(tt.Name+"stateless", func(t *testing.T) {
- // Split into two and use history...
- buf := new(bytes.Buffer)
- err = StatelessDeflate(buf, data1[:len(data1)/2], false, nil)
- if err != nil {
- t.Error(err)
- }
- // Use top half as dictionary...
- dict := data1[:len(data1)/2]
- err = StatelessDeflate(buf, data1[len(data1)/2:], true, dict)
- if err != nil {
- t.Error(err)
- }
- t.Log(buf.Len())
- fr1 := NewReader(buf)
- data2, err := ioutil.ReadAll(fr1)
- if err != nil {
- t.Error(err)
- }
- if bytes.Compare(data1, data2) != 0 {
- fmt.Printf("want:%x\ngot: %x\n", data1, data2)
- t.Error("not equal")
- }
- })
- }
- }
- func TestInvalidBits(t *testing.T) {
- oversubscribed := []int{1, 2, 3, 4, 4, 5}
- incomplete := []int{1, 2, 4, 4}
- var h huffmanDecoder
- if h.init(oversubscribed) {
- t.Fatal("Should reject oversubscribed bit-length set")
- }
- if h.init(incomplete) {
- t.Fatal("Should reject incomplete bit-length set")
- }
- }
- func TestStreams(t *testing.T) {
- // To verify any of these hexstrings as valid or invalid flate streams
- // according to the C zlib library, you can use the Python wrapper library:
- // >>> hex_string = "010100feff11"
- // >>> import zlib
- // >>> zlib.decompress(hex_string.decode("hex"), -15) # Negative means raw DEFLATE
- // '\x11'
- testCases := []struct {
- desc string // Description of the stream
- stream string // Hexstring of the input DEFLATE stream
- want string // Expected result. Use "fail" to expect failure
- }{{
- "degenerate HCLenTree",
- "05e0010000000000100000000000000000000000000000000000000000000000" +
- "00000000000000000004",
- "fail",
- }, {
- "complete HCLenTree, empty HLitTree, empty HDistTree",
- "05e0010400000000000000000000000000000000000000000000000000000000" +
- "00000000000000000010",
- "fail",
- }, {
- "empty HCLenTree",
- "05e0010000000000000000000000000000000000000000000000000000000000" +
- "00000000000000000010",
- "fail",
- }, {
- "complete HCLenTree, complete HLitTree, empty HDistTree, use missing HDist symbol",
- "000100feff000de0010400000000100000000000000000000000000000000000" +
- "0000000000000000000000000000002c",
- "fail",
- }, {
- "complete HCLenTree, complete HLitTree, degenerate HDistTree, use missing HDist symbol",
- "000100feff000de0010000000000000000000000000000000000000000000000" +
- "00000000000000000610000000004070",
- "fail",
- }, {
- "complete HCLenTree, empty HLitTree, empty HDistTree",
- "05e0010400000000100400000000000000000000000000000000000000000000" +
- "0000000000000000000000000008",
- "fail",
- }, {
- "complete HCLenTree, empty HLitTree, degenerate HDistTree",
- "05e0010400000000100400000000000000000000000000000000000000000000" +
- "0000000000000000000800000008",
- "fail",
- }, {
- "complete HCLenTree, degenerate HLitTree, degenerate HDistTree, use missing HLit symbol",
- "05e0010400000000100000000000000000000000000000000000000000000000" +
- "0000000000000000001c",
- "fail",
- }, {
- "complete HCLenTree, complete HLitTree, too large HDistTree",
- "edff870500000000200400000000000000000000000000000000000000000000" +
- "000000000000000000080000000000000004",
- "fail",
- }, {
- "complete HCLenTree, complete HLitTree, empty HDistTree, excessive repeater code",
- "edfd870500000000200400000000000000000000000000000000000000000000" +
- "000000000000000000e8b100",
- "fail",
- }, {
- "complete HCLenTree, complete HLitTree, empty HDistTree of normal length 30",
- "05fd01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
- "ffffffffffffffffff07000000fe01",
- "",
- }, {
- "complete HCLenTree, complete HLitTree, empty HDistTree of excessive length 31",
- "05fe01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
- "ffffffffffffffffff07000000fc03",
- "fail",
- }, {
- "complete HCLenTree, over-subscribed HLitTree, empty HDistTree",
- "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
- "ffffffffffffffffff07f00f",
- "fail",
- }, {
- "complete HCLenTree, under-subscribed HLitTree, empty HDistTree",
- "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
- "fffffffffcffffffff07f00f",
- "fail",
- }, {
- "complete HCLenTree, complete HLitTree with single code, empty HDistTree",
- "05e001240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
- "ffffffffffffffffff07f00f",
- "01",
- }, {
- "complete HCLenTree, complete HLitTree with multiple codes, empty HDistTree",
- "05e301240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
- "ffffffffffffffffff07807f",
- "01",
- }, {
- "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HDist symbol",
- "000100feff000de0010400000000100000000000000000000000000000000000" +
- "0000000000000000000000000000003c",
- "00000000",
- }, {
- "complete HCLenTree, degenerate HLitTree, degenerate HDistTree",
- "05e0010400000000100000000000000000000000000000000000000000000000" +
- "0000000000000000000c",
- "",
- }, {
- "complete HCLenTree, degenerate HLitTree, empty HDistTree",
- "05e0010400000000100000000000000000000000000000000000000000000000" +
- "00000000000000000004",
- "",
- }, {
- "complete HCLenTree, complete HLitTree, empty HDistTree, spanning repeater code",
- "edfd870500000000200400000000000000000000000000000000000000000000" +
- "000000000000000000e8b000",
- "",
- }, {
- "complete HCLenTree with length codes, complete HLitTree, empty HDistTree",
- "ede0010400000000100000000000000000000000000000000000000000000000" +
- "0000000000000000000400004000",
- "",
- }, {
- "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit symbol 284 with count 31",
- "000100feff00ede0010400000000100000000000000000000000000000000000" +
- "000000000000000000000000000000040000407f00",
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "0000000000000000000000000000000000000000000000000000000000000000" +
- "000000",
- }, {
- "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit and HDist symbols",
- "0cc2010d00000082b0ac4aff0eb07d27060000ffff",
- "616263616263",
- }, {
- "fixed block, use reserved symbol 287",
- "33180700",
- "fail",
- }, {
- "raw block",
- "010100feff11",
- "11",
- }, {
- "issue 10426 - over-subscribed HCLenTree causes a hang",
- "344c4a4e494d4b070000ff2e2eff2e2e2e2e2eff",
- "fail",
- }, {
- "issue 11030 - empty HDistTree unexpectedly leads to error",
- "05c0070600000080400fff37a0ca",
- "",
- }, {
- "issue 11033 - empty HDistTree unexpectedly leads to error",
- "050fb109c020cca5d017dcbca044881ee1034ec149c8980bbc413c2ab35be9dc" +
- "b1473449922449922411202306ee97b0383a521b4ffdcf3217f9f7d3adb701",
- "3130303634342068652e706870005d05355f7ed957ff084a90925d19e3ebc6d0" +
- "c6d7",
- }}
- for i, tc := range testCases {
- data, err := hex.DecodeString(tc.stream)
- if err != nil {
- t.Fatal(err)
- }
- data, err = ioutil.ReadAll(NewReader(bytes.NewReader(data)))
- if tc.want == "fail" {
- if err == nil {
- t.Errorf("#%d (%s): got nil error, want non-nil", i, tc.desc)
- }
- } else {
- if err != nil {
- t.Errorf("#%d (%s): %v", i, tc.desc, err)
- continue
- }
- if got := hex.EncodeToString(data); got != tc.want {
- t.Errorf("#%d (%s):\ngot %q\nwant %q", i, tc.desc, got, tc.want)
- }
- }
- }
- }
|