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$");
28 /* Copy this function for each test file and adjust it accordingly. */
29 DEFINE_TEST(test_compat_zip_1)
31 char name[] = "test_compat_zip_1.zip";
32 struct archive_entry *ae;
36 assert((a = archive_read_new()) != NULL);
37 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
38 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
39 extract_reference_file(name);
40 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
42 /* Read first entry. */
43 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
44 assertEqualString("META-INF/MANIFEST.MF", archive_entry_pathname(ae));
46 /* Read second entry. */
47 r = archive_read_next_header(a, &ae);
48 if (r == ARCHIVE_FATAL && archive_zlib_version() == NULL) {
49 skipping("Skipping ZIP compression check: %s",
50 archive_error_string(a));
53 assertEqualIntA(a, ARCHIVE_OK, r);
54 assertEqualString("tmp.class", archive_entry_pathname(ae));
56 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
58 assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
59 assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP);
62 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
63 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
67 * Verify that we skip junk between entries. The compat_zip_2.zip file
68 * has several bytes of junk between 'file1' and 'file2'. Such
69 * junk is routinely introduced by some Zip writers when they manipulate
70 * existing zip archives.
72 DEFINE_TEST(test_compat_zip_2)
74 char name[] = "test_compat_zip_2.zip";
75 struct archive_entry *ae;
78 assert((a = archive_read_new()) != NULL);
79 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
80 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
81 extract_reference_file(name);
82 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
84 /* Read first entry. */
85 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
86 assertEqualString("file1", archive_entry_pathname(ae));
88 /* Read first entry. */
89 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
90 assertEqualString("file2", archive_entry_pathname(ae));
92 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
93 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
94 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
98 * Issue 185: Test a regression that got in between 2.6 and 2.7 that
99 * broke extraction of Zip entries with length-at-end.
101 DEFINE_TEST(test_compat_zip_3)
103 const char *refname = "test_compat_zip_3.zip";
104 struct archive_entry *ae;
107 extract_reference_file(refname);
108 assert((a = archive_read_new()) != NULL);
109 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
110 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
111 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
114 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
115 assertEqualString("soapui-4.0.0/", archive_entry_pathname(ae));
116 assertEqualInt(0, archive_entry_size(ae));
117 assert(archive_entry_size_is_set(ae));
118 assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
121 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
122 assertEqualString("soapui-4.0.0/soapui-settings.xml", archive_entry_pathname(ae));
123 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
124 assertEqualInt(1030, archive_entry_size(ae));
125 assert(archive_entry_size_is_set(ae));
127 /* Extract under a different name. */
128 archive_entry_set_pathname(ae, "test_3.txt");
129 if(archive_zlib_version() != NULL) {
132 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0));
133 /* Verify the first 12 bytes actually got written to disk correctly. */
134 p = slurpfile(&s, "test_3.txt");
135 assertEqualInt(s, 1030);
136 assertEqualMem(p, "<?xml versio", 12);
139 skipping("Skipping ZIP compression check, no libz support");
141 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
143 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
144 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
148 * A file with leading garbage (similar to an SFX file).
150 DEFINE_TEST(test_compat_zip_4)
152 const char *refname = "test_compat_zip_4.zip";
153 struct archive_entry *ae;
158 extract_reference_file(refname);
159 p = slurpfile(&s, refname);
161 /* SFX files require seek support. */
162 assert((a = archive_read_new()) != NULL);
163 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
164 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
165 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 18));
168 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
169 assertEqualString("foo", archive_entry_pathname(ae));
170 assertEqualInt(4, archive_entry_size(ae));
171 assert(archive_entry_size_is_set(ae));
172 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
173 assertEqualInt(0412, archive_entry_perm(ae));
176 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
177 assertEqualString("bar", archive_entry_pathname(ae));
178 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
179 assertEqualInt(4, archive_entry_size(ae));
180 assert(archive_entry_size_is_set(ae));
181 assertEqualInt(0567, archive_entry_perm(ae));
184 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
185 assertEqualString("baz", archive_entry_pathname(ae));
186 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
187 assertEqualInt(4, archive_entry_size(ae));
188 assert(archive_entry_size_is_set(ae));
189 assertEqualInt(0644, archive_entry_perm(ae));
191 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
192 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
194 /* Try reading without seek support and watch it fail. */
195 assert((a = archive_read_new()) != NULL);
196 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
197 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
198 assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory(a, p, s, 3));
199 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
200 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
204 * Issue 152: A file generated by a tool that doesn't really
205 * believe in populating local file headers at all. This
206 * is only readable with the seeking reader.
208 DEFINE_TEST(test_compat_zip_5)
210 const char *refname = "test_compat_zip_5.zip";
211 struct archive_entry *ae;
216 extract_reference_file(refname);
217 p = slurpfile(&s, refname);
219 /* Verify with seek support.
220 * Everything works correctly here. */
221 assert((a = archive_read_new()) != NULL);
222 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
223 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
224 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 18));
226 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
227 assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
228 assertEqualInt(3559, archive_entry_size(ae));
229 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
230 assertEqualInt(0664, archive_entry_perm(ae));
232 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
233 assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
234 assertEqualInt(456, archive_entry_size(ae));
235 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
236 assertEqualInt(0664, archive_entry_perm(ae));
238 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
239 assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
240 assertEqualInt(1495, archive_entry_size(ae));
241 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
242 assertEqualInt(0664, archive_entry_perm(ae));
243 /* TODO: Read some of the file data and verify it.
244 The code to read uncompressed Zip entries with "file at end" semantics
245 is tricky and should be verified more carefully. */
247 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
248 assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
250 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
251 assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
253 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
254 assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));
256 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
257 assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
259 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
260 assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
262 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
263 assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
265 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
266 assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
268 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
269 assertEqualString("_rels/.rels", archive_entry_pathname(ae));
271 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
272 assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
274 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
276 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
277 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
279 /* Try reading without seek support. */
280 assert((a = archive_read_new()) != NULL);
281 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
282 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
283 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 3));
285 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
286 assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
287 assertEqualInt(0, archive_entry_size(ae));
288 assert(!archive_entry_size_is_set(ae));
289 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
290 assertEqualInt(0664, archive_entry_perm(ae));
292 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
293 assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
294 assertEqualInt(0, archive_entry_size(ae));
295 assert(!archive_entry_size_is_set(ae));
296 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
297 assertEqualInt(0664, archive_entry_perm(ae));
299 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
300 assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
301 assertEqualInt(0, archive_entry_size(ae));
302 assert(!archive_entry_size_is_set(ae));
303 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
304 assertEqualInt(0664, archive_entry_perm(ae));
306 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
307 assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
309 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
310 assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
312 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
313 assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));
315 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
316 assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
318 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
319 assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
321 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
322 assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
324 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
325 assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
327 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
328 assertEqualString("_rels/.rels", archive_entry_pathname(ae));
330 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
331 assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
333 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
335 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
336 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
341 * Issue 225: Errors extracting MSDOS Zip archives with directories.
344 compat_zip_6_verify(struct archive *a)
346 struct archive_entry *ae;
348 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
349 assertEqualString("New Folder/New Folder/", archive_entry_pathname(ae));
350 assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
351 /* Zip timestamps are local time, so vary by time zone. */
352 /* TODO: A more complex assert would work here; we could
353 verify that it's within +/- 24 hours of a particular value. */
354 /* assertEqualInt(1327314468, archive_entry_mtime(ae)); */
355 assertEqualInt(0, archive_entry_size(ae));
356 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
357 assertEqualString("New Folder/New Folder/New Text Document.txt", archive_entry_pathname(ae));
358 assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
359 /* Zip timestamps are local time, so vary by time zone. */
360 /* assertEqualInt(1327314476, archive_entry_mtime(ae)); */
361 assertEqualInt(11, archive_entry_size(ae));
362 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
365 DEFINE_TEST(test_compat_zip_6)
367 const char *refname = "test_compat_zip_6.zip";
372 extract_reference_file(refname);
373 p = slurpfile(&s, refname);
375 assert((a = archive_read_new()) != NULL);
376 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
377 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
378 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 7));
379 compat_zip_6_verify(a);
380 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
382 assert((a = archive_read_new()) != NULL);
383 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
384 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
385 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 7));
386 compat_zip_6_verify(a);
387 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
392 * Issue 226: Try to reproduce hang when reading archives where the
393 * length-at-end marker ends exactly on a block boundary.
395 DEFINE_TEST(test_compat_zip_7)
397 const char *refname = "test_compat_zip_7.xps";
399 struct archive_entry *ae;
404 extract_reference_file(refname);
405 p = slurpfile(&s, refname);
407 for (i = 1; i < 1000; ++i) {
408 assert((a = archive_read_new()) != NULL);
409 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
410 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, i));
412 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
413 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
414 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
415 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
416 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
417 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
418 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
419 assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
421 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));