]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/test/test_read_format_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_read_format_zip.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * Copyright (c) 2011 Michihiro NAKAJIMA
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include "test.h"
27 __FBSDID("$FreeBSD$");
28
29 #ifdef HAVE_LIBZ
30 static const int libz_enabled = 1;
31 #else
32 static const int libz_enabled = 0;
33 #endif
34
35 /*
36  * The reference file for this has been manually tweaked so that:
37  *   * file2 has length-at-end but file1 does not
38  *   * file2 has an invalid CRC
39  */
40 static void
41 verify_basic(struct archive *a, int seek_checks)
42 {
43         struct archive_entry *ae;
44         char *buff[128];
45         const void *pv;
46         size_t s;
47         int64_t o;
48
49         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
50         assertEqualString("dir/", archive_entry_pathname(ae));
51         assertEqualInt(1179604249, archive_entry_mtime(ae));
52         assertEqualInt(0, archive_entry_size(ae));
53         if (seek_checks)
54                 assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
55         assertEqualIntA(a, ARCHIVE_EOF,
56             archive_read_data_block(a, &pv, &s, &o));
57         assertEqualInt((int)s, 0);
58
59         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
60         assertEqualString("file1", archive_entry_pathname(ae));
61         assertEqualInt(1179604289, archive_entry_mtime(ae));
62         if (seek_checks)
63                 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
64         assertEqualInt(18, archive_entry_size(ae));
65         failure("archive_read_data() returns number of bytes read");
66         if (libz_enabled) {
67                 assertEqualInt(18, archive_read_data(a, buff, 19));
68                 assertEqualMem(buff, "hello\nhello\nhello\n", 18);
69         } else {
70                 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
71                 assertEqualString(archive_error_string(a),
72                     "Unsupported ZIP compression method (deflation)");
73                 assert(archive_errno(a) != 0);
74         }
75
76         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
77         assertEqualString("file2", archive_entry_pathname(ae));
78         assertEqualInt(1179605932, archive_entry_mtime(ae));
79         if (seek_checks) {
80                 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
81                 assertEqualInt(64, archive_entry_size_is_set(ae));
82         } else {
83                 failure("file2 has length-at-end, so we shouldn't see a valid size when streaming");
84                 assertEqualInt(0, archive_entry_size_is_set(ae));
85         }
86         if (libz_enabled) {
87                 failure("file2 has a bad CRC, so read should fail and not change buff");
88                 memset(buff, 'a', 19);
89                 assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19));
90                 assertEqualMem(buff, "aaaaaaaaaaaaaaaaaaa", 19);
91         } else {
92                 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
93                 assertEqualString(archive_error_string(a),
94                     "Unsupported ZIP compression method (deflation)");
95                 assert(archive_errno(a) != 0);
96         }
97         assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
98         /* Verify the number of files read. */
99         failure("the archive file has three files");
100         assertEqualInt(3, archive_file_count(a));
101         assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
102         assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
103         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
104         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
105 }
106
107 static void
108 test_basic(void)
109 {
110         const char *refname = "test_read_format_zip.zip";
111         struct archive *a;
112         char *p;
113         size_t s;
114
115         extract_reference_file(refname);
116
117         /* Verify with seeking reader. */
118         assert((a = archive_read_new()) != NULL);
119         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
120         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
121         assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
122         verify_basic(a, 1);
123
124         /* Verify with streaming reader. */
125         p = slurpfile(&s, refname);
126         assert((a = archive_read_new()) != NULL);
127         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
128         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
129         assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
130         verify_basic(a, 0);
131 }
132
133 /*
134  * Read Info-ZIP New Unix Extra Field 0x7875 "ux".
135  *  Currently stores Unix UID/GID up to 32 bits.
136  */
137 static void
138 verify_info_zip_ux(struct archive *a, int seek_checks)
139 {
140         struct archive_entry *ae;
141         char *buff[128];
142
143         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
144         assertEqualString("file1", archive_entry_pathname(ae));
145         assertEqualInt(1300668680, archive_entry_mtime(ae));
146         assertEqualInt(18, archive_entry_size(ae));
147         if (seek_checks)
148                 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
149         failure("zip reader should read Info-ZIP New Unix Extra Field");
150         assertEqualInt(1001, archive_entry_uid(ae));
151         assertEqualInt(1001, archive_entry_gid(ae));
152         if (libz_enabled) {
153                 failure("archive_read_data() returns number of bytes read");
154                 assertEqualInt(18, archive_read_data(a, buff, 19));
155                 assertEqualMem(buff, "hello\nhello\nhello\n", 18);
156         } else {
157                 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
158                 assertEqualString(archive_error_string(a),
159                     "Unsupported ZIP compression method (deflation)");
160                 assert(archive_errno(a) != 0);
161         }
162         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
163
164         /* Verify the number of files read. */
165         failure("the archive file has just one file");
166         assertEqualInt(1, archive_file_count(a));
167
168         assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
169         assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
170         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
171         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
172 }
173
174 static void
175 test_info_zip_ux(void)
176 {
177         const char *refname = "test_read_format_zip_ux.zip";
178         struct archive *a;
179         char *p;
180         size_t s;
181
182         extract_reference_file(refname);
183
184         /* Verify with seeking reader. */
185         assert((a = archive_read_new()) != NULL);
186         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
187         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
188         assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
189         verify_info_zip_ux(a, 1);
190
191         /* Verify with streaming reader. */
192         p = slurpfile(&s, refname);
193         assert((a = archive_read_new()) != NULL);
194         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
195         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
196         assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
197         verify_info_zip_ux(a, 0);
198 }
199
200 /*
201  * Verify that test_read_extract correctly works with
202  * Zip entries that use length-at-end.
203  */
204 static void
205 verify_extract_length_at_end(struct archive *a, int seek_checks)
206 {
207         struct archive_entry *ae;
208
209         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
210
211         assertEqualString("hello.txt", archive_entry_pathname(ae));
212         if (seek_checks) {
213                 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
214                 assert(archive_entry_size_is_set(ae));
215                 assertEqualInt(6, archive_entry_size(ae));
216         } else {
217                 assert(!archive_entry_size_is_set(ae));
218                 assertEqualInt(0, archive_entry_size(ae));
219         }
220
221         if (libz_enabled) {
222                 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0));
223                 assertFileContents("hello\x0A", 6, "hello.txt");
224         } else {
225                 assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0));
226                 assertEqualString(archive_error_string(a),
227                     "Unsupported ZIP compression method (deflation)");
228                 assert(archive_errno(a) != 0);
229         }
230
231         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
232         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
233 }
234
235 static void
236 test_extract_length_at_end(void)
237 {
238         const char *refname = "test_read_format_zip_length_at_end.zip";
239         char *p;
240         size_t s;
241         struct archive *a;
242
243         extract_reference_file(refname);
244
245         /* Verify extraction with seeking reader. */
246         assert((a = archive_read_new()) != NULL);
247         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
248         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
249         assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
250         verify_extract_length_at_end(a, 1);
251
252         /* Verify extraction with streaming reader. */
253         p = slurpfile(&s, refname);
254         assert((a = archive_read_new()) != NULL);
255         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
256         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
257         assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
258         verify_extract_length_at_end(a, 0);
259 }
260
261 static void
262 test_symlink(void)
263 {
264         const char *refname = "test_read_format_zip_symlink.zip";
265         char *p;
266         size_t s;
267         struct archive *a;
268         struct archive_entry *ae;
269
270         extract_reference_file(refname);
271         p = slurpfile(&s, refname);
272
273         /* Symlinks can only be extracted with the seeking reader. */
274         assert((a = archive_read_new()) != NULL);
275         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
276         assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
277
278         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
279         assertEqualString("file", archive_entry_pathname(ae));
280         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
281
282         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
283         assertEqualString("symlink", archive_entry_pathname(ae));
284         assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
285         assertEqualInt(0, archive_entry_size(ae));
286         assertEqualString("file", archive_entry_symlink(ae));
287
288         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
289         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
290         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
291 }
292
293 DEFINE_TEST(test_read_format_zip)
294 {
295         test_basic();
296         test_info_zip_ux();
297         test_extract_length_at_end();
298         test_symlink();
299 }