test_read_format_mtree.c revision 348607
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: stable/11/contrib/libarchive/libarchive/test/test_read_format_mtree.c 348607 2019-06-04 10:35:54Z mm $");
28
29static void
30test_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 = (time_t)((uintmax_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
205static void
206test_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 */
238static void
239test_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
286DEFINE_TEST(test_read_format_mtree)
287{
288	test_read_format_mtree1();
289	test_read_format_mtree2();
290	test_read_format_mtree3();
291}
292
293DEFINE_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
354DEFINE_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
454DEFINE_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 */
559DEFINE_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 */
626DEFINE_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 */
693DEFINE_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/*
721 * Check mtree file with non-printable ascii characters
722 */
723DEFINE_TEST(test_read_format_mtree_noprint)
724{
725	const char reffile[] = "test_read_format_mtree_noprint.mtree";
726	struct archive_entry *ae;
727	struct archive *a;
728
729	extract_reference_file(reffile);
730
731	assert((a = archive_read_new()) != NULL);
732	assertEqualIntA(a, ARCHIVE_OK,
733	    archive_read_support_filter_all(a));
734	assertEqualIntA(a, ARCHIVE_OK,
735	    archive_read_support_format_all(a));
736	assertEqualIntA(a, ARCHIVE_OK,
737	    archive_read_open_filename(a, reffile, 11));
738
739	assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
740	assertEqualString("Can't parse line 3", archive_error_string(a));
741
742	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
743	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
744}
745