2 * Copyright (c) 2003-2007 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 __FBSDID("$FreeBSD$");
29 static const int libz_enabled = 1;
31 static const int libz_enabled = 0;
34 /* Copy this function for each test file and adjust it accordingly. */
36 test_compat_zip_1(void)
38 char name[] = "test_compat_zip_1.zip";
39 struct archive_entry *ae;
43 assert((a = archive_read_new()) != NULL);
44 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
45 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
46 extract_reference_file(name);
47 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
49 /* Read first entry. */
50 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
51 assertEqualString("META-INF/MANIFEST.MF", archive_entry_pathname(ae));
53 /* Read second entry. */
54 r = archive_read_next_header(a, &ae);
55 if (r == ARCHIVE_FATAL && !libz_enabled) {
56 skipping("Skipping ZIP compression check: %s",
57 archive_error_string(a));
60 assertEqualIntA(a, ARCHIVE_OK, r);
61 assertEqualString("tmp.class", archive_entry_pathname(ae));
63 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
65 assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
66 assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP);
69 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
70 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
74 * Verify that we skip junk between entries. The compat_zip_2.zip file
75 * has several bytes of junk between 'file1' and 'file2'. Such
76 * junk is routinely introduced by some Zip writers when they manipulate
77 * existing zip archives.
80 test_compat_zip_2(void)
82 char name[] = "test_compat_zip_2.zip";
83 struct archive_entry *ae;
86 assert((a = archive_read_new()) != NULL);
87 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
88 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
89 extract_reference_file(name);
90 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
92 /* Read first entry. */
93 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
94 assertEqualString("file1", archive_entry_pathname(ae));
96 /* Read first entry. */
97 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
98 assertEqualString("file2", archive_entry_pathname(ae));
100 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
101 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
102 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
106 * Issue 185: Test a regression that got in between 2.6 and 2.7 that
107 * broke extraction of Zip entries with length-at-end.
110 test_compat_zip_3(void)
112 const char *refname = "test_compat_zip_3.zip";
113 struct archive_entry *ae;
116 extract_reference_file(refname);
117 assert((a = archive_read_new()) != NULL);
118 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
119 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
120 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
123 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
124 assertEqualString("soapui-4.0.0/", archive_entry_pathname(ae));
125 assertEqualInt(0, archive_entry_size(ae));
126 assert(archive_entry_size_is_set(ae));
127 assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
130 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
131 assertEqualString("soapui-4.0.0/soapui-settings.xml", archive_entry_pathname(ae));
132 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
133 assertEqualInt(1030, archive_entry_size(ae));
134 assert(archive_entry_size_is_set(ae));
136 /* Extract under a different name. */
137 archive_entry_set_pathname(ae, "test_3.txt");
141 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0));
142 /* Verify the first 12 bytes actually got written to disk correctly. */
143 p = slurpfile(&s, "test_3.txt");
144 assertEqualInt(s, 1030);
145 assertEqualMem(p, "<?xml versio", 12);
148 skipping("Skipping ZIP compression check, no libz support");
150 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
152 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
153 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
157 * A file with leading garbage (similar to an SFX file).
160 test_compat_zip_4(void)
162 const char *refname = "test_compat_zip_4.zip";
163 struct archive_entry *ae;
168 extract_reference_file(refname);
169 p = slurpfile(&s, refname);
171 /* SFX files require seek support. */
172 assert((a = archive_read_new()) != NULL);
173 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
174 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
175 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 18));
178 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
179 assertEqualString("foo", archive_entry_pathname(ae));
180 assertEqualInt(4, archive_entry_size(ae));
181 assert(archive_entry_size_is_set(ae));
182 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
183 assertEqualInt(0412, archive_entry_perm(ae));
186 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
187 assertEqualString("bar", archive_entry_pathname(ae));
188 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
189 assertEqualInt(4, archive_entry_size(ae));
190 assert(archive_entry_size_is_set(ae));
191 assertEqualInt(0567, archive_entry_perm(ae));
194 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
195 assertEqualString("baz", archive_entry_pathname(ae));
196 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
197 assertEqualInt(4, archive_entry_size(ae));
198 assert(archive_entry_size_is_set(ae));
199 assertEqualInt(0644, archive_entry_perm(ae));
201 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
202 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
204 /* Try reading without seek support and watch it fail. */
205 assert((a = archive_read_new()) != NULL);
206 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
207 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
208 assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory(a, p, s, 3));
209 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
210 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
214 * Issue 152: A file generated by a tool that doesn't really
215 * believe in populating local file headers at all. This
216 * is only readable with the seeking reader.
219 test_compat_zip_5(void)
221 const char *refname = "test_compat_zip_5.zip";
222 struct archive_entry *ae;
227 extract_reference_file(refname);
228 p = slurpfile(&s, refname);
230 /* Verify with seek support.
231 * Everything works correctly here. */
232 assert((a = archive_read_new()) != NULL);
233 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
234 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
235 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 18));
237 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
238 assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
239 assertEqualInt(3559, archive_entry_size(ae));
240 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
241 assertEqualInt(0666, archive_entry_perm(ae));
243 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
244 assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
245 assertEqualInt(456, archive_entry_size(ae));
246 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
247 assertEqualInt(0666, archive_entry_perm(ae));
249 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
250 assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
251 assertEqualInt(1495, archive_entry_size(ae));
252 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
253 assertEqualInt(0666, archive_entry_perm(ae));
254 /* TODO: Read some of the file data and verify it.
255 The code to read uncompressed Zip entries with "file at end" semantics
256 is tricky and should be verified more carefully. */
258 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
259 assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
261 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
262 assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
264 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
265 assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));
267 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
268 assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
270 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
271 assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
273 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
274 assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
276 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
277 assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
279 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
280 assertEqualString("_rels/.rels", archive_entry_pathname(ae));
282 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
283 assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
285 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
287 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
288 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
290 /* Try reading without seek support. */
291 assert((a = archive_read_new()) != NULL);
292 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
293 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
294 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 3));
296 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
297 assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
298 assertEqualInt(0, archive_entry_size(ae));
299 assert(!archive_entry_size_is_set(ae));
300 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
301 assertEqualInt(0666, archive_entry_perm(ae));
303 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
304 assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
305 assertEqualInt(0, archive_entry_size(ae));
306 assert(!archive_entry_size_is_set(ae));
307 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
308 assertEqualInt(0666, archive_entry_perm(ae));
310 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
311 assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
312 assertEqualInt(0, archive_entry_size(ae));
313 assert(!archive_entry_size_is_set(ae));
314 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
315 assertEqualInt(0666, archive_entry_perm(ae));
317 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
318 assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
320 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
321 assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
323 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
324 assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));
326 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
327 assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
329 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
330 assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
332 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
333 assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
335 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
336 assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
338 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
339 assertEqualString("_rels/.rels", archive_entry_pathname(ae));
341 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
342 assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
344 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
346 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
347 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
352 * Issue 225: Errors extracting MSDOS Zip archives with directories.
355 compat_zip_6_verify(struct archive *a)
357 struct archive_entry *ae;
359 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
360 assertEqualString("New Folder/New Folder/", archive_entry_pathname(ae));
361 assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
362 /* Zip timestamps are local time, so vary by time zone. */
363 /* TODO: A more complex assert would work here; we could
364 verify that it's within +/- 24 hours of a particular value. */
365 /* assertEqualInt(1327314468, archive_entry_mtime(ae)); */
366 assertEqualInt(0, archive_entry_size(ae));
367 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
368 assertEqualString("New Folder/New Folder/New Text Document.txt", archive_entry_pathname(ae));
369 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
370 /* Zip timestamps are local time, so vary by time zone. */
371 /* assertEqualInt(1327314476, archive_entry_mtime(ae)); */
372 assertEqualInt(11, archive_entry_size(ae));
373 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
377 test_compat_zip_6(void)
379 const char *refname = "test_compat_zip_6.zip";
384 extract_reference_file(refname);
385 p = slurpfile(&s, refname);
387 assert((a = archive_read_new()) != NULL);
388 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
389 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
390 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 7));
391 compat_zip_6_verify(a);
392 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
394 assert((a = archive_read_new()) != NULL);
395 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
396 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
397 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 7));
398 compat_zip_6_verify(a);
399 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
404 * Issue 226: Try to reproduce hang when reading archives where the
405 * length-at-end marker ends exactly on a block boundary.
408 test_compat_zip_7(void)
410 const char *refname = "test_compat_zip_7.xps";
412 struct archive_entry *ae;
417 extract_reference_file(refname);
418 p = slurpfile(&s, refname);
420 for (i = 1; i < 1000; ++i) {
421 assert((a = archive_read_new()) != NULL);
422 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
423 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, i));
425 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
426 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
427 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
428 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
429 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
430 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
431 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
432 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
434 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
439 DEFINE_TEST(test_compat_zip)