xref: /freebsd/contrib/libarchive/libarchive/test/test_write_format_zip.c (revision 38f0b757fd84d17d0fc24739a7cda160c4516d81)
1 /*-
2  * Copyright (c) 2003-2008 Tim Kientzle
3  * Copyright (c) 2008 Anselm Strauss
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 
27 /*
28  * Development supported by Google Summer of Code 2008.
29  */
30 
31 #include "test.h"
32 __FBSDID("$FreeBSD$");
33 
34 static void
35 verify_contents(struct archive *a, int expect_details)
36 {
37 	char filedata[64];
38 	struct archive_entry *ae;
39 
40 	/*
41 	 * Read and verify first file.
42 	 */
43 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
44 	assertEqualInt(1, archive_entry_mtime(ae));
45 	/* Zip doesn't store high-resolution mtime. */
46 	assertEqualInt(0, archive_entry_mtime_nsec(ae));
47 	assertEqualInt(0, archive_entry_atime(ae));
48 	assertEqualInt(0, archive_entry_ctime(ae));
49 	assertEqualString("file", archive_entry_pathname(ae));
50 	if (expect_details) {
51 		assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
52 		assertEqualInt(8, archive_entry_size(ae));
53 	} else {
54 		assertEqualInt(0, archive_entry_size(ae));
55 	}
56 	assertEqualIntA(a, 8,
57 	    archive_read_data(a, filedata, sizeof(filedata)));
58 	assertEqualMem(filedata, "12345678", 8);
59 
60 
61 	/*
62 	 * Read the second file back.
63 	 */
64 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
65 	assertEqualInt(1, archive_entry_mtime(ae));
66 	assertEqualInt(0, archive_entry_mtime_nsec(ae));
67 	assertEqualInt(0, archive_entry_atime(ae));
68 	assertEqualInt(0, archive_entry_ctime(ae));
69 	assertEqualString("file2", archive_entry_pathname(ae));
70 	if (expect_details) {
71 		assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
72 		assertEqualInt(4, archive_entry_size(ae));
73 	} else {
74 		assertEqualInt(0, archive_entry_size(ae));
75 	}
76 	assertEqualIntA(a, 4,
77 	    archive_read_data(a, filedata, sizeof(filedata)));
78 	assertEqualMem(filedata, "1234", 4);
79 
80 	/*
81 	 * Read the third file back.
82 	 */
83 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
84 	assertEqualInt(1, archive_entry_mtime(ae));
85 	assertEqualInt(0, archive_entry_mtime_nsec(ae));
86 	assertEqualInt(0, archive_entry_atime(ae));
87 	assertEqualInt(0, archive_entry_ctime(ae));
88 	assertEqualString("symlink", archive_entry_pathname(ae));
89 	if (expect_details) {
90 		assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
91 		assertEqualInt(0, archive_entry_size(ae));
92 		assertEqualString("file1", archive_entry_symlink(ae));
93 	} else {
94 		assertEqualInt(AE_IFREG | 0666, archive_entry_mode(ae));
95 		assertEqualInt(0, archive_entry_size(ae));
96 	}
97 
98 	/*
99 	 * Read the dir entry back.
100 	 */
101 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
102 	assertEqualInt(11, archive_entry_mtime(ae));
103 	assertEqualInt(0, archive_entry_mtime_nsec(ae));
104 	assertEqualInt(0, archive_entry_atime(ae));
105 	assertEqualInt(0, archive_entry_ctime(ae));
106 	assertEqualString("dir/", archive_entry_pathname(ae));
107 	if (expect_details)
108 		assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
109 	assertEqualInt(0, archive_entry_size(ae));
110 	assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
111 
112 	/* Verify the end of the archive. */
113 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
114 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
115 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
116 }
117 
118 DEFINE_TEST(test_write_format_zip)
119 {
120 	struct archive_entry *ae;
121 	struct archive *a;
122 	size_t used;
123 	size_t buffsize = 1000000;
124 	char *buff;
125 	const char *compression_type;
126 
127 	buff = malloc(buffsize);
128 
129 	/* Create a new archive in memory. */
130 	assert((a = archive_write_new()) != NULL);
131 	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a));
132 #ifdef HAVE_ZLIB_H
133 	compression_type = "deflate";
134 #else
135 	compression_type = "store";
136 #endif
137 	assertEqualIntA(a, ARCHIVE_OK,
138 	    archive_write_set_format_option(a, "zip", "compression", compression_type));
139 	assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
140 	assertEqualIntA(a, ARCHIVE_OK,
141 	    archive_write_open_memory(a, buff, buffsize, &used));
142 
143 	/*
144 	 * Write a file to it.
145 	 */
146 	assert((ae = archive_entry_new()) != NULL);
147 	archive_entry_set_mtime(ae, 1, 10);
148 	assertEqualInt(1, archive_entry_mtime(ae));
149 	assertEqualInt(10, archive_entry_mtime_nsec(ae));
150 	archive_entry_copy_pathname(ae, "file");
151 	assertEqualString("file", archive_entry_pathname(ae));
152 	archive_entry_set_mode(ae, AE_IFREG | 0755);
153 	assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
154 	archive_entry_set_size(ae, 8);
155 
156 	assertEqualInt(0, archive_write_header(a, ae));
157 	archive_entry_free(ae);
158 	assertEqualInt(8, archive_write_data(a, "12345678", 9));
159 	assertEqualInt(0, archive_write_data(a, "1", 1));
160 
161 	/*
162 	 * Write another file to it.
163 	 */
164 	assert((ae = archive_entry_new()) != NULL);
165 	archive_entry_set_mtime(ae, 1, 10);
166 	assertEqualInt(1, archive_entry_mtime(ae));
167 	assertEqualInt(10, archive_entry_mtime_nsec(ae));
168 	archive_entry_copy_pathname(ae, "file2");
169 	assertEqualString("file2", archive_entry_pathname(ae));
170 	archive_entry_set_mode(ae, AE_IFREG | 0755);
171 	assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
172 	archive_entry_set_size(ae, 4);
173 
174 	assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
175 	archive_entry_free(ae);
176 	assertEqualInt(4, archive_write_data(a, "1234", 5));
177 
178 	/*
179 	 * Write symbolic like file to it.
180 	 */
181 	assert((ae = archive_entry_new()) != NULL);
182 	archive_entry_set_mtime(ae, 1, 10);
183 	assertEqualInt(1, archive_entry_mtime(ae));
184 	assertEqualInt(10, archive_entry_mtime_nsec(ae));
185 	archive_entry_copy_pathname(ae, "symlink");
186 	assertEqualString("symlink", archive_entry_pathname(ae));
187 	archive_entry_copy_symlink(ae, "file1");
188 	assertEqualString("file1", archive_entry_symlink(ae));
189 	archive_entry_set_mode(ae, AE_IFLNK | 0755);
190 	assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae));
191 	archive_entry_set_size(ae, 4);
192 
193 	assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
194 	archive_entry_free(ae);
195 
196 	/*
197 	 * Write a directory to it.
198 	 */
199 	assert((ae = archive_entry_new()) != NULL);
200 	archive_entry_set_mtime(ae, 11, 110);
201 	archive_entry_copy_pathname(ae, "dir");
202 	archive_entry_set_mode(ae, S_IFDIR | 0755);
203 	archive_entry_set_size(ae, 512);
204 
205 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
206 	failure("size should be zero so that applications know not to write");
207 	assertEqualInt(0, archive_entry_size(ae));
208 	archive_entry_free(ae);
209 	assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
210 
211 	/* Close out the archive. */
212 	assertEqualInt(ARCHIVE_OK, archive_write_close(a));
213 	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
214 
215 	/*
216 	 * Now, read the data back.
217 	 */
218 	/* With the standard memory reader. */
219 	assert((a = archive_read_new()) != NULL);
220 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
221 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
222 	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
223 	verify_contents(a, 1);
224 
225 	/* With the test memory reader -- streaming mode. */
226 	assert((a = archive_read_new()) != NULL);
227 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
228 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
229 	assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7));
230 	/* Streaming reader doesn't see mode information from Central Directory. */
231 	verify_contents(a, 0);
232 
233 	/* With the test memory reader -- seeking mode. */
234 	assert((a = archive_read_new()) != NULL);
235 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
236 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
237 	assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));
238 	verify_contents(a, 1);
239 
240 	free(buff);
241 }
242