1 /*-
2 * Copyright (c) 2003-2008 Tim Kientzle
3 * Copyright (c) 2010 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
28 #define __LIBARCHIVE_TEST
29 #include "archive_write_private.h"
30
31 #include <locale.h>
32
33 static void
test_xar(const char * option)34 test_xar(const char *option)
35 {
36 char buff2[64];
37 size_t buffsize = 4096;
38 char *buff;
39 struct archive_entry *ae;
40 struct archive *a;
41 size_t used;
42 const char *name;
43 const void *value;
44 size_t size;
45
46 /* Create a new archive in memory. */
47 assert((a = archive_write_new()) != NULL);
48 if (archive_write_set_format_xar(a) != ARCHIVE_OK) {
49 skipping("xar is not supported on this platform");
50 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
51 return;
52 }
53 assertA(0 == archive_write_add_filter_none(a));
54 if (option != NULL &&
55 archive_write_set_options(a, option) != ARCHIVE_OK) {
56 skipping("option `%s` is not supported on this platform", option);
57 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
58 return;
59 }
60
61 buff = malloc(buffsize);
62 assert(buff != NULL);
63
64 assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
65
66 /*
67 * "file" has a bunch of attributes and 8 bytes of data and
68 * 7 bytes of xattr data and 3 bytes of xattr.
69 */
70 assert((ae = archive_entry_new()) != NULL);
71 archive_entry_set_atime(ae, 2, 20);
72 archive_entry_set_ctime(ae, 4, 40);
73 archive_entry_set_mtime(ae, 5, 50);
74 archive_entry_copy_pathname(ae, "file");
75 archive_entry_set_mode(ae, AE_IFREG | 0755);
76 archive_entry_set_nlink(ae, 2);
77 archive_entry_set_size(ae, 8);
78 archive_entry_xattr_add_entry(ae, "user.data1", "ABCDEFG", 7);
79 archive_entry_xattr_add_entry(ae, "user.data2", "XYZ", 3);
80 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
81 archive_entry_free(ae);
82 assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
83
84 /*
85 * "file2" is symbolic link to file
86 */
87 assert((ae = archive_entry_new()) != NULL);
88 archive_entry_set_atime(ae, 2, 20);
89 archive_entry_set_ctime(ae, 4, 40);
90 archive_entry_set_mtime(ae, 5, 50);
91 archive_entry_copy_pathname(ae, "file2");
92 archive_entry_copy_symlink(ae, "file");
93 archive_entry_set_mode(ae, AE_IFLNK | 0755);
94 archive_entry_set_size(ae, 0);
95 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
96 archive_entry_free(ae);
97
98 /*
99 * "dir/file" has a bunch of attributes and 8 bytes of data.
100 */
101 assert((ae = archive_entry_new()) != NULL);
102 archive_entry_set_atime(ae, 2, 20);
103 archive_entry_set_ctime(ae, 4, 40);
104 archive_entry_set_mtime(ae, 5, 50);
105 archive_entry_copy_pathname(ae, "dir/../../dir/file");
106 archive_entry_set_mode(ae, AE_IFREG | 0755);
107 archive_entry_set_size(ae, 8);
108 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
109 archive_entry_free(ae);
110 assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9));
111
112 /*
113 * "dir/dir2/file4" is hard link to file
114 */
115 assert((ae = archive_entry_new()) != NULL);
116 archive_entry_set_atime(ae, 2, 20);
117 archive_entry_set_ctime(ae, 4, 40);
118 archive_entry_set_mtime(ae, 5, 50);
119 archive_entry_copy_pathname(ae, "dir/..//dir/dir2/file4");
120 archive_entry_copy_hardlink(ae, "file");
121 archive_entry_set_mode(ae, AE_IFREG | 0755);
122 archive_entry_set_nlink(ae, 2);
123 archive_entry_set_size(ae, 0);
124 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
125 archive_entry_free(ae);
126
127 /*
128 * "dir/dir3" is a directory
129 */
130 assert((ae = archive_entry_new()) != NULL);
131 archive_entry_set_atime(ae, 2, 20);
132 archive_entry_set_ctime(ae, 4, 40);
133 archive_entry_set_mtime(ae, 5, 50);
134 archive_entry_copy_pathname(ae, "dir/dir3");
135 archive_entry_set_mode(ae, AE_IFDIR | 0755);
136 archive_entry_unset_size(ae);
137 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
138 archive_entry_free(ae);
139
140 /*
141 * Add a wrong path "dir/dir2/file4/wrong"
142 */
143 assert((ae = archive_entry_new()) != NULL);
144 archive_entry_set_atime(ae, 2, 20);
145 archive_entry_set_ctime(ae, 4, 40);
146 archive_entry_set_mtime(ae, 5, 50);
147 archive_entry_copy_pathname(ae, "dir/dir2/file4/wrong");
148 archive_entry_set_mode(ae, AE_IFREG | 0755);
149 archive_entry_set_nlink(ae, 1);
150 archive_entry_set_size(ae, 0);
151 assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
152 archive_entry_free(ae);
153
154 /*
155 * "dir/file{UNICODE}" has a name that requires base64 encoding
156 */
157 assert((ae = archive_entry_new()) != NULL);
158 archive_entry_set_atime(ae, 2, 20);
159 archive_entry_set_ctime(ae, 4, 40);
160 archive_entry_set_mtime(ae, 5, 50);
161 archive_entry_copy_pathname_w(ae, L"dir/file\U0001F574");
162 archive_entry_set_mode(ae, AE_IFREG | 0755);
163 archive_entry_set_size(ae, 8);
164 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
165 archive_entry_free(ae);
166 assertEqualIntA(a, 8, archive_write_data(a, "ghijklmn", 9));
167
168 /*
169 * XXX TODO XXX Archive directory, other file types.
170 * Archive extended attributes, ACLs, other metadata.
171 * Verify they get read back correctly.
172 */
173
174 /* Close out the archive. */
175 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
176 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
177
178 /*
179 *
180 * Now, read the data back.
181 *
182 */
183 assert((a = archive_read_new()) != NULL);
184 assertEqualIntA(a, 0, archive_read_support_format_all(a));
185 assertEqualIntA(a, 0, archive_read_support_filter_all(a));
186 assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
187
188 /*
189 * Read "file"
190 */
191 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
192 assertEqualInt(2, archive_entry_atime(ae));
193 assertEqualInt(0, archive_entry_atime_nsec(ae));
194 assertEqualInt(4, archive_entry_ctime(ae));
195 assertEqualInt(0, archive_entry_ctime_nsec(ae));
196 assertEqualInt(5, archive_entry_mtime(ae));
197 assertEqualInt(0, archive_entry_mtime_nsec(ae));
198 assertEqualString("file", archive_entry_pathname(ae));
199 assert((AE_IFREG | 0755) == archive_entry_mode(ae));
200 assertEqualInt(2, archive_entry_nlink(ae));
201 assertEqualInt(8, archive_entry_size(ae));
202 assertEqualInt(2, archive_entry_xattr_reset(ae));
203 assertEqualInt(ARCHIVE_OK,
204 archive_entry_xattr_next(ae, &name, &value, &size));
205 assertEqualString("user.data2", name);
206 assertEqualMem(value, "XYZ", 3);
207 assertEqualInt(ARCHIVE_OK,
208 archive_entry_xattr_next(ae, &name, &value, &size));
209 assertEqualString("user.data1", name);
210 assertEqualMem(value, "ABCDEFG", 7);
211 assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
212 assertEqualMem(buff2, "12345678", 8);
213
214 /*
215 * Read "file2"
216 */
217 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
218 assert(archive_entry_atime_is_set(ae));
219 assertEqualInt(2, archive_entry_atime(ae));
220 assertEqualInt(0, archive_entry_atime_nsec(ae));
221 assert(archive_entry_ctime_is_set(ae));
222 assertEqualInt(4, archive_entry_ctime(ae));
223 assertEqualInt(0, archive_entry_ctime_nsec(ae));
224 assert(archive_entry_mtime_is_set(ae));
225 assertEqualInt(5, archive_entry_mtime(ae));
226 assertEqualInt(0, archive_entry_mtime_nsec(ae));
227 assertEqualString("file2", archive_entry_pathname(ae));
228 assertEqualString("file", archive_entry_symlink(ae));
229 assert((AE_IFLNK | 0755) == archive_entry_mode(ae));
230 assertEqualInt(0, archive_entry_size(ae));
231
232 /*
233 * Read "dir/file3"
234 */
235 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
236 assertEqualInt(2, archive_entry_atime(ae));
237 assertEqualInt(0, archive_entry_atime_nsec(ae));
238 assertEqualInt(4, archive_entry_ctime(ae));
239 assertEqualInt(0, archive_entry_ctime_nsec(ae));
240 assertEqualInt(5, archive_entry_mtime(ae));
241 assertEqualInt(0, archive_entry_mtime_nsec(ae));
242 assertEqualString("dir/file", archive_entry_pathname(ae));
243 assert((AE_IFREG | 0755) == archive_entry_mode(ae));
244 assertEqualInt(8, archive_entry_size(ae));
245 assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
246 assertEqualMem(buff2, "abcdefgh", 8);
247
248 /*
249 * Read "dir/dir2/file4"
250 */
251 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
252 assert(archive_entry_atime_is_set(ae));
253 assertEqualInt(2, archive_entry_atime(ae));
254 assertEqualInt(0, archive_entry_atime_nsec(ae));
255 assert(archive_entry_ctime_is_set(ae));
256 assertEqualInt(4, archive_entry_ctime(ae));
257 assertEqualInt(0, archive_entry_ctime_nsec(ae));
258 assert(archive_entry_mtime_is_set(ae));
259 assertEqualInt(5, archive_entry_mtime(ae));
260 assertEqualInt(0, archive_entry_mtime_nsec(ae));
261 assertEqualString("dir/dir2/file4", archive_entry_pathname(ae));
262 assertEqualString("file", archive_entry_hardlink(ae));
263 assert((AE_IFREG | 0755) == archive_entry_mode(ae));
264 assertEqualInt(2, archive_entry_nlink(ae));
265 assertEqualInt(0, archive_entry_size(ae));
266
267 /*
268 * Read "dir/dir3"
269 */
270 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
271 assert(archive_entry_atime_is_set(ae));
272 assertEqualInt(2, archive_entry_atime(ae));
273 assertEqualInt(0, archive_entry_atime_nsec(ae));
274 assert(archive_entry_ctime_is_set(ae));
275 assertEqualInt(4, archive_entry_ctime(ae));
276 assertEqualInt(0, archive_entry_ctime_nsec(ae));
277 assert(archive_entry_mtime_is_set(ae));
278 assertEqualInt(5, archive_entry_mtime(ae));
279 assertEqualInt(0, archive_entry_mtime_nsec(ae));
280 assertEqualString("dir/dir3", archive_entry_pathname(ae));
281 assert((AE_IFDIR | 0755) == archive_entry_mode(ae));
282
283 /*
284 * Read "dir/file{UNICODE}"
285 */
286 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
287 assertEqualInt(2, archive_entry_atime(ae));
288 assertEqualInt(0, archive_entry_atime_nsec(ae));
289 assertEqualInt(4, archive_entry_ctime(ae));
290 assertEqualInt(0, archive_entry_ctime_nsec(ae));
291 assertEqualInt(5, archive_entry_mtime(ae));
292 assertEqualInt(0, archive_entry_mtime_nsec(ae));
293 assertEqualWString(L"dir/file\U0001F574", archive_entry_pathname_w(ae));
294 assert((AE_IFREG | 0755) == archive_entry_mode(ae));
295 assertEqualInt(8, archive_entry_size(ae));
296 assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
297 assertEqualMem(buff2, "ghijklmn", 8);
298
299 /*
300 * Verify the end of the archive.
301 */
302 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
303 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
304 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
305
306 free(buff);
307 }
308
DEFINE_TEST(test_write_format_xar)309 DEFINE_TEST(test_write_format_xar)
310 {
311 /* xar mandates the use of UTF-8 XML; if we cannot
312 * use UTF-8, perhaps we should not write xar. */
313 if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
314 skipping("en_US.UTF-8 locale not available on this system.");
315 return;
316 }
317
318 /* Default mode. */
319 test_xar(NULL);
320
321 /* Disable TOC checksum. */
322 test_xar("!toc-checksum");
323 test_xar("toc-checksum=none");
324 #ifdef ARCHIVE_HAS_SHA1
325 /* Specify TOC checksum type to sha1. */
326 test_xar("toc-checksum=sha1");
327 #endif
328 #ifdef ARCHIVE_HAS_MD5
329 /* Specify TOC checksum type to md5. */
330 test_xar("toc-checksum=md5");
331 #endif
332 #ifdef ARCHIVE_HAS_SHA256
333 /* Specify TOC checksum type to sha256. */
334 test_xar("toc-checksum=sha256");
335 #endif
336 #ifdef ARCHIVE_HAS_SHA512
337 /* Specify TOC checksum type to sha512. */
338 test_xar("toc-checksum=sha512");
339 #endif
340
341 /* Disable file checksum. */
342 test_xar("!checksum");
343 test_xar("checksum=none");
344 #ifdef ARCHIVE_HAS_SHA1
345 /* Specify file checksum type to sha1. */
346 test_xar("checksum=sha1");
347 #endif
348 #ifdef ARCHIVE_HAS_MD5
349 /* Specify file checksum type to md5. */
350 test_xar("checksum=md5");
351 #endif
352 #ifdef ARCHIVE_HAS_SHA256
353 /* Specify file checksum type to sha256. */
354 test_xar("checksum=sha256");
355 #endif
356 #ifdef ARCHIVE_HAS_SHA512
357 /* Specify file checksum type to sha512. */
358 test_xar("checksum=sha512");
359 #endif
360
361 /* Disable compression. */
362 test_xar("!compression");
363 test_xar("compression=none");
364 /* Specify compression type to gzip. */
365 test_xar("compression=gzip");
366 test_xar("compression=gzip,compression-level=1");
367 test_xar("compression=gzip,compression-level=9");
368 /* Specify compression type to bzip2. */
369 test_xar("compression=bzip2");
370 test_xar("compression=bzip2,compression-level=1");
371 test_xar("compression=bzip2,compression-level=9");
372 /* Specify compression type to lzma. */
373 test_xar("compression=lzma");
374 test_xar("compression=lzma,compression-level=1");
375 test_xar("compression=lzma,compression-level=9");
376 /* Specify compression type to xz. */
377 test_xar("compression=xz");
378 test_xar("compression=xz,compression-level=1");
379 test_xar("compression=xz,compression-level=9");
380 }
381
DEFINE_TEST(test_write_format_xar_entry_trunc)382 DEFINE_TEST(test_write_format_xar_entry_trunc)
383 {
384 struct archive *a;
385 struct archive_entry *ae;
386 unsigned char buff[1024];
387 size_t used = 0;
388
389 assert((a = archive_write_new()) != NULL);
390 if (archive_write_set_format_xar(a) != ARCHIVE_OK) {
391 skipping("xar is not supported on this platform");
392 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
393 return;
394 }
395 assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
396 assertEqualIntA(a, ARCHIVE_OK,
397 archive_write_open_memory(a, buff, sizeof(buff), &used));
398
399 assert((ae = archive_entry_new()) != NULL);
400 archive_entry_set_pathname(ae, "foo");
401 archive_entry_set_mode(ae, S_IFREG | 0644);
402 archive_entry_set_size(ae, 1028);
403 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
404 archive_entry_free(ae);
405 assertEqualIntA(a, 3, archive_write_data(a, "foo", 3));
406
407 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
408 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
409 }
410
DEFINE_TEST(test_write_format_xar_unregister)411 DEFINE_TEST(test_write_format_xar_unregister)
412 {
413 struct archive *a;
414 struct archive_write *aw;
415
416 assert((a = archive_write_new()) != NULL);
417 if (archive_write_set_format_xar(a) != ARCHIVE_OK) {
418 skipping("xar is not supported on this platform");
419 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
420 return;
421 }
422
423 aw = (struct archive_write *)a;
424 assert(aw->format_data != NULL);
425 assert(aw->format_free != NULL);
426
427 assertEqualIntA(a, ARCHIVE_OK,
428 __archive_write_unregister_format(aw));
429
430 assert(aw->format_data == NULL);
431 assert(aw->format_name == NULL);
432 assert(aw->format_init == NULL);
433 assert(aw->format_options == NULL);
434 assert(aw->format_finish_entry == NULL);
435 assert(aw->format_write_header == NULL);
436 assert(aw->format_write_data == NULL);
437 assert(aw->format_close == NULL);
438 assert(aw->format_free == NULL);
439 assertEqualInt(0, aw->archive.archive_format);
440 assert(aw->archive.archive_format_name == NULL);
441
442 assertEqualIntA(a, ARCHIVE_FAILED,
443 archive_write_set_format_option(a, NULL, "compression",
444 "gzip"));
445
446 assertEqualIntA(a, ARCHIVE_OK,
447 __archive_write_unregister_format(aw));
448 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
449 }
450