test_read_format_zip.c revision 248616
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: head/contrib/libarchive/libarchive/test/test_read_format_zip.c 248616 2013-03-22 13:36:03Z mm $");
28
29#ifdef HAVE_LIBZ
30static const int libz_enabled = 1;
31#else
32static 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 */
40static void
41verify_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
107static void
108test_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 */
137static void
138verify_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
174static void
175test_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 */
204static void
205verify_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
235static void
236test_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
261static void
262test_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
293DEFINE_TEST(test_read_format_zip)
294{
295	test_basic();
296	test_info_zip_ux();
297	test_extract_length_at_end();
298	test_symlink();
299}
300