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 = (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 	/* md5digest */
200 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
201 	assertEqualString(archive_entry_pathname(ae), "dir2/md5file");
202 	assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
203 	    "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e",
204 	    16);
205 
206 	/* rmd160digest */
207 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
208 	assertEqualString(archive_entry_pathname(ae), "dir2/rmd160file");
209 	assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_RMD160),
210 	    "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90"
211 	    "\xaf\xd8\x07\x09", 20);
212 
213 	/* sha1digest */
214 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
215 	assertEqualString(archive_entry_pathname(ae), "dir2/sha1file");
216 	assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA1),
217 	    "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90"
218 	    "\xaf\xd8\x07\x09", 20);
219 
220 	/* sha256digest */
221 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
222 	assertEqualString(archive_entry_pathname(ae), "dir2/sha256file");
223 	assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA256),
224 	    "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
225 	    "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55",
226 	    32);
227 
228 	/* sha384digest */
229 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
230 	assertEqualString(archive_entry_pathname(ae), "dir2/sha384file");
231 	assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA384),
232 	    "\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a"
233 	    "\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda"
234 	    "\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b",
235 	    48);
236 
237 	/* sha512digest */
238 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
239 	assertEqualString(archive_entry_pathname(ae), "dir2/sha512file");
240 	assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA512),
241 	    "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07"
242 	    "\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce"
243 	    "\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f"
244 	    "\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e",
245 	    64);
246 
247 	/* md5 digest is too short */
248 	assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
249 	assertEqualString(archive_entry_pathname(ae), "dir2/md5tooshort");
250 	assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
251 	    16, 0x00);
252 
253 	/* md5 digest is too long */
254 	assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
255 	assertEqualString(archive_entry_pathname(ae), "dir2/md5toolong");
256 	assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
257 	    16, 0x00);
258 
259 	/* md5 digest is uppercase hex */
260 	assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
261 	assertEqualString(archive_entry_pathname(ae), "dir2/md5caphex");
262 	assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
263 	    16, 0x00);
264 
265 	/* md5 digest is not hex */
266 	assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
267 	assertEqualString(archive_entry_pathname(ae), "dir2/md5nothex");
268 	assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
269 	    16, 0x00);
270 
271 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
272 	assertEqualInt(30, archive_file_count(a));
273 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
274 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
275 }
276 
277 static void
278 test_read_format_mtree2(void)
279 {
280 	static char archive[] =
281 	    "#mtree\n"
282 	    "d type=dir content=.\n";
283 	struct archive_entry *ae;
284 	struct archive *a;
285 
286 	assert((a = archive_read_new()) != NULL);
287 	assertEqualIntA(a, ARCHIVE_OK,
288 	    archive_read_support_filter_all(a));
289 	assertEqualIntA(a, ARCHIVE_OK,
290 	    archive_read_support_format_all(a));
291 	assertEqualIntA(a, ARCHIVE_OK,
292 	    archive_read_set_options(a, "mtree:checkfs"));
293 	assertEqualIntA(a, ARCHIVE_OK,
294 	    archive_read_open_memory(a, archive, sizeof(archive)));
295 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
296 	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
297 	assertEqualString(archive_entry_pathname(ae), "d");
298 	assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
299 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
300 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
301 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
302 	assertEqualInt(1, archive_file_count(a));
303 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
304 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
305 }
306 
307 /*
308  * Reported to libarchive.googlecode.com as Issue 121.
309  */
310 static void
311 test_read_format_mtree3(void)
312 {
313 	static char archive[] =
314 	    "#mtree\n"
315 	    "a type=file contents=file\n"
316 	    "b type=link link=a\n"
317 	    "c type=file contents=file\n";
318 	struct archive_entry *ae;
319 	struct archive *a;
320 
321 	assertMakeDir("mtree3", 0777);
322 	assertChdir("mtree3");
323 	assertMakeFile("file", 0644, "file contents");
324 
325 	assert((a = archive_read_new()) != NULL);
326 	assertEqualIntA(a, ARCHIVE_OK,
327 	    archive_read_support_filter_all(a));
328 	assertEqualIntA(a, ARCHIVE_OK,
329 	    archive_read_support_format_all(a));
330 	assertEqualIntA(a, ARCHIVE_OK,
331 	    archive_read_set_options(a, "mtree:checkfs"));
332 	assertEqualIntA(a, ARCHIVE_OK,
333 	    archive_read_open_memory(a, archive, sizeof(archive)));
334 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
335 	assertEqualString(archive_entry_pathname(ae), "a");
336 	assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
337 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
338 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
339 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
340 	assertEqualString(archive_entry_pathname(ae), "b");
341 	assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
342 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
343 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
344 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
345 	assertEqualString(archive_entry_pathname(ae), "c");
346 	assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
347 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
348 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
349 
350 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
351 	assertEqualInt(3, archive_file_count(a));
352 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
353 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
354 
355 	assertChdir("..");
356 }
357 
358 DEFINE_TEST(test_read_format_mtree)
359 {
360 	test_read_format_mtree1();
361 	test_read_format_mtree2();
362 	test_read_format_mtree3();
363 }
364 
365 DEFINE_TEST(test_read_format_mtree_filenames_only)
366 {
367 	static char archive[] =
368 	    "/set type=file mode=0644\n"
369 	    "./a\n"
370 	    "./b\n"
371 	    "./c\n"
372 	    "./d\n"
373 	    "./e\n"
374 	    "./f mode=0444\n";
375 	struct archive_entry *ae;
376 	struct archive *a;
377 
378 	assertMakeFile("file", 0644, "file contents");
379 
380 	assert((a = archive_read_new()) != NULL);
381 	assertEqualIntA(a, ARCHIVE_OK,
382 	    archive_read_support_filter_all(a));
383 	assertEqualIntA(a, ARCHIVE_OK,
384 	    archive_read_support_format_all(a));
385 	assertEqualIntA(a, ARCHIVE_OK,
386 	    archive_read_set_options(a, "mtree:checkfs"));
387 	assertEqualIntA(a, ARCHIVE_OK,
388 	    archive_read_open_memory(a, archive, sizeof(archive)));
389 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
390 	assertEqualString(archive_entry_pathname(ae), "./a");
391 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
392 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
393 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
394 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
395 	assertEqualString(archive_entry_pathname(ae), "./b");
396 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
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_is_encrypted(ae), 0);
403 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
404 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
405 	assertEqualString(archive_entry_pathname(ae), "./d");
406 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
407 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
408 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
409 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
410 	assertEqualString(archive_entry_pathname(ae), "./e");
411 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
412 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
413 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
414 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
415 	assertEqualString(archive_entry_pathname(ae), "./f");
416 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444);
417 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
418 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
419 
420 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
421 	assertEqualInt(6, archive_file_count(a));
422 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
423 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
424 }
425 
426 DEFINE_TEST(test_read_format_mtree_nochange)
427 {
428 	static char archive[] =
429 	    "#mtree\n"
430 	    "./a type=file mode=0644 time=123\n"
431 	    "./b type=file mode=0644 time=234\n"
432 	    "./c type=file mode=0644 time=345\n";
433 	static char archive2[] =
434 	    "#mtree\n"
435 	    "./a type=file mode=0644 time=123 nochange\n"
436 	    "./b type=file mode=0644 time=234\n"
437 	    "./c type=file mode=0644 time=345 nochange\n";
438 	struct archive_entry *ae;
439 	struct archive *a;
440 
441 	assertMakeFile("a", 0640, "12345");
442 	assertMakeFile("b", 0664, "123456");
443 	assertMakeFile("c", 0755, "1234567");
444 
445 	/*
446 	 * Test 1. Read a mtree archive without `nochange' keyword.
447 	 */
448 	assert((a = archive_read_new()) != NULL);
449 	assertEqualIntA(a, ARCHIVE_OK,
450 	    archive_read_support_filter_all(a));
451 	assertEqualIntA(a, ARCHIVE_OK,
452 	    archive_read_support_format_all(a));
453 	assertEqualIntA(a, ARCHIVE_OK,
454 	    archive_read_set_options(a, "mtree:checkfs"));
455 	assertEqualIntA(a, ARCHIVE_OK,
456 	    archive_read_open_memory(a, archive, sizeof(archive)));
457 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
458 	assertEqualString(archive_entry_pathname(ae), "./a");
459 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
460 	assertEqualInt(archive_entry_mtime(ae), 123);
461 	assertEqualInt(archive_entry_size(ae), 5);
462 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
463 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
464 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
465 	assertEqualString(archive_entry_pathname(ae), "./b");
466 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
467 	assertEqualInt(archive_entry_mtime(ae), 234);
468 	assertEqualInt(archive_entry_size(ae), 6);
469 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
470 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
471 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
472 	assertEqualString(archive_entry_pathname(ae), "./c");
473 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
474 	assertEqualInt(archive_entry_mtime(ae), 345);
475 	assertEqualInt(archive_entry_size(ae), 7);
476 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
477 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
478 
479 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
480 	assertEqualInt(3, archive_file_count(a));
481 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
482 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
483 
484 	/*
485 	 * Test 2. Read a mtree archive with `nochange' keyword.
486 	 */
487 	assert((a = archive_read_new()) != NULL);
488 	assertEqualIntA(a, ARCHIVE_OK,
489 	    archive_read_support_filter_all(a));
490 	assertEqualIntA(a, ARCHIVE_OK,
491 	    archive_read_support_format_all(a));
492 	assertEqualIntA(a, ARCHIVE_OK,
493 	    archive_read_set_options(a, "mtree:checkfs"));
494 	assertEqualIntA(a, ARCHIVE_OK,
495 	    archive_read_open_memory(a, archive2, sizeof(archive2)));
496 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
497 	assertEqualString(archive_entry_pathname(ae), "./a");
498 #if !defined(_WIN32) || defined(__CYGWIN__)
499 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0640);
500 #endif
501 	assert(archive_entry_mtime(ae) != 123);
502 	assertEqualInt(archive_entry_size(ae), 5);
503 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
504 	assertEqualString(archive_entry_pathname(ae), "./b");
505 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
506 	assertEqualInt(archive_entry_mtime(ae), 234);
507 	assertEqualInt(archive_entry_size(ae), 6);
508 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
509 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
510 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
511 	assertEqualString(archive_entry_pathname(ae), "./c");
512 #if !defined(_WIN32) || defined(__CYGWIN__)
513 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0755);
514 #endif
515 	assert(archive_entry_mtime(ae) != 345);
516 	assertEqualInt(archive_entry_size(ae), 7);
517 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
518 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
519 
520 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
521 	assertEqualInt(3, archive_file_count(a));
522 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
523 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
524 }
525 
526 DEFINE_TEST(test_read_format_mtree_nomagic_v1_form)
527 {
528 	const char reffile[] = "test_read_format_mtree_nomagic.mtree";
529 	char buff[16];
530 	struct archive_entry *ae;
531 	struct archive *a;
532 	FILE *f;
533 
534 	extract_reference_file(reffile);
535 
536 	assert((a = archive_read_new()) != NULL);
537 	assertEqualIntA(a, ARCHIVE_OK,
538 	    archive_read_support_filter_all(a));
539 	assertEqualIntA(a, ARCHIVE_OK,
540 	    archive_read_support_format_all(a));
541 	assertEqualIntA(a, ARCHIVE_OK,
542 	    archive_read_set_options(a, "mtree:checkfs"));
543 	assertEqualIntA(a, ARCHIVE_OK,
544 	    archive_read_open_filename(a, reffile, 11));
545 
546 	/*
547 	 * Read "file", whose data is available on disk.
548 	 */
549 	f = fopen("file", "wb");
550 	assert(f != NULL);
551 	assertEqualInt(3, fwrite("hi\n", 1, 3, f));
552 	fclose(f);
553 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
554 	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
555 	assertEqualString(archive_entry_pathname(ae), "file");
556 	assertEqualInt(archive_entry_uid(ae), 18);
557 	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
558 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
559 	assertEqualInt(archive_entry_size(ae), 3);
560 	assertEqualInt(3, archive_read_data(a, buff, 3));
561 	assertEqualMem(buff, "hi\n", 3);
562 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
563 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
564 
565 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
566 	assertEqualString(archive_entry_pathname(ae), "dir");
567 	assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
568 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
569 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
570 
571 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
572 	assertEqualString(archive_entry_pathname(ae), "dir/file with space");
573 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
574 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
575 
576 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
577 	assertEqualString(archive_entry_pathname(ae), "file with space");
578 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
579 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
580 
581 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
582 	assertEqualString(archive_entry_pathname(ae), "dir2");
583 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
584 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
585 
586 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
587 	assertEqualString(archive_entry_pathname(ae), "dir2/dir3a");
588 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
589 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
590 
591 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
592 	assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a");
593 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
594 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
595 
596 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
597 	assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2");
598 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
599 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
600 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
601 
602 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
603 	assertEqualString(archive_entry_pathname(ae), "dir2/indir2");
604 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
605 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
606 
607 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
608 	assertEqualString(archive_entry_pathname(ae), "dir2/dir3b");
609 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
610 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
611 
612 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
613 	assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b");
614 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
615 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
616 
617 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
618 	assertEqualString(archive_entry_pathname(ae), "notindir");
619 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
620 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
621 
622 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
623 	assertEqualInt(12, archive_file_count(a));
624 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
625 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
626 }
627 
628 /*
629  * Test for a format that NetBSD mtree -C generates.
630  */
631 DEFINE_TEST(test_read_format_mtree_nomagic_v2_form)
632 {
633 	const char reffile[] = "test_read_format_mtree_nomagic2.mtree";
634 	char buff[16];
635 	struct archive_entry *ae;
636 	struct archive *a;
637 	FILE *f;
638 
639 	extract_reference_file(reffile);
640 
641 	assert((a = archive_read_new()) != NULL);
642 	assertEqualIntA(a, ARCHIVE_OK,
643 	    archive_read_support_filter_all(a));
644 	assertEqualIntA(a, ARCHIVE_OK,
645 	    archive_read_support_format_all(a));
646 	assertEqualIntA(a, ARCHIVE_OK,
647 	    archive_read_set_options(a, "mtree:checkfs"));
648 	assertEqualIntA(a, ARCHIVE_OK,
649 	    archive_read_open_filename(a, reffile, 11));
650 
651 	/*
652 	 * Read "file", whose data is available on disk.
653 	 */
654 	f = fopen("file", "wb");
655 	assert(f != NULL);
656 	assertEqualInt(3, fwrite("hi\n", 1, 3, f));
657 	fclose(f);
658 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
659 	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
660 	assertEqualString(archive_entry_pathname(ae), "./file");
661 	assertEqualInt(archive_entry_uid(ae), 18);
662 	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
663 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
664 	assertEqualInt(archive_entry_size(ae), 3);
665 	assertEqualInt(3, archive_read_data(a, buff, 3));
666 	assertEqualMem(buff, "hi\n", 3);
667 
668 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
669 	assertEqualString(archive_entry_pathname(ae), "./dir");
670 	assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
671 
672 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
673 	assertEqualString(archive_entry_pathname(ae), "./dir/file with space");
674 	assertEqualInt(archive_entry_uid(ae), 18);
675 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
676 
677 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
678 	assertEqualString(archive_entry_pathname(ae), "./file with space");
679 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
680 
681 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
682 	assertEqualString(archive_entry_pathname(ae), "./dir2");
683 	assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
684 
685 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
686 	assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a");
687 	assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
688 
689 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
690 	assertEqualInt(6, archive_file_count(a));
691 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
692 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
693 }
694 
695 /*
696  * Test for a format that NetBSD mtree -D generates.
697  */
698 DEFINE_TEST(test_read_format_mtree_nomagic_v2_netbsd_form)
699 {
700 	const char reffile[] = "test_read_format_mtree_nomagic3.mtree";
701 	char buff[16];
702 	struct archive_entry *ae;
703 	struct archive *a;
704 	FILE *f;
705 
706 	extract_reference_file(reffile);
707 
708 	assert((a = archive_read_new()) != NULL);
709 	assertEqualIntA(a, ARCHIVE_OK,
710 	    archive_read_support_filter_all(a));
711 	assertEqualIntA(a, ARCHIVE_OK,
712 	    archive_read_support_format_all(a));
713 	assertEqualIntA(a, ARCHIVE_OK,
714 	    archive_read_set_options(a, "mtree:checkfs"));
715 	assertEqualIntA(a, ARCHIVE_OK,
716 	    archive_read_open_filename(a, reffile, 11));
717 
718 	/*
719 	 * Read "file", whose data is available on disk.
720 	 */
721 	f = fopen("file", "wb");
722 	assert(f != NULL);
723 	assertEqualInt(3, fwrite("hi\n", 1, 3, f));
724 	fclose(f);
725 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
726 	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
727 	assertEqualString(archive_entry_pathname(ae), "./file");
728 	assertEqualInt(archive_entry_uid(ae), 18);
729 	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
730 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
731 	assertEqualInt(archive_entry_size(ae), 3);
732 	assertEqualInt(3, archive_read_data(a, buff, 3));
733 	assertEqualMem(buff, "hi\n", 3);
734 
735 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
736 	assertEqualString(archive_entry_pathname(ae), "./dir");
737 	assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
738 
739 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
740 	assertEqualString(archive_entry_pathname(ae), "./dir/file with space");
741 	assertEqualInt(archive_entry_uid(ae), 18);
742 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
743 
744 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
745 	assertEqualString(archive_entry_pathname(ae), "./file with space");
746 	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
747 
748 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
749 	assertEqualString(archive_entry_pathname(ae), "./dir2");
750 	assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
751 
752 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
753 	assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a");
754 	assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
755 
756 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
757 	assertEqualInt(6, archive_file_count(a));
758 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
759 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
760 }
761 
762 /*
763  * We should get a warning if the contents file doesn't exist.
764  */
765 DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file)
766 {
767 	static char archive[] =
768 	    "#mtree\n"
769 	    "a type=file contents=nonexistent_file\n";
770 	struct archive_entry *ae;
771 	struct archive *a;
772 
773 	assert((a = archive_read_new()) != NULL);
774 	assertEqualIntA(a, ARCHIVE_OK,
775 	    archive_read_support_filter_all(a));
776 	assertEqualIntA(a, ARCHIVE_OK,
777 	    archive_read_support_format_all(a));
778 	assertEqualIntA(a, ARCHIVE_OK,
779 	    archive_read_set_options(a, "mtree:checkfs"));
780 	assertEqualIntA(a, ARCHIVE_OK,
781 	    archive_read_open_memory(a, archive, sizeof(archive)));
782 	assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
783 	assert(strlen(archive_error_string(a)) > 0);
784 	assertEqualString(archive_entry_pathname(ae), "a");
785 	assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
786 
787 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
788 	assertEqualInt(1, archive_file_count(a));
789 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
790 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
791 }
792 
793 /*
794  * Check mtree file with non-printable ascii characters
795  */
796 DEFINE_TEST(test_read_format_mtree_noprint)
797 {
798 	const char reffile[] = "test_read_format_mtree_noprint.mtree";
799 	struct archive_entry *ae;
800 	struct archive *a;
801 
802 	extract_reference_file(reffile);
803 
804 	assert((a = archive_read_new()) != NULL);
805 	assertEqualIntA(a, ARCHIVE_OK,
806 	    archive_read_support_filter_all(a));
807 	assertEqualIntA(a, ARCHIVE_OK,
808 	    archive_read_support_format_all(a));
809 	assertEqualIntA(a, ARCHIVE_OK,
810 	    archive_read_open_filename(a, reffile, 11));
811 
812 	assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
813 	assertEqualString("Can't parse line 3", archive_error_string(a));
814 
815 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
816 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
817 }
818 
819 /*
820  * Check mtree file with tab characters, which are supported but not printable
821  */
822 DEFINE_TEST(test_read_format_mtree_tab)
823 {
824 	static char archive[] =
825 	    "#mtree\n"
826 	    "\ta\ttype=file\n";
827 	struct archive_entry *ae;
828 	struct archive *a;
829 
830 	assert((a = archive_read_new()) != NULL);
831 	assertEqualIntA(a, ARCHIVE_OK,
832 	    archive_read_support_filter_all(a));
833 	assertEqualIntA(a, ARCHIVE_OK,
834 	    archive_read_support_format_all(a));
835 	assertEqualIntA(a, ARCHIVE_OK,
836 	    archive_read_open_memory(a, archive, sizeof(archive)));
837 
838 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
839 	assertEqualString(archive_entry_pathname(ae), "a");
840 	assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
841 
842 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
843 	assertEqualInt(1, archive_file_count(a));
844 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
845 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
846 }
847