1
2
3
4
5
6
7
8
9 package flate
10
11 import (
12 "archive/zip"
13 "bytes"
14 "compress/flate"
15 "encoding/hex"
16 "fmt"
17 "io"
18 "os"
19 "testing"
20 )
21
22
23 func TestIssue5915(t *testing.T) {
24 bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0, 5, 5, 6,
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 0, 11, 0, 8, 0, 6, 6, 10, 8}
27 var h huffmanDecoder
28 if h.init(bits) {
29 t.Fatalf("Given sequence of bits is bad, and should not succeed.")
30 }
31 }
32
33
34 func TestIssue5962(t *testing.T) {
35 bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0,
36 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11}
37 var h huffmanDecoder
38 if h.init(bits) {
39 t.Fatalf("Given sequence of bits is bad, and should not succeed.")
40 }
41 }
42
43
44 func TestIssue6255(t *testing.T) {
45 bits1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11}
46 bits2 := []int{11, 13}
47 var h huffmanDecoder
48 if !h.init(bits1) {
49 t.Fatalf("Given sequence of bits is good and should succeed.")
50 }
51 if h.init(bits2) {
52 t.Fatalf("Given sequence of bits is bad and should not succeed.")
53 }
54 }
55
56 func TestInvalidEncoding(t *testing.T) {
57
58 var h huffmanDecoder
59 if !h.init([]int{1}) {
60 t.Fatal("Failed to initialize Huffman decoder")
61 }
62
63
64 var f decompressor
65 f.r = bytes.NewReader([]byte{0xff})
66
67 _, err := f.huffSym(&h)
68 if err == nil {
69 t.Fatal("Should have rejected invalid bit sequence")
70 }
71 }
72
73 func TestRegressions(t *testing.T) {
74
75 data, err := os.ReadFile("testdata/regression.zip")
76 if err != nil {
77 t.Fatal(err)
78 }
79 zr, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
80 if err != nil {
81 t.Fatal(err)
82 }
83 for _, tt := range zr.File {
84 data, err := tt.Open()
85 if err != nil {
86 t.Fatal(err)
87 }
88 data1, err := io.ReadAll(data)
89 if err != nil {
90 t.Fatal(err)
91 }
92 t.Run(tt.Name, func(t *testing.T) {
93 if testing.Short() && len(data1) > 10000 {
94 t.SkipNow()
95 }
96 for level := 0; level <= 9; level++ {
97 t.Run(fmt.Sprint(tt.Name+"-level", 1), func(t *testing.T) {
98 buf := new(bytes.Buffer)
99 fw, err := NewWriter(buf, level)
100 if err != nil {
101 t.Error(err)
102 }
103 n, err := fw.Write(data1)
104 if n != len(data1) {
105 t.Error("short write")
106 }
107 if err != nil {
108 t.Error(err)
109 }
110 err = fw.Close()
111 if err != nil {
112 t.Error(err)
113 }
114 fr1 := NewReader(buf)
115 data2, err := io.ReadAll(fr1)
116 if err != nil {
117 t.Error(err)
118 }
119 if !bytes.Equal(data1, data2) {
120 t.Error("not equal")
121 }
122
123 buf.Reset()
124 fw.Reset(buf)
125 n, err = fw.Write(data1)
126 if n != len(data1) {
127 t.Error("short write")
128 }
129 if err != nil {
130 t.Error(err)
131 }
132 err = fw.Close()
133 if err != nil {
134 t.Error(err)
135 }
136 fr1 = flate.NewReader(buf)
137 data2, err = io.ReadAll(fr1)
138 if err != nil {
139 t.Error(err)
140 }
141 if !bytes.Equal(data1, data2) {
142 t.Error("not equal")
143 }
144 })
145 }
146 t.Run(tt.Name+"stateless", func(t *testing.T) {
147
148 buf := new(bytes.Buffer)
149 err = StatelessDeflate(buf, data1[:len(data1)/2], false, nil)
150 if err != nil {
151 t.Error(err)
152 }
153
154
155 dict := data1[:len(data1)/2]
156 err = StatelessDeflate(buf, data1[len(data1)/2:], true, dict)
157 if err != nil {
158 t.Error(err)
159 }
160 t.Log(buf.Len())
161 fr1 := NewReader(buf)
162 data2, err := io.ReadAll(fr1)
163 if err != nil {
164 t.Error(err)
165 }
166 if !bytes.Equal(data1, data2) {
167
168 t.Error("not equal")
169 }
170 })
171 })
172 }
173 }
174
175 func TestInvalidBits(t *testing.T) {
176 oversubscribed := []int{1, 2, 3, 4, 4, 5}
177 incomplete := []int{1, 2, 4, 4}
178 var h huffmanDecoder
179 if h.init(oversubscribed) {
180 t.Fatal("Should reject oversubscribed bit-length set")
181 }
182 if h.init(incomplete) {
183 t.Fatal("Should reject incomplete bit-length set")
184 }
185 }
186
187 func TestStreams(t *testing.T) {
188
189
190
191
192
193
194
195 testCases := []struct {
196 desc string
197 stream string
198 want string
199 }{{
200 "degenerate HCLenTree",
201 "05e0010000000000100000000000000000000000000000000000000000000000" +
202 "00000000000000000004",
203 "fail",
204 }, {
205 "complete HCLenTree, empty HLitTree, empty HDistTree",
206 "05e0010400000000000000000000000000000000000000000000000000000000" +
207 "00000000000000000010",
208 "fail",
209 }, {
210 "empty HCLenTree",
211 "05e0010000000000000000000000000000000000000000000000000000000000" +
212 "00000000000000000010",
213 "fail",
214 }, {
215 "complete HCLenTree, complete HLitTree, empty HDistTree, use missing HDist symbol",
216 "000100feff000de0010400000000100000000000000000000000000000000000" +
217 "0000000000000000000000000000002c",
218 "fail",
219 }, {
220 "complete HCLenTree, complete HLitTree, degenerate HDistTree, use missing HDist symbol",
221 "000100feff000de0010000000000000000000000000000000000000000000000" +
222 "00000000000000000610000000004070",
223 "fail",
224 }, {
225 "complete HCLenTree, empty HLitTree, empty HDistTree",
226 "05e0010400000000100400000000000000000000000000000000000000000000" +
227 "0000000000000000000000000008",
228 "fail",
229 }, {
230 "complete HCLenTree, empty HLitTree, degenerate HDistTree",
231 "05e0010400000000100400000000000000000000000000000000000000000000" +
232 "0000000000000000000800000008",
233 "fail",
234 }, {
235 "complete HCLenTree, degenerate HLitTree, degenerate HDistTree, use missing HLit symbol",
236 "05e0010400000000100000000000000000000000000000000000000000000000" +
237 "0000000000000000001c",
238 "fail",
239 }, {
240 "complete HCLenTree, complete HLitTree, too large HDistTree",
241 "edff870500000000200400000000000000000000000000000000000000000000" +
242 "000000000000000000080000000000000004",
243 "fail",
244 }, {
245 "complete HCLenTree, complete HLitTree, empty HDistTree, excessive repeater code",
246 "edfd870500000000200400000000000000000000000000000000000000000000" +
247 "000000000000000000e8b100",
248 "fail",
249 }, {
250 "complete HCLenTree, complete HLitTree, empty HDistTree of normal length 30",
251 "05fd01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
252 "ffffffffffffffffff07000000fe01",
253 "",
254 }, {
255 "complete HCLenTree, complete HLitTree, empty HDistTree of excessive length 31",
256 "05fe01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
257 "ffffffffffffffffff07000000fc03",
258 "fail",
259 }, {
260 "complete HCLenTree, over-subscribed HLitTree, empty HDistTree",
261 "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
262 "ffffffffffffffffff07f00f",
263 "fail",
264 }, {
265 "complete HCLenTree, under-subscribed HLitTree, empty HDistTree",
266 "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
267 "fffffffffcffffffff07f00f",
268 "fail",
269 }, {
270 "complete HCLenTree, complete HLitTree with single code, empty HDistTree",
271 "05e001240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
272 "ffffffffffffffffff07f00f",
273 "01",
274 }, {
275 "complete HCLenTree, complete HLitTree with multiple codes, empty HDistTree",
276 "05e301240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
277 "ffffffffffffffffff07807f",
278 "01",
279 }, {
280 "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HDist symbol",
281 "000100feff000de0010400000000100000000000000000000000000000000000" +
282 "0000000000000000000000000000003c",
283 "00000000",
284 }, {
285 "complete HCLenTree, degenerate HLitTree, degenerate HDistTree",
286 "05e0010400000000100000000000000000000000000000000000000000000000" +
287 "0000000000000000000c",
288 "",
289 }, {
290 "complete HCLenTree, degenerate HLitTree, empty HDistTree",
291 "05e0010400000000100000000000000000000000000000000000000000000000" +
292 "00000000000000000004",
293 "",
294 }, {
295 "complete HCLenTree, complete HLitTree, empty HDistTree, spanning repeater code",
296 "edfd870500000000200400000000000000000000000000000000000000000000" +
297 "000000000000000000e8b000",
298 "",
299 }, {
300 "complete HCLenTree with length codes, complete HLitTree, empty HDistTree",
301 "ede0010400000000100000000000000000000000000000000000000000000000" +
302 "0000000000000000000400004000",
303 "",
304 }, {
305 "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit symbol 284 with count 31",
306 "000100feff00ede0010400000000100000000000000000000000000000000000" +
307 "000000000000000000000000000000040000407f00",
308 "0000000000000000000000000000000000000000000000000000000000000000" +
309 "0000000000000000000000000000000000000000000000000000000000000000" +
310 "0000000000000000000000000000000000000000000000000000000000000000" +
311 "0000000000000000000000000000000000000000000000000000000000000000" +
312 "0000000000000000000000000000000000000000000000000000000000000000" +
313 "0000000000000000000000000000000000000000000000000000000000000000" +
314 "0000000000000000000000000000000000000000000000000000000000000000" +
315 "0000000000000000000000000000000000000000000000000000000000000000" +
316 "000000",
317 }, {
318 "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit and HDist symbols",
319 "0cc2010d00000082b0ac4aff0eb07d27060000ffff",
320 "616263616263",
321 }, {
322 "fixed block, use reserved symbol 287",
323 "33180700",
324 "fail",
325 }, {
326 "raw block",
327 "010100feff11",
328 "11",
329 }, {
330 "issue 10426 - over-subscribed HCLenTree causes a hang",
331 "344c4a4e494d4b070000ff2e2eff2e2e2e2e2eff",
332 "fail",
333 }, {
334 "issue 11030 - empty HDistTree unexpectedly leads to error",
335 "05c0070600000080400fff37a0ca",
336 "",
337 }, {
338 "issue 11033 - empty HDistTree unexpectedly leads to error",
339 "050fb109c020cca5d017dcbca044881ee1034ec149c8980bbc413c2ab35be9dc" +
340 "b1473449922449922411202306ee97b0383a521b4ffdcf3217f9f7d3adb701",
341 "3130303634342068652e706870005d05355f7ed957ff084a90925d19e3ebc6d0" +
342 "c6d7",
343 }}
344
345 for i, tc := range testCases {
346 data, err := hex.DecodeString(tc.stream)
347 if err != nil {
348 t.Fatal(err)
349 }
350 data, err = io.ReadAll(NewReader(bytes.NewReader(data)))
351 if tc.want == "fail" {
352 if err == nil {
353 t.Errorf("#%d (%s): got nil error, want non-nil", i, tc.desc)
354 }
355 } else {
356 if err != nil {
357 t.Errorf("#%d (%s): %v", i, tc.desc, err)
358 continue
359 }
360 if got := hex.EncodeToString(data); got != tc.want {
361 t.Errorf("#%d (%s):\ngot %q\nwant %q", i, tc.desc, got, tc.want)
362 }
363
364 }
365 }
366 }
367
View as plain text