]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/test/test_read_format_mtree.c
MFC r299529,r299540,r299576,r299896:
[FreeBSD/stable/10.git] / contrib / libarchive / libarchive / test / test_read_format_mtree.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * Copyright (c) 2011-2012 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$");
28
29 static void
30 test_read_format_mtree1(void)
31 {
32         const char reffile[] = "test_read_format_mtree.mtree";
33         char buff[16];
34         struct archive_entry *ae;
35         struct archive *a;
36         FILE *f;
37         /* Compute max 64-bit signed twos-complement value
38          * without relying on overflow.  This assumes that long long
39          * is at least 64 bits. */
40         static const long long max_int64 = ((((long long)1) << 62) - 1) + (((long long)1) << 62);
41         time_t min_time;
42         volatile time_t t;
43
44         extract_reference_file(reffile);
45
46         /*
47          * An access error occurred on some platform when mtree
48          * format handling open a directory. It is for through
49          * the routine which open a directory that we create
50          * "dir" and "dir2" directories.
51          */
52         assertMakeDir("dir", 0775);
53         assertMakeDir("dir2", 0775);
54
55         assert((a = archive_read_new()) != NULL);
56         assertEqualIntA(a, ARCHIVE_OK,
57             archive_read_support_filter_all(a));
58         assertEqualIntA(a, ARCHIVE_OK,
59             archive_read_support_format_all(a));
60         assertEqualIntA(a, ARCHIVE_OK,
61             archive_read_set_options(a, "mtree:checkfs"));
62         assertEqualIntA(a, ARCHIVE_OK,
63             archive_read_open_filename(a, reffile, 11));
64
65         /*
66          * Read "file", whose data is available on disk.
67          */
68         f = fopen("file", "wb");
69         assert(f != NULL);
70         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
71         fclose(f);
72         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
73         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
74         assertEqualString(archive_entry_pathname(ae), "file");
75         assertEqualInt(archive_entry_uid(ae), 18);
76         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
77         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
78         assertEqualInt(archive_entry_size(ae), 3);
79         assertEqualInt(3, archive_read_data(a, buff, 3));
80         assertEqualMem(buff, "hi\n", 3);
81         assertEqualInt(archive_entry_is_encrypted(ae), 0);
82         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
83
84         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
85         assertEqualString(archive_entry_pathname(ae), "dir");
86         assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
87         assertEqualInt(archive_entry_is_encrypted(ae), 0);
88         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
89
90         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
91         assertEqualString(archive_entry_pathname(ae), "dir/file with space");
92         assertEqualInt(archive_entry_is_encrypted(ae), 0);
93         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
94
95         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
96         assertEqualString(archive_entry_pathname(ae), "file with space");
97         assertEqualInt(archive_entry_is_encrypted(ae), 0);
98         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
99
100         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
101         assertEqualString(archive_entry_pathname(ae), "dir2");
102         assertEqualInt(archive_entry_is_encrypted(ae), 0);
103         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
104
105         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
106         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a");
107         assertEqualInt(archive_entry_is_encrypted(ae), 0);
108         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
109
110         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
111         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a");
112         assertEqualInt(archive_entry_is_encrypted(ae), 0);
113         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
114
115         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
116         assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2");
117         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
118         assertEqualInt(archive_entry_is_encrypted(ae), 0);
119         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
120
121         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
122         assertEqualString(archive_entry_pathname(ae), "dir2/indir2");
123         assertEqualInt(archive_entry_is_encrypted(ae), 0);
124         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
125
126         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
127         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b");
128         assertEqualInt(archive_entry_is_encrypted(ae), 0);
129         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
130
131         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
132         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b");
133         assertEqualInt(archive_entry_is_encrypted(ae), 0);
134         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
135
136         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
137         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/filename\\with_esc\b\t\fapes");
138         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
139         assertEqualInt(archive_entry_is_encrypted(ae), 0);
140         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
141
142         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
143         assertEqualString(archive_entry_pathname(ae), "notindir");
144         assertEqualInt(archive_entry_is_encrypted(ae), 0);
145         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
146
147         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
148         assertEqualString(archive_entry_pathname(ae), "dir2/emptyfile");
149         assertEqualInt(archive_entry_size(ae), 0);
150         assertEqualInt(archive_entry_is_encrypted(ae), 0);
151         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
152
153         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
154         assertEqualString(archive_entry_pathname(ae), "dir2/smallfile");
155         assertEqualInt(archive_entry_size(ae), 1);
156         assertEqualInt(archive_entry_is_encrypted(ae), 0);
157         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
158
159         /* TODO: Mtree reader should probably return ARCHIVE_WARN for this. */
160         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
161         assertEqualString(archive_entry_pathname(ae), "dir2/toosmallfile");
162         assertEqualInt(archive_entry_size(ae), -1);
163         assertEqualInt(archive_entry_is_encrypted(ae), 0);
164         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
165
166         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
167         assertEqualString(archive_entry_pathname(ae), "dir2/bigfile");
168         assertEqualInt(archive_entry_size(ae), max_int64);
169         assertEqualInt(archive_entry_is_encrypted(ae), 0);
170         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
171
172         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
173         assertEqualString(archive_entry_pathname(ae), "dir2/toobigfile");
174         /* Size in mtree is max_int64 + 1; should return max_int64. */
175         assertEqualInt(archive_entry_size(ae), max_int64);
176         assertEqualInt(archive_entry_is_encrypted(ae), 0);
177         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
178
179         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
180         assertEqualString(archive_entry_pathname(ae), "dir2/veryoldfile");
181         /* The value in the file is MIN_INT64_T, but time_t may be narrower. */
182         /* Verify min_time is the smallest possible time_t. */
183         min_time = archive_entry_mtime(ae);
184         assert(min_time <= 0);
185         /* Simply asserting min_time - 1 > 0 breaks with some compiler optimizations. */
186         t = min_time - 1;
187         assert(t > 0);
188         assertEqualInt(archive_entry_is_encrypted(ae), 0);
189         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
190
191         /* toooldfile is 1 sec older, which should overflow and get returned
192          * with the same value. */
193         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
194         assertEqualString(archive_entry_pathname(ae), "dir2/toooldfile");
195         assertEqualInt(archive_entry_mtime(ae), min_time);
196         assertEqualInt(archive_entry_is_encrypted(ae), 0);
197         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
198
199         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
200         assertEqualInt(20, archive_file_count(a));
201         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
202         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
203 }
204
205 static void
206 test_read_format_mtree2(void)
207 {
208         static char archive[] =
209             "#mtree\n"
210             "d type=dir content=.\n";
211         struct archive_entry *ae;
212         struct archive *a;
213
214         assert((a = archive_read_new()) != NULL);
215         assertEqualIntA(a, ARCHIVE_OK,
216             archive_read_support_filter_all(a));
217         assertEqualIntA(a, ARCHIVE_OK,
218             archive_read_support_format_all(a));
219         assertEqualIntA(a, ARCHIVE_OK,
220             archive_read_set_options(a, "mtree:checkfs"));
221         assertEqualIntA(a, ARCHIVE_OK,
222             archive_read_open_memory(a, archive, sizeof(archive)));
223         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
224         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
225         assertEqualString(archive_entry_pathname(ae), "d");
226         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
227         assertEqualInt(archive_entry_is_encrypted(ae), 0);
228         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
229         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
230         assertEqualInt(1, archive_file_count(a));
231         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
232         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
233 }
234
235 /*
236  * Reported to libarchive.googlecode.com as Issue 121.
237  */
238 static void
239 test_read_format_mtree3(void)
240 {
241         static char archive[] =
242             "#mtree\n"
243             "a type=file contents=file\n"
244             "b type=link link=a\n"
245             "c type=file contents=file\n";
246         struct archive_entry *ae;
247         struct archive *a;
248
249         assertMakeDir("mtree3", 0777);
250         assertChdir("mtree3");
251         assertMakeFile("file", 0644, "file contents");
252
253         assert((a = archive_read_new()) != NULL);
254         assertEqualIntA(a, ARCHIVE_OK,
255             archive_read_support_filter_all(a));
256         assertEqualIntA(a, ARCHIVE_OK,
257             archive_read_support_format_all(a));
258         assertEqualIntA(a, ARCHIVE_OK,
259             archive_read_set_options(a, "mtree:checkfs"));
260         assertEqualIntA(a, ARCHIVE_OK,
261             archive_read_open_memory(a, archive, sizeof(archive)));
262         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
263         assertEqualString(archive_entry_pathname(ae), "a");
264         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
265         assertEqualInt(archive_entry_is_encrypted(ae), 0);
266         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
267         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
268         assertEqualString(archive_entry_pathname(ae), "b");
269         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
270         assertEqualInt(archive_entry_is_encrypted(ae), 0);
271         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
272         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
273         assertEqualString(archive_entry_pathname(ae), "c");
274         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
275         assertEqualInt(archive_entry_is_encrypted(ae), 0);
276         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
277
278         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
279         assertEqualInt(3, archive_file_count(a));
280         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
281         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
282
283         assertChdir("..");
284 }
285
286 DEFINE_TEST(test_read_format_mtree)
287 {
288         test_read_format_mtree1();
289         test_read_format_mtree2();
290         test_read_format_mtree3();
291 }
292
293 DEFINE_TEST(test_read_format_mtree_filenames_only)
294 {
295         static char archive[] =
296             "/set type=file mode=0644\n"
297             "./a\n"
298             "./b\n"
299             "./c\n"
300             "./d\n"
301             "./e\n"
302             "./f mode=0444\n";
303         struct archive_entry *ae;
304         struct archive *a;
305
306         assertMakeFile("file", 0644, "file contents");
307
308         assert((a = archive_read_new()) != NULL);
309         assertEqualIntA(a, ARCHIVE_OK,
310             archive_read_support_filter_all(a));
311         assertEqualIntA(a, ARCHIVE_OK,
312             archive_read_support_format_all(a));
313         assertEqualIntA(a, ARCHIVE_OK,
314             archive_read_set_options(a, "mtree:checkfs"));
315         assertEqualIntA(a, ARCHIVE_OK,
316             archive_read_open_memory(a, archive, sizeof(archive)));
317         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
318         assertEqualString(archive_entry_pathname(ae), "./a");   
319         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
320         assertEqualInt(archive_entry_is_encrypted(ae), 0);
321         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
322         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
323         assertEqualString(archive_entry_pathname(ae), "./b");
324         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
325         assertEqualInt(archive_entry_is_encrypted(ae), 0);
326         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
327         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
328         assertEqualString(archive_entry_pathname(ae), "./c");
329         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
330         assertEqualInt(archive_entry_is_encrypted(ae), 0);
331         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
332         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
333         assertEqualString(archive_entry_pathname(ae), "./d");
334         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
335         assertEqualInt(archive_entry_is_encrypted(ae), 0);
336         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
337         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
338         assertEqualString(archive_entry_pathname(ae), "./e");
339         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
340         assertEqualInt(archive_entry_is_encrypted(ae), 0);
341         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
342         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
343         assertEqualString(archive_entry_pathname(ae), "./f");
344         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444);
345         assertEqualInt(archive_entry_is_encrypted(ae), 0);
346         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
347
348         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
349         assertEqualInt(6, archive_file_count(a));
350         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
351         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
352 }
353
354 DEFINE_TEST(test_read_format_mtree_nochange)
355 {
356         static char archive[] =
357             "#mtree\n"
358             "./a type=file mode=0644 time=123\n"
359             "./b type=file mode=0644 time=234\n"
360             "./c type=file mode=0644 time=345\n";
361         static char archive2[] =
362             "#mtree\n"
363             "./a type=file mode=0644 time=123 nochange\n"
364             "./b type=file mode=0644 time=234\n"
365             "./c type=file mode=0644 time=345 nochange\n";
366         struct archive_entry *ae;
367         struct archive *a;
368
369         assertMakeFile("a", 0640, "12345");
370         assertMakeFile("b", 0664, "123456");
371         assertMakeFile("c", 0755, "1234567");
372
373         /*
374          * Test 1. Read a mtree archive without `nochange' keyword.
375          */
376         assert((a = archive_read_new()) != NULL);
377         assertEqualIntA(a, ARCHIVE_OK,
378             archive_read_support_filter_all(a));
379         assertEqualIntA(a, ARCHIVE_OK,
380             archive_read_support_format_all(a));
381         assertEqualIntA(a, ARCHIVE_OK,
382             archive_read_set_options(a, "mtree:checkfs"));
383         assertEqualIntA(a, ARCHIVE_OK,
384             archive_read_open_memory(a, archive, sizeof(archive)));
385         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
386         assertEqualString(archive_entry_pathname(ae), "./a");
387         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
388         assertEqualInt(archive_entry_mtime(ae), 123);
389         assertEqualInt(archive_entry_size(ae), 5);
390         assertEqualInt(archive_entry_is_encrypted(ae), 0);
391         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
392         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
393         assertEqualString(archive_entry_pathname(ae), "./b");
394         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
395         assertEqualInt(archive_entry_mtime(ae), 234);
396         assertEqualInt(archive_entry_size(ae), 6);
397         assertEqualInt(archive_entry_is_encrypted(ae), 0);
398         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
399         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
400         assertEqualString(archive_entry_pathname(ae), "./c");
401         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
402         assertEqualInt(archive_entry_mtime(ae), 345);
403         assertEqualInt(archive_entry_size(ae), 7);
404         assertEqualInt(archive_entry_is_encrypted(ae), 0);
405         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
406
407         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
408         assertEqualInt(3, archive_file_count(a));
409         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
410         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
411
412         /*
413          * Test 2. Read a mtree archive with `nochange' keyword.
414          */
415         assert((a = archive_read_new()) != NULL);
416         assertEqualIntA(a, ARCHIVE_OK,
417             archive_read_support_filter_all(a));
418         assertEqualIntA(a, ARCHIVE_OK,
419             archive_read_support_format_all(a));
420         assertEqualIntA(a, ARCHIVE_OK,
421             archive_read_set_options(a, "mtree:checkfs"));
422         assertEqualIntA(a, ARCHIVE_OK,
423             archive_read_open_memory(a, archive2, sizeof(archive2)));
424         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
425         assertEqualString(archive_entry_pathname(ae), "./a");
426 #if !defined(_WIN32) || defined(__CYGWIN__)
427         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0640);
428 #endif
429         assert(archive_entry_mtime(ae) != 123);
430         assertEqualInt(archive_entry_size(ae), 5);
431         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
432         assertEqualString(archive_entry_pathname(ae), "./b");
433         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
434         assertEqualInt(archive_entry_mtime(ae), 234);
435         assertEqualInt(archive_entry_size(ae), 6);
436         assertEqualInt(archive_entry_is_encrypted(ae), 0);
437         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
438         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
439         assertEqualString(archive_entry_pathname(ae), "./c");
440 #if !defined(_WIN32) || defined(__CYGWIN__)
441         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0755);
442 #endif
443         assert(archive_entry_mtime(ae) != 345);
444         assertEqualInt(archive_entry_size(ae), 7);
445         assertEqualInt(archive_entry_is_encrypted(ae), 0);
446         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
447
448         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
449         assertEqualInt(3, archive_file_count(a));
450         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
451         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
452 }
453
454 DEFINE_TEST(test_read_format_mtree_nomagic_v1_form)
455 {
456         const char reffile[] = "test_read_format_mtree_nomagic.mtree";
457         char buff[16];
458         struct archive_entry *ae;
459         struct archive *a;
460         FILE *f;
461
462         extract_reference_file(reffile);
463
464         assert((a = archive_read_new()) != NULL);
465         assertEqualIntA(a, ARCHIVE_OK,
466             archive_read_support_filter_all(a));
467         assertEqualIntA(a, ARCHIVE_OK,
468             archive_read_support_format_all(a));
469         assertEqualIntA(a, ARCHIVE_OK,
470             archive_read_set_options(a, "mtree:checkfs"));
471         assertEqualIntA(a, ARCHIVE_OK,
472             archive_read_open_filename(a, reffile, 11));
473
474         /*
475          * Read "file", whose data is available on disk.
476          */
477         f = fopen("file", "wb");
478         assert(f != NULL);
479         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
480         fclose(f);
481         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
482         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
483         assertEqualString(archive_entry_pathname(ae), "file");
484         assertEqualInt(archive_entry_uid(ae), 18);
485         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
486         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
487         assertEqualInt(archive_entry_size(ae), 3);
488         assertEqualInt(3, archive_read_data(a, buff, 3));
489         assertEqualMem(buff, "hi\n", 3);
490         assertEqualInt(archive_entry_is_encrypted(ae), 0);
491         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
492
493         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
494         assertEqualString(archive_entry_pathname(ae), "dir");
495         assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
496         assertEqualInt(archive_entry_is_encrypted(ae), 0);
497         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
498
499         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
500         assertEqualString(archive_entry_pathname(ae), "dir/file with space");
501         assertEqualInt(archive_entry_is_encrypted(ae), 0);
502         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
503
504         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
505         assertEqualString(archive_entry_pathname(ae), "file with space");
506         assertEqualInt(archive_entry_is_encrypted(ae), 0);
507         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
508
509         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
510         assertEqualString(archive_entry_pathname(ae), "dir2");
511         assertEqualInt(archive_entry_is_encrypted(ae), 0);
512         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
513
514         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
515         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a");
516         assertEqualInt(archive_entry_is_encrypted(ae), 0);
517         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
518
519         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
520         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a");
521         assertEqualInt(archive_entry_is_encrypted(ae), 0);
522         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
523
524         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
525         assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2");
526         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
527         assertEqualInt(archive_entry_is_encrypted(ae), 0);
528         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
529
530         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
531         assertEqualString(archive_entry_pathname(ae), "dir2/indir2");
532         assertEqualInt(archive_entry_is_encrypted(ae), 0);
533         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
534
535         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
536         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b");
537         assertEqualInt(archive_entry_is_encrypted(ae), 0);
538         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
539
540         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
541         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b");
542         assertEqualInt(archive_entry_is_encrypted(ae), 0);
543         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
544
545         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
546         assertEqualString(archive_entry_pathname(ae), "notindir");
547         assertEqualInt(archive_entry_is_encrypted(ae), 0);
548         assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
549
550         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
551         assertEqualInt(12, archive_file_count(a));
552         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
553         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
554 }
555
556 /*
557  * Test for a format that NetBSD mtree -C generates.
558  */
559 DEFINE_TEST(test_read_format_mtree_nomagic_v2_form)
560 {
561         const char reffile[] = "test_read_format_mtree_nomagic2.mtree";
562         char buff[16];
563         struct archive_entry *ae;
564         struct archive *a;
565         FILE *f;
566
567         extract_reference_file(reffile);
568
569         assert((a = archive_read_new()) != NULL);
570         assertEqualIntA(a, ARCHIVE_OK,
571             archive_read_support_filter_all(a));
572         assertEqualIntA(a, ARCHIVE_OK,
573             archive_read_support_format_all(a));
574         assertEqualIntA(a, ARCHIVE_OK,
575             archive_read_set_options(a, "mtree:checkfs"));
576         assertEqualIntA(a, ARCHIVE_OK,
577             archive_read_open_filename(a, reffile, 11));
578
579         /*
580          * Read "file", whose data is available on disk.
581          */
582         f = fopen("file", "wb");
583         assert(f != NULL);
584         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
585         fclose(f);
586         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
587         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
588         assertEqualString(archive_entry_pathname(ae), "./file");
589         assertEqualInt(archive_entry_uid(ae), 18);
590         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
591         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
592         assertEqualInt(archive_entry_size(ae), 3);
593         assertEqualInt(3, archive_read_data(a, buff, 3));
594         assertEqualMem(buff, "hi\n", 3);
595
596         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
597         assertEqualString(archive_entry_pathname(ae), "./dir");
598         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
599
600         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
601         assertEqualString(archive_entry_pathname(ae), "./dir/file with space");
602         assertEqualInt(archive_entry_uid(ae), 18);
603         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
604
605         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
606         assertEqualString(archive_entry_pathname(ae), "./file with space");
607         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
608
609         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
610         assertEqualString(archive_entry_pathname(ae), "./dir2");
611         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
612
613         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
614         assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a");
615         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
616
617         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
618         assertEqualInt(6, archive_file_count(a));
619         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
620         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
621 }
622
623 /*
624  * Test for a format that NetBSD mtree -D generates.
625  */
626 DEFINE_TEST(test_read_format_mtree_nomagic_v2_netbsd_form)
627 {
628         const char reffile[] = "test_read_format_mtree_nomagic3.mtree";
629         char buff[16];
630         struct archive_entry *ae;
631         struct archive *a;
632         FILE *f;
633
634         extract_reference_file(reffile);
635
636         assert((a = archive_read_new()) != NULL);
637         assertEqualIntA(a, ARCHIVE_OK,
638             archive_read_support_filter_all(a));
639         assertEqualIntA(a, ARCHIVE_OK,
640             archive_read_support_format_all(a));
641         assertEqualIntA(a, ARCHIVE_OK,
642             archive_read_set_options(a, "mtree:checkfs"));
643         assertEqualIntA(a, ARCHIVE_OK,
644             archive_read_open_filename(a, reffile, 11));
645
646         /*
647          * Read "file", whose data is available on disk.
648          */
649         f = fopen("file", "wb");
650         assert(f != NULL);
651         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
652         fclose(f);
653         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
654         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
655         assertEqualString(archive_entry_pathname(ae), "./file");
656         assertEqualInt(archive_entry_uid(ae), 18);
657         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
658         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
659         assertEqualInt(archive_entry_size(ae), 3);
660         assertEqualInt(3, archive_read_data(a, buff, 3));
661         assertEqualMem(buff, "hi\n", 3);
662
663         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
664         assertEqualString(archive_entry_pathname(ae), "./dir");
665         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
666
667         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
668         assertEqualString(archive_entry_pathname(ae), "./dir/file with space");
669         assertEqualInt(archive_entry_uid(ae), 18);
670         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
671
672         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
673         assertEqualString(archive_entry_pathname(ae), "./file with space");
674         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
675
676         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
677         assertEqualString(archive_entry_pathname(ae), "./dir2");
678         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
679
680         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
681         assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a");
682         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
683
684         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
685         assertEqualInt(6, archive_file_count(a));
686         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
687         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
688 }
689
690 /*
691  * We should get a warning if the contents file doesn't exist.
692  */
693 DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file)
694 {
695         static char archive[] =
696             "#mtree\n"
697             "a type=file contents=nonexistent_file\n";
698         struct archive_entry *ae;
699         struct archive *a;
700
701         assert((a = archive_read_new()) != NULL);
702         assertEqualIntA(a, ARCHIVE_OK,
703             archive_read_support_filter_all(a));
704         assertEqualIntA(a, ARCHIVE_OK,
705             archive_read_support_format_all(a));
706         assertEqualIntA(a, ARCHIVE_OK,
707             archive_read_set_options(a, "mtree:checkfs"));
708         assertEqualIntA(a, ARCHIVE_OK,
709             archive_read_open_memory(a, archive, sizeof(archive)));
710         assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
711         assert(strlen(archive_error_string(a)) > 0);
712         assertEqualString(archive_entry_pathname(ae), "a");
713         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
714
715         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
716         assertEqualInt(1, archive_file_count(a));
717         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
718         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
719 }
720