Home | History | Annotate | Download | only in flate
      1 // Copyright 2009 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // This test tests some internals of the flate package.
      6 // The tests in package compress/gzip serve as the
      7 // end-to-end test of the decompressor.
      8 
      9 package flate
     10 
     11 import (
     12 	"bytes"
     13 	"encoding/hex"
     14 	"io/ioutil"
     15 	"testing"
     16 )
     17 
     18 // The following test should not panic.
     19 func TestIssue5915(t *testing.T) {
     20 	bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0, 5, 5, 6,
     21 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     22 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 0, 11, 0, 8, 0, 6, 6, 10, 8}
     23 	var h huffmanDecoder
     24 	if h.init(bits) {
     25 		t.Fatalf("Given sequence of bits is bad, and should not succeed.")
     26 	}
     27 }
     28 
     29 // The following test should not panic.
     30 func TestIssue5962(t *testing.T) {
     31 	bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0,
     32 		5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11}
     33 	var h huffmanDecoder
     34 	if h.init(bits) {
     35 		t.Fatalf("Given sequence of bits is bad, and should not succeed.")
     36 	}
     37 }
     38 
     39 // The following test should not panic.
     40 func TestIssue6255(t *testing.T) {
     41 	bits1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11}
     42 	bits2 := []int{11, 13}
     43 	var h huffmanDecoder
     44 	if !h.init(bits1) {
     45 		t.Fatalf("Given sequence of bits is good and should succeed.")
     46 	}
     47 	if h.init(bits2) {
     48 		t.Fatalf("Given sequence of bits is bad and should not succeed.")
     49 	}
     50 }
     51 
     52 func TestInvalidEncoding(t *testing.T) {
     53 	// Initialize Huffman decoder to recognize "0".
     54 	var h huffmanDecoder
     55 	if !h.init([]int{1}) {
     56 		t.Fatal("Failed to initialize Huffman decoder")
     57 	}
     58 
     59 	// Initialize decompressor with invalid Huffman coding.
     60 	var f decompressor
     61 	f.r = bytes.NewReader([]byte{0xff})
     62 
     63 	_, err := f.huffSym(&h)
     64 	if err == nil {
     65 		t.Fatal("Should have rejected invalid bit sequence")
     66 	}
     67 }
     68 
     69 func TestInvalidBits(t *testing.T) {
     70 	oversubscribed := []int{1, 2, 3, 4, 4, 5}
     71 	incomplete := []int{1, 2, 4, 4}
     72 	var h huffmanDecoder
     73 	if h.init(oversubscribed) {
     74 		t.Fatal("Should reject oversubscribed bit-length set")
     75 	}
     76 	if h.init(incomplete) {
     77 		t.Fatal("Should reject incomplete bit-length set")
     78 	}
     79 }
     80 
     81 func TestStreams(t *testing.T) {
     82 	// To verify any of these hexstrings as valid or invalid flate streams
     83 	// according to the C zlib library, you can use the Python wrapper library:
     84 	// >>> hex_string = "010100feff11"
     85 	// >>> import zlib
     86 	// >>> zlib.decompress(hex_string.decode("hex"), -15) # Negative means raw DEFLATE
     87 	// '\x11'
     88 
     89 	testCases := []struct {
     90 		desc   string // Description of the stream
     91 		stream string // Hexstring of the input DEFLATE stream
     92 		want   string // Expected result. Use "fail" to expect failure
     93 	}{{
     94 		"degenerate HCLenTree",
     95 		"05e0010000000000100000000000000000000000000000000000000000000000" +
     96 			"00000000000000000004",
     97 		"fail",
     98 	}, {
     99 		"complete HCLenTree, empty HLitTree, empty HDistTree",
    100 		"05e0010400000000000000000000000000000000000000000000000000000000" +
    101 			"00000000000000000010",
    102 		"fail",
    103 	}, {
    104 		"empty HCLenTree",
    105 		"05e0010000000000000000000000000000000000000000000000000000000000" +
    106 			"00000000000000000010",
    107 		"fail",
    108 	}, {
    109 		"complete HCLenTree, complete HLitTree, empty HDistTree, use missing HDist symbol",
    110 		"000100feff000de0010400000000100000000000000000000000000000000000" +
    111 			"0000000000000000000000000000002c",
    112 		"fail",
    113 	}, {
    114 		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use missing HDist symbol",
    115 		"000100feff000de0010000000000000000000000000000000000000000000000" +
    116 			"00000000000000000610000000004070",
    117 		"fail",
    118 	}, {
    119 		"complete HCLenTree, empty HLitTree, empty HDistTree",
    120 		"05e0010400000000100400000000000000000000000000000000000000000000" +
    121 			"0000000000000000000000000008",
    122 		"fail",
    123 	}, {
    124 		"complete HCLenTree, empty HLitTree, degenerate HDistTree",
    125 		"05e0010400000000100400000000000000000000000000000000000000000000" +
    126 			"0000000000000000000800000008",
    127 		"fail",
    128 	}, {
    129 		"complete HCLenTree, degenerate HLitTree, degenerate HDistTree, use missing HLit symbol",
    130 		"05e0010400000000100000000000000000000000000000000000000000000000" +
    131 			"0000000000000000001c",
    132 		"fail",
    133 	}, {
    134 		"complete HCLenTree, complete HLitTree, too large HDistTree",
    135 		"edff870500000000200400000000000000000000000000000000000000000000" +
    136 			"000000000000000000080000000000000004",
    137 		"fail",
    138 	}, {
    139 		"complete HCLenTree, complete HLitTree, empty HDistTree, excessive repeater code",
    140 		"edfd870500000000200400000000000000000000000000000000000000000000" +
    141 			"000000000000000000e8b100",
    142 		"fail",
    143 	}, {
    144 		"complete HCLenTree, complete HLitTree, empty HDistTree of normal length 30",
    145 		"05fd01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
    146 			"ffffffffffffffffff07000000fe01",
    147 		"",
    148 	}, {
    149 		"complete HCLenTree, complete HLitTree, empty HDistTree of excessive length 31",
    150 		"05fe01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
    151 			"ffffffffffffffffff07000000fc03",
    152 		"fail",
    153 	}, {
    154 		"complete HCLenTree, over-subscribed HLitTree, empty HDistTree",
    155 		"05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
    156 			"ffffffffffffffffff07f00f",
    157 		"fail",
    158 	}, {
    159 		"complete HCLenTree, under-subscribed HLitTree, empty HDistTree",
    160 		"05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
    161 			"fffffffffcffffffff07f00f",
    162 		"fail",
    163 	}, {
    164 		"complete HCLenTree, complete HLitTree with single code, empty HDistTree",
    165 		"05e001240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
    166 			"ffffffffffffffffff07f00f",
    167 		"01",
    168 	}, {
    169 		"complete HCLenTree, complete HLitTree with multiple codes, empty HDistTree",
    170 		"05e301240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
    171 			"ffffffffffffffffff07807f",
    172 		"01",
    173 	}, {
    174 		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HDist symbol",
    175 		"000100feff000de0010400000000100000000000000000000000000000000000" +
    176 			"0000000000000000000000000000003c",
    177 		"00000000",
    178 	}, {
    179 		"complete HCLenTree, degenerate HLitTree, degenerate HDistTree",
    180 		"05e0010400000000100000000000000000000000000000000000000000000000" +
    181 			"0000000000000000000c",
    182 		"",
    183 	}, {
    184 		"complete HCLenTree, degenerate HLitTree, empty HDistTree",
    185 		"05e0010400000000100000000000000000000000000000000000000000000000" +
    186 			"00000000000000000004",
    187 		"",
    188 	}, {
    189 		"complete HCLenTree, complete HLitTree, empty HDistTree, spanning repeater code",
    190 		"edfd870500000000200400000000000000000000000000000000000000000000" +
    191 			"000000000000000000e8b000",
    192 		"",
    193 	}, {
    194 		"complete HCLenTree with length codes, complete HLitTree, empty HDistTree",
    195 		"ede0010400000000100000000000000000000000000000000000000000000000" +
    196 			"0000000000000000000400004000",
    197 		"",
    198 	}, {
    199 		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit symbol 284 with count 31",
    200 		"000100feff00ede0010400000000100000000000000000000000000000000000" +
    201 			"000000000000000000000000000000040000407f00",
    202 		"0000000000000000000000000000000000000000000000000000000000000000" +
    203 			"0000000000000000000000000000000000000000000000000000000000000000" +
    204 			"0000000000000000000000000000000000000000000000000000000000000000" +
    205 			"0000000000000000000000000000000000000000000000000000000000000000" +
    206 			"0000000000000000000000000000000000000000000000000000000000000000" +
    207 			"0000000000000000000000000000000000000000000000000000000000000000" +
    208 			"0000000000000000000000000000000000000000000000000000000000000000" +
    209 			"0000000000000000000000000000000000000000000000000000000000000000" +
    210 			"000000",
    211 	}, {
    212 		"complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit and HDist symbols",
    213 		"0cc2010d00000082b0ac4aff0eb07d27060000ffff",
    214 		"616263616263",
    215 	}, {
    216 		"fixed block, use reserved symbol 287",
    217 		"33180700",
    218 		"fail",
    219 	}, {
    220 		"raw block",
    221 		"010100feff11",
    222 		"11",
    223 	}, {
    224 		"issue 10426 - over-subscribed HCLenTree causes a hang",
    225 		"344c4a4e494d4b070000ff2e2eff2e2e2e2e2eff",
    226 		"fail",
    227 	}, {
    228 		"issue 11030 - empty HDistTree unexpectedly leads to error",
    229 		"05c0070600000080400fff37a0ca",
    230 		"",
    231 	}, {
    232 		"issue 11033 - empty HDistTree unexpectedly leads to error",
    233 		"050fb109c020cca5d017dcbca044881ee1034ec149c8980bbc413c2ab35be9dc" +
    234 			"b1473449922449922411202306ee97b0383a521b4ffdcf3217f9f7d3adb701",
    235 		"3130303634342068652e706870005d05355f7ed957ff084a90925d19e3ebc6d0" +
    236 			"c6d7",
    237 	}}
    238 
    239 	for i, tc := range testCases {
    240 		data, err := hex.DecodeString(tc.stream)
    241 		if err != nil {
    242 			t.Fatal(err)
    243 		}
    244 		data, err = ioutil.ReadAll(NewReader(bytes.NewReader(data)))
    245 		if tc.want == "fail" {
    246 			if err == nil {
    247 				t.Errorf("#%d (%s): got nil error, want non-nil", i, tc.desc)
    248 			}
    249 		} else {
    250 			if err != nil {
    251 				t.Errorf("#%d (%s): %v", i, tc.desc, err)
    252 				continue
    253 			}
    254 			if got := hex.EncodeToString(data); got != tc.want {
    255 				t.Errorf("#%d (%s):\ngot  %q\nwant %q", i, tc.desc, got, tc.want)
    256 			}
    257 
    258 		}
    259 	}
    260 }
    261