test_read_format_zip.c revision 302001
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 302001 2016-06-17 22:40:10Z 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("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
105static void
106test_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}
130
131/*
132 * Read Info-ZIP New Unix Extra Field 0x7875 "ux".
133 *  Currently stores Unix UID/GID up to 32 bits.
134 */
135static void
136verify_info_zip_ux(struct archive *a, int seek_checks)
137{
138	struct archive_entry *ae;
139	char *buff[128];
140
141	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
142	assertEqualString("file1", archive_entry_pathname(ae));
143	assertEqualInt(1300668680, archive_entry_mtime(ae));
144	assertEqualInt(18, archive_entry_size(ae));
145	assertEqualInt(archive_entry_is_encrypted(ae), 0);
146	assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
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 (archive_zlib_version() != NULL) {
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	assertEqualInt(archive_entry_is_encrypted(ae), 0);
212	assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
213	assertEqualString("hello.txt", archive_entry_pathname(ae));
214	if (seek_checks) {
215		assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
216		assert(archive_entry_size_is_set(ae));
217		assertEqualInt(6, archive_entry_size(ae));
218	} else {
219		assert(!archive_entry_size_is_set(ae));
220		assertEqualInt(0, archive_entry_size(ae));
221	}
222
223	if (archive_zlib_version() != NULL) {
224		assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0));
225		assertFileContents("hello\x0A", 6, "hello.txt");
226	} else {
227		assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0));
228		assertEqualString(archive_error_string(a),
229		    "Unsupported ZIP compression method (deflation)");
230		assert(archive_errno(a) != 0);
231	}
232
233	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
234	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
235}
236
237static void
238test_extract_length_at_end(void)
239{
240	const char *refname = "test_read_format_zip_length_at_end.zip";
241	char *p;
242	size_t s;
243	struct archive *a;
244
245	extract_reference_file(refname);
246
247	/* Verify extraction with seeking reader. */
248	assert((a = archive_read_new()) != NULL);
249	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
250	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
251	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
252	verify_extract_length_at_end(a, 1);
253
254	/* Verify extraction with streaming reader. */
255	p = slurpfile(&s, refname);
256	assert((a = archive_read_new()) != NULL);
257	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
258	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
259	assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
260	verify_extract_length_at_end(a, 0);
261}
262
263static void
264test_symlink(void)
265{
266	const char *refname = "test_read_format_zip_symlink.zip";
267	char *p;
268	size_t s;
269	struct archive *a;
270	struct archive_entry *ae;
271
272	extract_reference_file(refname);
273	p = slurpfile(&s, refname);
274
275	/* Symlinks can only be extracted with the seeking reader. */
276	assert((a = archive_read_new()) != NULL);
277	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
278	assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
279
280	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
281	assertEqualString("file", archive_entry_pathname(ae));
282	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
283	assertEqualInt(archive_entry_is_encrypted(ae), 0);
284	assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
285
286	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
287	assertEqualString("symlink", archive_entry_pathname(ae));
288	assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
289	assertEqualInt(0, archive_entry_size(ae));
290	assertEqualString("file", archive_entry_symlink(ae));
291	assertEqualInt(archive_entry_is_encrypted(ae), 0);
292	assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
293
294	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
295	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
296	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
297}
298
299DEFINE_TEST(test_read_format_zip)
300{
301	test_basic();
302	test_info_zip_ux();
303	test_extract_length_at_end();
304	test_symlink();
305}
306