]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/test/test_compat_zip.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / contrib / libarchive / libarchive / test / test_compat_zip.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
24  */
25 #include "test.h"
26 __FBSDID("$FreeBSD$");
27
28 /* Copy this function for each test file and adjust it accordingly. */
29 DEFINE_TEST(test_compat_zip_1)
30 {
31         char name[] = "test_compat_zip_1.zip";
32         struct archive_entry *ae;
33         struct archive *a;
34         int r;
35
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));
41
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));
45
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));
51                 goto finish;
52         }
53         assertEqualIntA(a, ARCHIVE_OK, r);
54         assertEqualString("tmp.class", archive_entry_pathname(ae));
55
56         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
57
58         assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
59         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP);
60
61 finish:
62         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
63         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
64 }
65
66 /*
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.
71  */
72 DEFINE_TEST(test_compat_zip_2)
73 {
74         char name[] = "test_compat_zip_2.zip";
75         struct archive_entry *ae;
76         struct archive *a;
77
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));
83
84         /* Read first entry. */
85         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
86         assertEqualString("file1", archive_entry_pathname(ae));
87
88         /* Read first entry. */
89         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
90         assertEqualString("file2", archive_entry_pathname(ae));
91
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));
95 }
96
97 /*
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.
100  */
101 DEFINE_TEST(test_compat_zip_3)
102 {
103         const char *refname = "test_compat_zip_3.zip";
104         struct archive_entry *ae;
105         struct archive *a;
106
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));
112
113         /* First entry. */
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));
119
120         /* Second entry. */
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));
126
127         /* Extract under a different name. */
128         archive_entry_set_pathname(ae, "test_3.txt");
129         if(archive_zlib_version() != NULL) {
130                 char *p;
131                 size_t s;
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);
137                 free(p);
138         } else {
139                 skipping("Skipping ZIP compression check, no libz support");
140         }
141         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
142
143         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
144         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
145 }
146
147 /**
148  * A file with leading garbage (similar to an SFX file).
149  */
150 DEFINE_TEST(test_compat_zip_4)
151 {
152         const char *refname = "test_compat_zip_4.zip";
153         struct archive_entry *ae;
154         struct archive *a;
155         void *p;
156         size_t s;
157
158         extract_reference_file(refname);
159         p = slurpfile(&s, "%s", refname);
160
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));
166
167         /* First entry. */
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));
174
175         /* Second entry. */
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));
182
183         /* Third entry. */
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));
190
191         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
192         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
193
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));
201         free(p);
202 }
203 /**
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.
207  */
208 DEFINE_TEST(test_compat_zip_5)
209 {
210         const char *refname = "test_compat_zip_5.zip";
211         struct archive_entry *ae;
212         struct archive *a;
213         void *p;
214         size_t s;
215
216         extract_reference_file(refname);
217         p = slurpfile(&s, "%s", refname);
218
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));
225
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));
231
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));
237
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. */
246
247         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
248         assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
249
250         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
251         assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
252
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));
255
256         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
257         assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
258
259         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
260         assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
261
262         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
263         assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
264
265         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
266         assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
267
268         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
269         assertEqualString("_rels/.rels", archive_entry_pathname(ae));
270
271         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
272         assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
273
274         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
275
276         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
277         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
278
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));
284
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));
291
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));
298
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));
305
306         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
307         assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
308
309         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
310         assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
311
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));
314
315         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
316         assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
317
318         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
319         assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
320
321         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
322         assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
323
324         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
325         assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
326
327         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
328         assertEqualString("_rels/.rels", archive_entry_pathname(ae));
329
330         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
331         assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
332
333         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
334
335         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
336         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
337         free(p);
338 }
339
340 /*
341  * Issue 225: Errors extracting MSDOS Zip archives with directories.
342  */
343 static void
344 compat_zip_6_verify(struct archive *a)
345 {
346         struct archive_entry *ae;
347
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));
363 }
364
365 DEFINE_TEST(test_compat_zip_6)
366 {
367         const char *refname = "test_compat_zip_6.zip";
368         struct archive *a;
369         void *p;
370         size_t s;
371
372         extract_reference_file(refname);
373         p = slurpfile(&s, "%s", refname);
374
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));
381
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));
388         free(p);
389 }
390
391 /*
392  * Issue 226: Try to reproduce hang when reading archives where the
393  * length-at-end marker ends exactly on a block boundary.
394  */
395 DEFINE_TEST(test_compat_zip_7)
396 {
397         const char *refname = "test_compat_zip_7.xps";
398         struct archive *a;
399         struct archive_entry *ae;
400         void *p;
401         size_t s;
402         int i;
403
404         extract_reference_file(refname);
405         p = slurpfile(&s, "%s", refname);
406
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));
411
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));
420
421                 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
422         }
423         free(p);
424 }
425
426 /**
427  * A file with backslash path separators instead of slashes.
428  * PowerShell's Compress-Archive cmdlet produces such archives.
429  */
430 DEFINE_TEST(test_compat_zip_8)
431 {
432         const char *refname = "test_compat_zip_8.zip";
433         struct archive *a;
434         struct archive_entry *ae;
435         void *p;
436         size_t s;
437
438         extract_reference_file(refname);
439         p = slurpfile(&s, "%s", refname);
440
441         assert((a = archive_read_new()) != NULL);
442         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
443         assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, 7));
444
445         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
446         /* This file is in the archive as arc\test */
447         assertEqualString("arc/test", archive_entry_pathname(ae));
448         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
449         free(p);
450 }