]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/test/test_read_format_zip.c
MFC r310866,310868,310870,311903,313074:
[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 /*
30  * The reference file for this has been manually tweaked so that:
31  *   * file2 has length-at-end but file1 does not
32  *   * file2 has an invalid CRC
33  */
34 static void
35 verify_basic(struct archive *a, int seek_checks)
36 {
37         struct archive_entry *ae;
38         char *buff[128];
39         const void *pv;
40         size_t s;
41         int64_t o;
42
43         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
44         assertEqualString("dir/", archive_entry_pathname(ae));
45         assertEqualInt(1179604249, archive_entry_mtime(ae));
46         assertEqualInt(0, archive_entry_size(ae));
47         if (seek_checks)
48                 assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
49         assertEqualInt(archive_entry_is_encrypted(ae), 0);
50         assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
51         assertEqualIntA(a, ARCHIVE_EOF,
52             archive_read_data_block(a, &pv, &s, &o));
53         assertEqualInt((int)s, 0);
54
55         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
56         assertEqualString("file1", archive_entry_pathname(ae));
57         assertEqualInt(1179604289, archive_entry_mtime(ae));
58         if (seek_checks)
59                 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
60         assertEqualInt(18, archive_entry_size(ae));
61         assertEqualInt(archive_entry_is_encrypted(ae), 0);
62         assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
63         failure("archive_read_data() returns number of bytes read");
64         if (archive_zlib_version() != NULL) {
65                 assertEqualInt(18, archive_read_data(a, buff, 19));
66                 assertEqualMem(buff, "hello\nhello\nhello\n", 18);
67         } else {
68                 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
69                 assertEqualString(archive_error_string(a),
70                     "Unsupported ZIP compression method (deflation)");
71                 assert(archive_errno(a) != 0);
72         }
73
74         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
75         assertEqualString("file2", archive_entry_pathname(ae));
76         assertEqualInt(1179605932, archive_entry_mtime(ae));
77         assertEqualInt(archive_entry_is_encrypted(ae), 0);
78         assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
79         if (seek_checks) {
80                 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
81         }
82         assert(archive_entry_size_is_set(ae));
83         assertEqualInt(18, archive_entry_size(ae));
84         if (archive_zlib_version() != NULL) {
85                 failure("file2 has a bad CRC, so read should fail and not change buff");
86                 memset(buff, 'a', 19);
87                 assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19));
88                 assertEqualMem(buff, "aaaaaaaaaaaaaaaaaaa", 19);
89         } else {
90                 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
91                 assertEqualString(archive_error_string(a),
92                     "Unsupported ZIP compression method (deflation)");
93                 assert(archive_errno(a) != 0);
94         }
95         assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
96         /* Verify the number of files read. */
97         failure("the archive file has three files");
98         assertEqualInt(3, archive_file_count(a));
99         assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
100         assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
101         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
102         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
103 }
104
105 static void
106 test_basic(void)
107 {
108         const char *refname = "test_read_format_zip.zip";
109         struct archive *a;
110         char *p;
111         size_t s;
112
113         extract_reference_file(refname);
114
115         /* Verify with seeking reader. */
116         assert((a = archive_read_new()) != NULL);
117         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
118         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
119         assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
120         verify_basic(a, 1);
121
122         /* Verify with streaming reader. */
123         p = slurpfile(&s, refname);
124         assert((a = archive_read_new()) != NULL);
125         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
126         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
127         assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
128         verify_basic(a, 0);
129         free(p);
130 }
131
132 /*
133  * Read Info-ZIP New Unix Extra Field 0x7875 "ux".
134  *  Currently stores Unix UID/GID up to 32 bits.
135  */
136 static void
137 verify_info_zip_ux(struct archive *a, int seek_checks)
138 {
139         struct archive_entry *ae;
140         char *buff[128];
141
142         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
143         assertEqualString("file1", archive_entry_pathname(ae));
144         assertEqualInt(1300668680, archive_entry_mtime(ae));
145         assertEqualInt(18, archive_entry_size(ae));
146         assertEqualInt(archive_entry_is_encrypted(ae), 0);
147         assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
148         if (seek_checks)
149                 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
150         failure("zip reader should read Info-ZIP New Unix Extra Field");
151         assertEqualInt(1001, archive_entry_uid(ae));
152         assertEqualInt(1001, archive_entry_gid(ae));
153         if (archive_zlib_version() != NULL) {
154                 failure("archive_read_data() returns number of bytes read");
155                 assertEqualInt(18, archive_read_data(a, buff, 19));
156                 assertEqualMem(buff, "hello\nhello\nhello\n", 18);
157         } else {
158                 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
159                 assertEqualString(archive_error_string(a),
160                     "Unsupported ZIP compression method (deflation)");
161                 assert(archive_errno(a) != 0);
162         }
163         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
164
165         /* Verify the number of files read. */
166         failure("the archive file has just one file");
167         assertEqualInt(1, archive_file_count(a));
168
169         assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
170         assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
171         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
172         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
173 }
174
175 static void
176 test_info_zip_ux(void)
177 {
178         const char *refname = "test_read_format_zip_ux.zip";
179         struct archive *a;
180         char *p;
181         size_t s;
182
183         extract_reference_file(refname);
184
185         /* Verify with seeking reader. */
186         assert((a = archive_read_new()) != NULL);
187         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
188         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
189         assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
190         verify_info_zip_ux(a, 1);
191
192         /* Verify with streaming reader. */
193         p = slurpfile(&s, refname);
194         assert((a = archive_read_new()) != NULL);
195         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
196         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
197         assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
198         verify_info_zip_ux(a, 0);
199         free(p);
200 }
201
202 /*
203  * Verify that test_read_extract correctly works with
204  * Zip entries that use length-at-end.
205  */
206 static void
207 verify_extract_length_at_end(struct archive *a, int seek_checks)
208 {
209         struct archive_entry *ae;
210
211         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
212
213         assertEqualInt(archive_entry_is_encrypted(ae), 0);
214         assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
215         assertEqualString("hello.txt", archive_entry_pathname(ae));
216         if (seek_checks) {
217                 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
218                 assert(archive_entry_size_is_set(ae));
219                 assertEqualInt(6, archive_entry_size(ae));
220         } else {
221                 assert(!archive_entry_size_is_set(ae));
222                 assertEqualInt(0, archive_entry_size(ae));
223         }
224
225         if (archive_zlib_version() != NULL) {
226                 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0));
227                 assertFileContents("hello\x0A", 6, "hello.txt");
228         } else {
229                 assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0));
230                 assertEqualString(archive_error_string(a),
231                     "Unsupported ZIP compression method (deflation)");
232                 assert(archive_errno(a) != 0);
233         }
234
235         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
236         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
237 }
238
239 static void
240 test_extract_length_at_end(void)
241 {
242         const char *refname = "test_read_format_zip_length_at_end.zip";
243         char *p;
244         size_t s;
245         struct archive *a;
246
247         extract_reference_file(refname);
248
249         /* Verify extraction with seeking reader. */
250         assert((a = archive_read_new()) != NULL);
251         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
252         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
253         assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
254         verify_extract_length_at_end(a, 1);
255
256         /* Verify extraction with streaming reader. */
257         p = slurpfile(&s, refname);
258         assert((a = archive_read_new()) != NULL);
259         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
260         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
261         assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
262         verify_extract_length_at_end(a, 0);
263         free(p);
264 }
265
266 static void
267 test_symlink(void)
268 {
269         const char *refname = "test_read_format_zip_symlink.zip";
270         char *p;
271         size_t s;
272         struct archive *a;
273         struct archive_entry *ae;
274
275         extract_reference_file(refname);
276         p = slurpfile(&s, refname);
277
278         /* Symlinks can only be extracted with the seeking reader. */
279         assert((a = archive_read_new()) != NULL);
280         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
281         assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
282
283         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
284         assertEqualString("file", archive_entry_pathname(ae));
285         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
286         assertEqualInt(archive_entry_is_encrypted(ae), 0);
287         assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
288
289         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
290         assertEqualString("symlink", archive_entry_pathname(ae));
291         assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
292         assertEqualInt(0, archive_entry_size(ae));
293         assertEqualString("file", archive_entry_symlink(ae));
294         assertEqualInt(archive_entry_is_encrypted(ae), 0);
295         assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
296
297         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
298         assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
299         assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
300
301         free(p);
302 }
303
304 DEFINE_TEST(test_read_format_zip)
305 {
306         test_basic();
307         test_info_zip_ux();
308         test_extract_length_at_end();
309         test_symlink();
310 }