]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/test/test_compat_zip.c
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[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 #ifdef HAVE_LIBZ
29 static const int libz_enabled = 1;
30 #else
31 static const int libz_enabled = 0;
32 #endif
33
34 /* Copy this function for each test file and adjust it accordingly. */
35 static void
36 test_compat_zip_1(void)
37 {
38         char name[] = "test_compat_zip_1.zip";
39         struct archive_entry *ae;
40         struct archive *a;
41         int r;
42
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));
48
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));
52
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));
58                 goto finish;
59         }
60         assertEqualIntA(a, ARCHIVE_OK, r);
61         assertEqualString("tmp.class", archive_entry_pathname(ae));
62
63         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
64
65         assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
66         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP);
67
68 finish:
69         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
70         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
71 }
72
73 /*
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.
78  */
79 static void
80 test_compat_zip_2(void)
81 {
82         char name[] = "test_compat_zip_2.zip";
83         struct archive_entry *ae;
84         struct archive *a;
85
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));
91
92         /* Read first entry. */
93         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
94         assertEqualString("file1", archive_entry_pathname(ae));
95
96         /* Read first entry. */
97         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
98         assertEqualString("file2", archive_entry_pathname(ae));
99
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));
103 }
104
105 /*
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.
108  */
109 static void
110 test_compat_zip_3(void)
111 {
112         const char *refname = "test_compat_zip_3.zip";
113         struct archive_entry *ae;
114         struct archive *a;
115
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));
121
122         /* First entry. */
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));
128
129         /* Second entry. */
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));
135
136         /* Extract under a different name. */
137         archive_entry_set_pathname(ae, "test_3.txt");
138         if(libz_enabled) {
139                 char *p;
140                 size_t s;
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);
146                 free(p);
147         } else {
148                 skipping("Skipping ZIP compression check, no libz support");
149         }
150         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
151
152         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
153         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
154 }
155
156 /**
157  * A file with leading garbage (similar to an SFX file).
158  */
159 static void
160 test_compat_zip_4(void)
161 {
162         const char *refname = "test_compat_zip_4.zip";
163         struct archive_entry *ae;
164         struct archive *a;
165         void *p;
166         size_t s;
167
168         extract_reference_file(refname);
169         p = slurpfile(&s, refname);
170
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));
176
177         /* First entry. */
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));
184
185         /* Second entry. */
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));
192
193         /* Third entry. */
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));
200
201         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
202         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
203
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));
211         free(p);
212 }
213 /**
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.
217  */
218 static void
219 test_compat_zip_5(void)
220 {
221         const char *refname = "test_compat_zip_5.zip";
222         struct archive_entry *ae;
223         struct archive *a;
224         void *p;
225         size_t s;
226
227         extract_reference_file(refname);
228         p = slurpfile(&s, refname);
229
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));
236
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));
242
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));
248
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. */
257
258         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
259         assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
260
261         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
262         assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
263
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));
266
267         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
268         assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
269
270         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
271         assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
272
273         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
274         assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
275
276         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
277         assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
278
279         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
280         assertEqualString("_rels/.rels", archive_entry_pathname(ae));
281
282         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
283         assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
284
285         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
286
287         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
288         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
289
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));
295
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));
302
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));
309
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));
316
317         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
318         assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
319
320         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
321         assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
322
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));
325
326         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
327         assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
328
329         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
330         assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
331
332         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
333         assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
334
335         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
336         assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
337
338         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
339         assertEqualString("_rels/.rels", archive_entry_pathname(ae));
340
341         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
342         assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
343
344         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
345
346         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
347         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
348         free(p);
349 }
350
351 /*
352  * Issue 225: Errors extracting MSDOS Zip archives with directories.
353  */
354 static void
355 compat_zip_6_verify(struct archive *a)
356 {
357         struct archive_entry *ae;
358
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));
374 }
375
376 static void
377 test_compat_zip_6(void)
378 {
379         const char *refname = "test_compat_zip_6.zip";
380         struct archive *a;
381         void *p;
382         size_t s;
383
384         extract_reference_file(refname);
385         p = slurpfile(&s, refname);
386
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));
393
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));
400         free(p);
401 }
402
403 /*
404  * Issue 226: Try to reproduce hang when reading archives where the
405  * length-at-end marker ends exactly on a block boundary.
406  */
407 static void
408 test_compat_zip_7(void)
409 {
410         const char *refname = "test_compat_zip_7.xps";
411         struct archive *a;
412         struct archive_entry *ae;
413         void *p;
414         size_t s;
415         int i;
416
417         extract_reference_file(refname);
418         p = slurpfile(&s, refname);
419
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));
424
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));
433
434                 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
435         }
436         free(p);
437 }
438
439 DEFINE_TEST(test_compat_zip)
440 {
441         test_compat_zip_1();
442         test_compat_zip_2();
443         test_compat_zip_3();
444         test_compat_zip_4();
445         test_compat_zip_5();
446         test_compat_zip_6();
447         test_compat_zip_7();
448 }
449
450