1
2
3
4
5 package gzip
6
7 import (
8 "bytes"
9 "compress/flate"
10 "encoding/base64"
11 "io"
12 "os"
13 "strings"
14 "testing"
15 "time"
16 )
17
18 type gunzipTest struct {
19 name string
20 desc string
21 raw string
22 gzip []byte
23 err error
24 }
25
26 var gunzipTests = []gunzipTest{
27 {
28 "empty.txt",
29 "empty.txt",
30 "",
31 []byte{
32 0x1f, 0x8b, 0x08, 0x08, 0xf7, 0x5e, 0x14, 0x4a,
33 0x00, 0x03, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
34 0x74, 0x78, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 },
37 nil,
38 },
39 {
40 "",
41 "empty - with no file name",
42 "",
43 []byte{
44 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88,
45 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 },
48 nil,
49 },
50 {
51 "hello.txt",
52 "hello.txt",
53 "hello world\n",
54 []byte{
55 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
56 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
57 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
58 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
59 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
60 0x00, 0x00,
61 },
62 nil,
63 },
64 {
65 "hello.txt",
66 "hello.txt x2",
67 "hello world\n" +
68 "hello world\n",
69 []byte{
70 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
71 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
72 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
73 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
74 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
75 0x00, 0x00,
76 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
77 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
78 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
79 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
80 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
81 0x00, 0x00,
82 },
83 nil,
84 },
85 {
86 "shesells.txt",
87 "shesells.txt",
88 "she sells seashells by the seashore\n",
89 []byte{
90 0x1f, 0x8b, 0x08, 0x08, 0x72, 0x66, 0x8b, 0x4a,
91 0x00, 0x03, 0x73, 0x68, 0x65, 0x73, 0x65, 0x6c,
92 0x6c, 0x73, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x2b,
93 0xce, 0x48, 0x55, 0x28, 0x4e, 0xcd, 0xc9, 0x29,
94 0x06, 0x92, 0x89, 0xc5, 0x19, 0x60, 0x56, 0x52,
95 0xa5, 0x42, 0x09, 0x58, 0x18, 0x28, 0x90, 0x5f,
96 0x94, 0xca, 0x05, 0x00, 0x76, 0xb0, 0x3b, 0xeb,
97 0x24, 0x00, 0x00, 0x00,
98 },
99 nil,
100 },
101 {
102 "gettysburg",
103 "gettysburg",
104 " Four score and seven years ago our fathers brought forth on\n" +
105 "this continent, a new nation, conceived in Liberty, and dedicated\n" +
106 "to the proposition that all men are created equal.\n" +
107 " Now we are engaged in a great Civil War, testing whether that\n" +
108 "nation, or any nation so conceived and so dedicated, can long\n" +
109 "endure.\n" +
110 " We are met on a great battle-field of that war.\n" +
111 " We have come to dedicate a portion of that field, as a final\n" +
112 "resting place for those who here gave their lives that that\n" +
113 "nation might live. It is altogether fitting and proper that\n" +
114 "we should do this.\n" +
115 " But, in a larger sense, we can not dedicate — we can not\n" +
116 "consecrate — we can not hallow — this ground.\n" +
117 " The brave men, living and dead, who struggled here, have\n" +
118 "consecrated it, far above our poor power to add or detract.\n" +
119 "The world will little note, nor long remember what we say here,\n" +
120 "but it can never forget what they did here.\n" +
121 " It is for us the living, rather, to be dedicated here to the\n" +
122 "unfinished work which they who fought here have thus far so\n" +
123 "nobly advanced. It is rather for us to be here dedicated to\n" +
124 "the great task remaining before us — that from these honored\n" +
125 "dead we take increased devotion to that cause for which they\n" +
126 "gave the last full measure of devotion —\n" +
127 " that we here highly resolve that these dead shall not have\n" +
128 "died in vain — that this nation, under God, shall have a new\n" +
129 "birth of freedom — and that government of the people, by the\n" +
130 "people, for the people, shall not perish from this earth.\n" +
131 "\n" +
132 "Abraham Lincoln, November 19, 1863, Gettysburg, Pennsylvania\n",
133 []byte{
134 0x1f, 0x8b, 0x08, 0x08, 0xd1, 0x12, 0x2b, 0x4a,
135 0x00, 0x03, 0x67, 0x65, 0x74, 0x74, 0x79, 0x73,
136 0x62, 0x75, 0x72, 0x67, 0x00, 0x65, 0x54, 0xcd,
137 0x6e, 0xd4, 0x30, 0x10, 0xbe, 0xfb, 0x29, 0xe6,
138 0x01, 0x42, 0xa5, 0x0a, 0x09, 0xc1, 0x11, 0x90,
139 0x40, 0x48, 0xa8, 0xe2, 0x80, 0xd4, 0xf3, 0x24,
140 0x9e, 0x24, 0x56, 0xbd, 0x9e, 0xc5, 0x76, 0x76,
141 0x95, 0x1b, 0x0f, 0xc1, 0x13, 0xf2, 0x24, 0x7c,
142 0x63, 0x77, 0x9b, 0x4a, 0x5c, 0xaa, 0x6e, 0x6c,
143 0xcf, 0x7c, 0x7f, 0x33, 0x44, 0x5f, 0x74, 0xcb,
144 0x54, 0x26, 0xcd, 0x42, 0x9c, 0x3c, 0x15, 0xb9,
145 0x48, 0xa2, 0x5d, 0x38, 0x17, 0xe2, 0x45, 0xc9,
146 0x4e, 0x67, 0xae, 0xab, 0xe0, 0xf7, 0x98, 0x75,
147 0x5b, 0xd6, 0x4a, 0xb3, 0xe6, 0xba, 0x92, 0x26,
148 0x57, 0xd7, 0x50, 0x68, 0xd2, 0x54, 0x43, 0x92,
149 0x54, 0x07, 0x62, 0x4a, 0x72, 0xa5, 0xc4, 0x35,
150 0x68, 0x1a, 0xec, 0x60, 0x92, 0x70, 0x11, 0x4f,
151 0x21, 0xd1, 0xf7, 0x30, 0x4a, 0xae, 0xfb, 0xd0,
152 0x9a, 0x78, 0xf1, 0x61, 0xe2, 0x2a, 0xde, 0x55,
153 0x25, 0xd4, 0xa6, 0x73, 0xd6, 0xb3, 0x96, 0x60,
154 0xef, 0xf0, 0x9b, 0x2b, 0x71, 0x8c, 0x74, 0x02,
155 0x10, 0x06, 0xac, 0x29, 0x8b, 0xdd, 0x25, 0xf9,
156 0xb5, 0x71, 0xbc, 0x73, 0x44, 0x0f, 0x7a, 0xa5,
157 0xab, 0xb4, 0x33, 0x49, 0x0b, 0x2f, 0xbd, 0x03,
158 0xd3, 0x62, 0x17, 0xe9, 0x73, 0xb8, 0x84, 0x48,
159 0x8f, 0x9c, 0x07, 0xaa, 0x52, 0x00, 0x6d, 0xa1,
160 0xeb, 0x2a, 0xc6, 0xa0, 0x95, 0x76, 0x37, 0x78,
161 0x9a, 0x81, 0x65, 0x7f, 0x46, 0x4b, 0x45, 0x5f,
162 0xe1, 0x6d, 0x42, 0xe8, 0x01, 0x13, 0x5c, 0x38,
163 0x51, 0xd4, 0xb4, 0x38, 0x49, 0x7e, 0xcb, 0x62,
164 0x28, 0x1e, 0x3b, 0x82, 0x93, 0x54, 0x48, 0xf1,
165 0xd2, 0x7d, 0xe4, 0x5a, 0xa3, 0xbc, 0x99, 0x83,
166 0x44, 0x4f, 0x3a, 0x77, 0x36, 0x57, 0xce, 0xcf,
167 0x2f, 0x56, 0xbe, 0x80, 0x90, 0x9e, 0x84, 0xea,
168 0x51, 0x1f, 0x8f, 0xcf, 0x90, 0xd4, 0x60, 0xdc,
169 0x5e, 0xb4, 0xf7, 0x10, 0x0b, 0x26, 0xe0, 0xff,
170 0xc4, 0xd1, 0xe5, 0x67, 0x2e, 0xe7, 0xc8, 0x93,
171 0x98, 0x05, 0xb8, 0xa8, 0x45, 0xc0, 0x4d, 0x09,
172 0xdc, 0x84, 0x16, 0x2b, 0x0d, 0x9a, 0x21, 0x53,
173 0x04, 0x8b, 0xd2, 0x0b, 0xbd, 0xa2, 0x4c, 0xa7,
174 0x60, 0xee, 0xd9, 0xe1, 0x1d, 0xd1, 0xb7, 0x4a,
175 0x30, 0x8f, 0x63, 0xd5, 0xa5, 0x8b, 0x33, 0x87,
176 0xda, 0x1a, 0x18, 0x79, 0xf3, 0xe3, 0xa6, 0x17,
177 0x94, 0x2e, 0xab, 0x6e, 0xa0, 0xe3, 0xcd, 0xac,
178 0x50, 0x8c, 0xca, 0xa7, 0x0d, 0x76, 0x37, 0xd1,
179 0x23, 0xe7, 0x05, 0x57, 0x8b, 0xa4, 0x22, 0x83,
180 0xd9, 0x62, 0x52, 0x25, 0xad, 0x07, 0xbb, 0xbf,
181 0xbf, 0xff, 0xbc, 0xfa, 0xee, 0x20, 0x73, 0x91,
182 0x29, 0xff, 0x7f, 0x02, 0x71, 0x62, 0x84, 0xb5,
183 0xf6, 0xb5, 0x25, 0x6b, 0x41, 0xde, 0x92, 0xb7,
184 0x76, 0x3f, 0x91, 0x91, 0x31, 0x1b, 0x41, 0x84,
185 0x62, 0x30, 0x0a, 0x37, 0xa4, 0x5e, 0x18, 0x3a,
186 0x99, 0x08, 0xa5, 0xe6, 0x6d, 0x59, 0x22, 0xec,
187 0x33, 0x39, 0x86, 0x26, 0xf5, 0xab, 0x66, 0xc8,
188 0x08, 0x20, 0xcf, 0x0c, 0xd7, 0x47, 0x45, 0x21,
189 0x0b, 0xf6, 0x59, 0xd5, 0xfe, 0x5c, 0x8d, 0xaa,
190 0x12, 0x7b, 0x6f, 0xa1, 0xf0, 0x52, 0x33, 0x4f,
191 0xf5, 0xce, 0x59, 0xd3, 0xab, 0x66, 0x10, 0xbf,
192 0x06, 0xc4, 0x31, 0x06, 0x73, 0xd6, 0x80, 0xa2,
193 0x78, 0xc2, 0x45, 0xcb, 0x03, 0x65, 0x39, 0xc9,
194 0x09, 0xd1, 0x06, 0x04, 0x33, 0x1a, 0x5a, 0xf1,
195 0xde, 0x01, 0xb8, 0x71, 0x83, 0xc4, 0xb5, 0xb3,
196 0xc3, 0x54, 0x65, 0x33, 0x0d, 0x5a, 0xf7, 0x9b,
197 0x90, 0x7c, 0x27, 0x1f, 0x3a, 0x58, 0xa3, 0xd8,
198 0xfd, 0x30, 0x5f, 0xb7, 0xd2, 0x66, 0xa2, 0x93,
199 0x1c, 0x28, 0xb7, 0xe9, 0x1b, 0x0c, 0xe1, 0x28,
200 0x47, 0x26, 0xbb, 0xe9, 0x7d, 0x7e, 0xdc, 0x96,
201 0x10, 0x92, 0x50, 0x56, 0x7c, 0x06, 0xe2, 0x27,
202 0xb4, 0x08, 0xd3, 0xda, 0x7b, 0x98, 0x34, 0x73,
203 0x9f, 0xdb, 0xf6, 0x62, 0xed, 0x31, 0x41, 0x13,
204 0xd3, 0xa2, 0xa8, 0x4b, 0x3a, 0xc6, 0x1d, 0xe4,
205 0x2f, 0x8c, 0xf8, 0xfb, 0x97, 0x64, 0xf4, 0xb6,
206 0x2f, 0x80, 0x5a, 0xf3, 0x56, 0xe0, 0x40, 0x50,
207 0xd5, 0x19, 0xd0, 0x1e, 0xfc, 0xca, 0xe5, 0xc9,
208 0xd4, 0x60, 0x00, 0x81, 0x2e, 0xa3, 0xcc, 0xb6,
209 0x52, 0xf0, 0xb4, 0xdb, 0x69, 0x99, 0xce, 0x7a,
210 0x32, 0x4c, 0x08, 0xed, 0xaa, 0x10, 0x10, 0xe3,
211 0x6f, 0xee, 0x99, 0x68, 0x95, 0x9f, 0x04, 0x71,
212 0xb2, 0x49, 0x2f, 0x62, 0xa6, 0x5e, 0xb4, 0xef,
213 0x02, 0xed, 0x4f, 0x27, 0xde, 0x4a, 0x0f, 0xfd,
214 0xc1, 0xcc, 0xdd, 0x02, 0x8f, 0x08, 0x16, 0x54,
215 0xdf, 0xda, 0xca, 0xe0, 0x82, 0xf1, 0xb4, 0x31,
216 0x7a, 0xa9, 0x81, 0xfe, 0x90, 0xb7, 0x3e, 0xdb,
217 0xd3, 0x35, 0xc0, 0x20, 0x80, 0x33, 0x46, 0x4a,
218 0x63, 0xab, 0xd1, 0x0d, 0x29, 0xd2, 0xe2, 0x84,
219 0xb8, 0xdb, 0xfa, 0xe9, 0x89, 0x44, 0x86, 0x7c,
220 0xe8, 0x0b, 0xe6, 0x02, 0x6a, 0x07, 0x9b, 0x96,
221 0xd0, 0xdb, 0x2e, 0x41, 0x4c, 0xa1, 0xd5, 0x57,
222 0x45, 0x14, 0xfb, 0xe3, 0xa6, 0x72, 0x5b, 0x87,
223 0x6e, 0x0c, 0x6d, 0x5b, 0xce, 0xe0, 0x2f, 0xe2,
224 0x21, 0x81, 0x95, 0xb0, 0xe8, 0xb6, 0x32, 0x0b,
225 0xb2, 0x98, 0x13, 0x52, 0x5d, 0xfb, 0xec, 0x63,
226 0x17, 0x8a, 0x9e, 0x23, 0x22, 0x36, 0xee, 0xcd,
227 0xda, 0xdb, 0xcf, 0x3e, 0xf1, 0xc7, 0xf1, 0x01,
228 0x12, 0x93, 0x0a, 0xeb, 0x6f, 0xf2, 0x02, 0x15,
229 0x96, 0x77, 0x5d, 0xef, 0x9c, 0xfb, 0x88, 0x91,
230 0x59, 0xf9, 0x84, 0xdd, 0x9b, 0x26, 0x8d, 0x80,
231 0xf9, 0x80, 0x66, 0x2d, 0xac, 0xf7, 0x1f, 0x06,
232 0xba, 0x7f, 0xff, 0xee, 0xed, 0x40, 0x5f, 0xa5,
233 0xd6, 0xbd, 0x8c, 0x5b, 0x46, 0xd2, 0x7e, 0x48,
234 0x4a, 0x65, 0x8f, 0x08, 0x42, 0x60, 0xf7, 0x0f,
235 0xb9, 0x16, 0x0b, 0x0c, 0x1a, 0x06, 0x00, 0x00,
236 },
237 nil,
238 },
239 {
240 "hello.txt",
241 "hello.txt + garbage",
242 "hello world\n",
243 []byte{
244 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
245 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
246 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
247 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
248 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
249 0x00, 0x00, 'g', 'a', 'r', 'b', 'a', 'g', 'e', '!', '!', '!',
250 },
251 ErrHeader,
252 },
253 {
254 "hello.txt",
255 "hello.txt + garbage",
256 "hello world\n",
257 []byte{
258 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
259 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
260 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
261 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
262 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
263 0x00, 0x00, gzipID1,
264 },
265 io.ErrUnexpectedEOF,
266 },
267 {
268 "hello.txt",
269 "hello.txt + corrupt checksum",
270 "hello world\n",
271 []byte{
272 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
273 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
274 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
275 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
276 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00,
277 0x00, 0x00,
278 },
279 ErrChecksum,
280 },
281 {
282 "hello.txt",
283 "hello.txt + corrupt size",
284 "hello world\n",
285 []byte{
286 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
287 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
288 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
289 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
290 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0xff, 0x00,
291 0x00, 0x00,
292 },
293 ErrChecksum,
294 },
295 {
296 "f1l3n4m3.tXt",
297 "header with all fields used",
298 "",
299 []byte{
300 0x1f, 0x8b, 0x08, 0x1e, 0x70, 0xf0, 0xf9, 0x4a,
301 0x00, 0xaa, 0x09, 0x00, 0x7a, 0x7a, 0x05, 0x00,
302 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x31, 0x6c,
303 0x33, 0x6e, 0x34, 0x6d, 0x33, 0x2e, 0x74, 0x58,
304 0x74, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
305 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
306 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
307 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
308 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
309 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
310 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
311 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
312 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
313 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
314 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
315 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
316 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
317 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
318 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
319 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
320 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
321 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
322 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
323 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
324 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
325 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
326 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
327 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
328 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
329 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
330 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
331 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
332 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
333 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
334 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
335 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
336 0xff, 0x00, 0x92, 0xfd, 0x01, 0x00, 0x00, 0xff,
337 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00,
339 },
340 nil,
341 },
342 {
343 "",
344 "truncated gzip file amid raw-block",
345 "hello",
346 []byte{
347 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
348 0x00, 0x0c, 0x00, 0xf3, 0xff, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
349 },
350 io.ErrUnexpectedEOF,
351 },
352 {
353 "",
354 "truncated gzip file amid fixed-block",
355 "He",
356 []byte{
357 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
358 0xf2, 0x48, 0xcd,
359 },
360 io.ErrUnexpectedEOF,
361 },
362 {
363 "hello.txt",
364 "gzip header with truncated name",
365 "hello world\n",
366 []byte{
367 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
368 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
369 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
370 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
371 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
372 0x00, 0x00,
373 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0xff, 0x01,
375 },
376 io.ErrUnexpectedEOF,
377 },
378 {
379 "",
380 "gzip header with truncated comment",
381 "hello world\n",
382 []byte{
383 0x1f, 0x8b, 0x08, 0x10, 0xc8, 0x58, 0x13, 0x4a,
384 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
385 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
386 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
387 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
388 0x00, 0x00,
389 0x1f, 0x8b, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0xff, 0x01,
391 },
392 io.ErrUnexpectedEOF,
393 },
394 }
395
396 func TestDecompressor(t *testing.T) {
397
398
399
400 r1 := new(Reader)
401
402 b := new(bytes.Buffer)
403 for _, tt := range gunzipTests {
404
405 in := bytes.NewReader(tt.gzip)
406 r2, err := NewReader(in)
407 if err != nil {
408 t.Errorf("%s: NewReader: %s", tt.desc, err)
409 continue
410 }
411 defer r2.Close()
412 if tt.name != r2.Name {
413 t.Errorf("%s: got name %s", tt.desc, r2.Name)
414 }
415 b.Reset()
416 n, err := io.Copy(b, r2)
417 if err != tt.err {
418 t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
419 }
420 s := b.String()
421 if s != tt.raw {
422 t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
423 }
424
425
426 in = bytes.NewReader(tt.gzip)
427 err = r1.Reset(in)
428 if err != nil {
429 t.Errorf("%s: Reset: %s", tt.desc, err)
430 continue
431 }
432 if tt.name != r1.Name {
433 t.Errorf("%s: got name %s", tt.desc, r1.Name)
434 }
435 b.Reset()
436 n, err = io.Copy(b, r1)
437 if err != tt.err {
438 t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
439 }
440 s = b.String()
441 if s != tt.raw {
442 t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
443 }
444 }
445 }
446
447 func TestIssue6550(t *testing.T) {
448
449
450
451
452
453 f, err := os.Open("testdata/issue6550.gz.base64")
454 if err != nil {
455 t.Fatal(err)
456 }
457 gzip, err := NewReader(base64.NewDecoder(base64.StdEncoding, f))
458 if err != nil {
459 t.Fatalf("NewReader(testdata/issue6550.gz): %v", err)
460 }
461 defer gzip.Close()
462 done := make(chan bool, 1)
463 go func() {
464 _, err := io.Copy(io.Discard, gzip)
465 if err == nil {
466 t.Errorf("Copy succeeded")
467 } else {
468 t.Logf("Copy failed (correctly): %v", err)
469 }
470 done <- true
471 }()
472 select {
473 case <-time.After(1 * time.Second):
474 t.Errorf("Copy hung")
475 case <-done:
476
477 }
478 }
479
480 func TestMultistreamFalse(t *testing.T) {
481
482 var tt gunzipTest
483 for _, tt = range gunzipTests {
484 if strings.HasSuffix(tt.desc, " x2") {
485 goto Found
486 }
487 }
488 t.Fatal("cannot find hello.txt x2 in gunzip tests")
489
490 Found:
491 br := bytes.NewReader(tt.gzip)
492 var r Reader
493 if err := r.Reset(br); err != nil {
494 t.Fatalf("first reset: %v", err)
495 }
496
497
498 const hello = "hello world\n"
499
500 r.Multistream(false)
501 data, err := io.ReadAll(&r)
502 if string(data) != hello || err != nil {
503 t.Fatalf("first stream = %q, %v, want %q, %v", string(data), err, hello, nil)
504 }
505
506 if err := r.Reset(br); err != nil {
507 t.Fatalf("second reset: %v", err)
508 }
509 r.Multistream(false)
510 data, err = io.ReadAll(&r)
511 if string(data) != hello || err != nil {
512 t.Fatalf("second stream = %q, %v, want %q, %v", string(data), err, hello, nil)
513 }
514
515 if err := r.Reset(br); err != io.EOF {
516 t.Fatalf("third reset: err=%v, want io.EOF", err)
517 }
518 }
519
520 func TestNilStream(t *testing.T) {
521
522
523 _, err := NewReader(bytes.NewReader(nil))
524 if err != io.EOF {
525 t.Fatalf("NewReader(nil) on empty stream: got %v, want io.EOF", err)
526 }
527 }
528
529 func TestTruncatedStreams(t *testing.T) {
530 cases := []struct {
531 name string
532 data []byte
533 }{
534 {
535 name: "original",
536 data: []byte("\x1f\x8b\b\x04\x00\tn\x88\x00\xff\a\x00foo bar\xcbH\xcd\xc9\xc9\xd7Q(\xcf/\xcaI\x01\x04:r\xab\xff\f\x00\x00\x00"),
537 },
538 {
539 name: "truncated name",
540 data: []byte{
541 0x1f, 0x8b, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01,
542 },
543 },
544 {
545 name: "truncated comment",
546 data: []byte{
547 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01,
548 },
549 },
550 }
551
552
553 for _, tc := range cases {
554 for i := 1; i < len(tc.data); i++ {
555 r, err := NewReader(strings.NewReader(string(tc.data[:i])))
556 if err != nil {
557 if err != io.ErrUnexpectedEOF {
558 t.Errorf("NewReader(%s-%d) on truncated stream: got %v, want %v", tc.name, i, err, io.ErrUnexpectedEOF)
559 }
560 continue
561 }
562 _, err = io.Copy(io.Discard, r)
563 if ferr, ok := err.(*flate.ReadError); ok {
564 err = ferr.Err
565 }
566 if err != io.ErrUnexpectedEOF {
567 t.Errorf("io.Copy(%s-%d) on truncated stream: got %v, want %v", tc.name, i, err, io.ErrUnexpectedEOF)
568 }
569 }
570 }
571 }
572
573 func TestCVE202230631(t *testing.T) {
574 var empty = []byte{0x1f, 0x8b, 0x08, 0x00, 0xa7, 0x8f, 0x43, 0x62, 0x00,
575 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
576 r := bytes.NewReader(bytes.Repeat(empty, 4e6))
577 z, err := NewReader(r)
578 if err != nil {
579 t.Fatalf("NewReader: got %v, want nil", err)
580 }
581
582
583 _, err = z.Read(make([]byte, 10))
584 if err != io.EOF {
585 t.Errorf("Reader.Read: got %v, want %v", err, io.EOF)
586 }
587 }
588
View as plain text