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