1 /*-
2  * Copyright (c) 2009-2011 Michihiro NAKAJIMA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "test.h"
26 
27 /*
28  * Check that a "zisofs" ISO 9660 image is correctly created.
29  */
30 
31 static const unsigned char primary_id[] = {
32     0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
33 };
34 static const unsigned char volumesize[] = {
35     0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23
36 };
37 static const unsigned char volumesize2[] = {
38     0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36
39 };
40 static const unsigned char volumesize3[] = {
41     0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28
42 };
43 static const unsigned char volumeidu16[] = {
44     0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f,
45     0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
46     0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
47     0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20
48 };
49 static const unsigned char supplementary_id[] = {
50     0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
51 };
52 static const unsigned char terminator_id[] = {
53     0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
54 };
55 
56 static const unsigned char zisofs_magic[8] = {
57     0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
58 };
59 
60 static const unsigned char zisofs_data[24] = {
61     0x37, 0xe4, 0x53, 0x96, 0xc9, 0xdb, 0xd6, 0x07,
62     0x00, 0x80, 0x00, 0x00, 0x04, 0x0f, 0x00, 0x00,
63     0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00
64 };
65 
66 static const unsigned char boot_id[] = {
67     0x00, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x45,
68     0x4c, 0x20, 0x54, 0x4f, 0x52, 0x49, 0x54, 0x4f,
69     0x20, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
70     0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,
71     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 };
73 
74 static const unsigned char boot_catalog[] = {
75     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78     0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x55, 0xaa,
79     0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
80     0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
83 };
84 
85 static const unsigned char el_torito_signature[] = {
86     "ER\355\001\012T\207\001RRIP_1991ATHE ROCK RIDGE "
87     "INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX "
88     "FILE SYSTEM SEMANTICSPLEASE CONTACT DISC PUBLISHER "
89     "FOR SPECIFICATION SOURCE.  SEE PUBLISHER IDENTIFIER "
90     "IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION."
91 };
92 
93 static void
test_write_format_iso9660_zisofs_1(void)94 test_write_format_iso9660_zisofs_1(void)
95 {
96 	unsigned char buff2[1024];
97 	unsigned char nullb[1024];
98 	struct archive *a;
99 	struct archive_entry *ae;
100 	unsigned char *buff;
101 	size_t buffsize = 36 * 2048;
102 	size_t used;
103 	unsigned int i;
104 	int r;
105 
106 	memset(nullb, 0, sizeof(nullb));
107 	buff = malloc(buffsize);
108 	assert(buff != NULL);
109 	if (buff == NULL)
110 		return;
111 
112 	/* ISO9660 format: Create a new archive in memory. */
113 	assert((a = archive_write_new()) != NULL);
114 	assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
115 	assertEqualIntA(a, 0, archive_write_add_filter_none(a));
116 	r = archive_write_set_option(a, NULL, "zisofs", "1");
117 	if (r == ARCHIVE_FATAL) {
118 		skipping("zisofs option not supported on this platform");
119 		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
120 		free(buff);
121 		return;
122 	}
123 	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
124 	assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
125 
126 	/*
127 	 * "file1" has a bunch of attributes and 256K bytes of null data.
128 	 */
129 	assert((ae = archive_entry_new()) != NULL);
130 	archive_entry_set_atime(ae, 2, 20);
131 	archive_entry_set_birthtime(ae, 3, 30);
132 	archive_entry_set_ctime(ae, 4, 40);
133 	archive_entry_set_mtime(ae, 5, 50);
134 	archive_entry_copy_pathname(ae, "file1");
135 	archive_entry_set_mode(ae, S_IFREG | 0755);
136 	archive_entry_set_size(ae, 256*1024);
137 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
138 	archive_entry_free(ae);
139 	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
140 
141 	/*
142 	 * "file2" has a bunch of attributes and 2048 bytes of null data.
143 	 */
144 	assert((ae = archive_entry_new()) != NULL);
145 	archive_entry_set_atime(ae, 2, 20);
146 	archive_entry_set_birthtime(ae, 3, 30);
147 	archive_entry_set_ctime(ae, 4, 40);
148 	archive_entry_set_mtime(ae, 5, 50);
149 	archive_entry_copy_pathname(ae, "file2");
150 	archive_entry_set_mode(ae, S_IFREG | 0755);
151 	archive_entry_set_size(ae, 2048);
152 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
153 	archive_entry_free(ae);
154 	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
155 
156 	/*
157 	 * "file3" has a bunch of attributes and 2049 bytes of null data.
158 	 */
159 	assert((ae = archive_entry_new()) != NULL);
160 	archive_entry_set_atime(ae, 2, 20);
161 	archive_entry_set_birthtime(ae, 3, 30);
162 	archive_entry_set_ctime(ae, 4, 40);
163 	archive_entry_set_mtime(ae, 5, 50);
164 	archive_entry_copy_pathname(ae, "file3");
165 	archive_entry_set_mode(ae, S_IFREG | 0755);
166 	archive_entry_set_size(ae, 2049);
167 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
168 	archive_entry_free(ae);
169 	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
170 
171 	/*
172 	 * "file4" has a bunch of attributes and 24 bytes of zisofs data
173 	 * which is compressed from 32K bytes null data.
174 	 */
175 	assert((ae = archive_entry_new()) != NULL);
176 	archive_entry_set_atime(ae, 2, 20);
177 	archive_entry_set_birthtime(ae, 3, 30);
178 	archive_entry_set_ctime(ae, 4, 40);
179 	archive_entry_set_mtime(ae, 5, 50);
180 	archive_entry_copy_pathname(ae, "file4");
181 	archive_entry_set_mode(ae, S_IFREG | 0755);
182 	archive_entry_set_size(ae, 24);
183 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
184 	archive_entry_free(ae);
185 	assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24));
186 
187 	/* Close out the archive. */
188 	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
189 	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
190 
191 	failure("The ISO image size should be 71680 bytes.");
192 	assertEqualInt(used, 2048 * 35);
193 
194 	/* Check System Area. */
195 	for (i = 0; i < 2048 * 16; i++) {
196 		failure("System Area should be all nulls.");
197 		assertEqualInt(buff[i], 0);
198 	}
199 
200 	/* Primary Volume. */
201 	failure("Primary Volume Descriptor should be in 16 Logical Sector.");
202 	assertEqualMem(buff+2048*16, primary_id, 8);
203 	assertEqualMem(buff+2048*16+0x28,
204 	    "CDROM                           ", 32);
205 	assertEqualMem(buff+2048*16+0x50, volumesize, 8);
206 
207 	/* Supplementary Volume. */
208 	failure("Supplementary Volume(Joliet) Descriptor "
209 	    "should be in 17 Logical Sector.");
210 	assertEqualMem(buff+2048*17, supplementary_id, 8);
211 	assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
212 	assertEqualMem(buff+2048*17+0x50, volumesize, 8);
213 	failure("Date and Time of Primary Volume and "
214 	    "Date and Time of Supplementary Volume "
215 	    "must be the same.");
216 	assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
217 
218 	/* Terminator. */
219 	failure("Volume Descriptor Set Terminator "
220 	    "should be in 18 Logical Sector.");
221 	assertEqualMem(buff+2048*18, terminator_id, 8);
222 	for (i = 8; i < 2048; i++) {
223 		failure("Body of Volume Descriptor Set Terminator "
224 		    "should be all nulls.");
225 		assertEqualInt(buff[2048*18+i], 0);
226 	}
227 
228 	/* "file1"  Contents is zisofs data. */
229 	failure("file1 image should be zisofs'ed.");
230 	assertEqualMem(buff+2048*31, zisofs_magic, 8);
231 	/* "file2"  Contents is not zisofs data. */
232 	failure("file2 image should not be zisofs'ed.");
233 	assertEqualMem(buff+2048*32, nullb, 8);
234 	/* "file3"  Contents is zisofs data. */
235 	failure("file3 image should be zisofs'ed.");
236 	assertEqualMem(buff+2048*33, zisofs_magic, 8);
237 	/* "file4"  Contents is zisofs data. */
238 	failure("file4 image should be zisofs'ed.");
239 	assertEqualMem(buff+2048*34, zisofs_magic, 8);
240 
241 	/*
242 	 * Read ISO image.
243 	 */
244 	assert((a = archive_read_new()) != NULL);
245 	assertEqualIntA(a, 0, archive_read_support_format_all(a));
246 	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
247 	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
248 
249 	/*
250 	 * Read Root Directory
251 	 * Root Directory entry must be in ISO image.
252 	 */
253 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
254 	assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
255 	assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
256 	assertEqualString(".", archive_entry_pathname(ae));
257 	assert((S_IFDIR | 0555) == archive_entry_mode(ae));
258 	assertEqualInt(2048, archive_entry_size(ae));
259 
260 	/*
261 	 * Read "file1" which has 256K bytes null data.
262 	 */
263 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
264 	assertEqualInt(2, archive_entry_atime(ae));
265 	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
266 	assertEqualInt(4, archive_entry_ctime(ae));
267 	assertEqualInt(5, archive_entry_mtime(ae));
268 	assertEqualString("file1", archive_entry_pathname(ae));
269 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
270 	assertEqualInt(256*1024, archive_entry_size(ae));
271 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
272 	assertEqualMem(buff2, nullb, 1024);
273 
274 	/*
275 	 * Read "file2" which has 2048 bytes null data.
276 	 */
277 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
278 	assertEqualInt(2, archive_entry_atime(ae));
279 	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
280 	assertEqualInt(4, archive_entry_ctime(ae));
281 	assertEqualInt(5, archive_entry_mtime(ae));
282 	assertEqualString("file2", archive_entry_pathname(ae));
283 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
284 	assertEqualInt(2048, archive_entry_size(ae));
285 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
286 	assertEqualMem(buff2, nullb, 1024);
287 
288 	/*
289 	 * Read "file3" which has 2049 bytes null data.
290 	 */
291 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
292 	assertEqualInt(2, archive_entry_atime(ae));
293 	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
294 	assertEqualInt(4, archive_entry_ctime(ae));
295 	assertEqualInt(5, archive_entry_mtime(ae));
296 	assertEqualString("file3", archive_entry_pathname(ae));
297 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
298 	assertEqualInt(2049, archive_entry_size(ae));
299 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
300 	assertEqualMem(buff2, nullb, 1024);
301 
302 	/*
303 	 * Read "file4" which has 32K bytes null data.
304 	 */
305 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
306 	assertEqualInt(2, archive_entry_atime(ae));
307 	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
308 	assertEqualInt(4, archive_entry_ctime(ae));
309 	assertEqualInt(5, archive_entry_mtime(ae));
310 	assertEqualString("file4", archive_entry_pathname(ae));
311 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
312 	assertEqualInt(32768, archive_entry_size(ae));
313 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
314 	assertEqualMem(buff2, nullb, 1024);
315 
316 	/*
317 	 * Verify the end of the archive.
318 	 */
319 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
320 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
321 	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
322 
323 	free(buff);
324 }
325 
326 static void
test_write_format_iso9660_zisofs_2(void)327 test_write_format_iso9660_zisofs_2(void)
328 {
329 	unsigned char buff2[1024];
330 	unsigned char data[1024];
331 	struct archive *a;
332 	struct archive_entry *ae;
333 	unsigned char *buff;
334 	size_t buffsize = 60 * 2048;
335 	size_t used;
336 	unsigned int i;
337 	int r;
338 
339 	buff = malloc(buffsize);
340 	assert(buff != NULL);
341 	if (buff == NULL)
342 		return;
343 
344 	/* ISO9660 format: Create a new archive in memory. */
345 	assert((a = archive_write_new()) != NULL);
346 	assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
347 	assertEqualIntA(a, 0, archive_write_add_filter_none(a));
348 	r = archive_write_set_option(a, NULL, "zisofs", "1");
349 	if (r == ARCHIVE_FATAL) {
350 		skipping("zisofs option not supported on this platform");
351 		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
352 		free(buff);
353 		return;
354 	}
355 	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
356 	assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
357 
358 	/*
359 	 * "file1" has a bunch of attributes and 256K bytes of random data.
360 	 */
361 	assert((ae = archive_entry_new()) != NULL);
362 	archive_entry_set_atime(ae, 2, 20);
363 	archive_entry_set_birthtime(ae, 3, 30);
364 	archive_entry_set_ctime(ae, 4, 40);
365 	archive_entry_set_mtime(ae, 5, 50);
366 	archive_entry_copy_pathname(ae, "file1");
367 	archive_entry_set_mode(ae, S_IFREG | 0755);
368 	archive_entry_set_size(ae, 256*1024);
369 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
370 	archive_entry_free(ae);
371 	for (i = 0; i < 256; i++) {
372 		int j;
373 		if (i == 0) {
374 			for (j = 0; j < (int)sizeof(data); j++)
375 				data[j] = (i^j) & 0xff;
376 		} else {
377 			for (j = 0; j < (int)sizeof(data); j++)
378 				data[j] ^= i+j;
379 		}
380 		assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
381 	}
382 
383 	/*
384 	 * "file2" has a bunch of attributes and 2048 bytes data.
385 	 */
386 	assert((ae = archive_entry_new()) != NULL);
387 	archive_entry_set_atime(ae, 2, 20);
388 	archive_entry_set_birthtime(ae, 3, 30);
389 	archive_entry_set_ctime(ae, 4, 40);
390 	archive_entry_set_mtime(ae, 5, 50);
391 	archive_entry_copy_pathname(ae, "file2");
392 	archive_entry_set_mode(ae, S_IFREG | 0755);
393 	archive_entry_set_size(ae, 2048);
394 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
395 	archive_entry_free(ae);
396 	memset(data, 'a', sizeof(data));
397 	assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
398 	memset(data, 'b', sizeof(data));
399 	assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
400 
401 	/*
402 	 * "file3" has a bunch of attributes and 1024 bytes of 'Z'
403 	 *  + 1025 bytes of null data.
404 	 */
405 	assert((ae = archive_entry_new()) != NULL);
406 	archive_entry_set_atime(ae, 2, 20);
407 	archive_entry_set_birthtime(ae, 3, 30);
408 	archive_entry_set_ctime(ae, 4, 40);
409 	archive_entry_set_mtime(ae, 5, 50);
410 	archive_entry_copy_pathname(ae, "file3");
411 	archive_entry_set_mode(ae, S_IFREG | 0755);
412 	archive_entry_set_size(ae, 2049);
413 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
414 	archive_entry_free(ae);
415 	memset(data, 'Z', sizeof(data));
416 	assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
417 
418 	/*
419 	 * "file4" has a bunch of attributes and 24 bytes of zisofs data
420 	 * which is compressed from 32K bytes null data.
421 	 */
422 	assert((ae = archive_entry_new()) != NULL);
423 	archive_entry_set_atime(ae, 2, 20);
424 	archive_entry_set_birthtime(ae, 3, 30);
425 	archive_entry_set_ctime(ae, 4, 40);
426 	archive_entry_set_mtime(ae, 5, 50);
427 	archive_entry_copy_pathname(ae, "file4");
428 	archive_entry_set_mode(ae, S_IFREG | 0755);
429 	archive_entry_set_size(ae, 24);
430 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
431 	archive_entry_free(ae);
432 	assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24));
433 
434 	/* Close out the archive. */
435 	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
436 	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
437 
438 	failure("The ISO image size should be 110592 bytes.");
439 	assertEqualInt(used, 2048 * 54);
440 
441 	/* Check System Area. */
442 	for (i = 0; i < 2048 * 16; i++) {
443 		failure("System Area should be all nulls.");
444 		assertEqualInt(buff[i], 0);
445 	}
446 
447 	/* Primary Volume. */
448 	failure("Primary Volume Descriptor should be in 16 Logical Sector.");
449 	assertEqualMem(buff+2048*16, primary_id, 8);
450 	assertEqualMem(buff+2048*16+0x28,
451 	    "CDROM                           ", 32);
452 	assertEqualMem(buff+2048*16+0x50, volumesize2, 8);
453 
454 	/* Supplementary Volume. */
455 	failure("Supplementary Volume(Joliet) Descriptor "
456 	    "should be in 17 Logical Sector.");
457 	assertEqualMem(buff+2048*17, supplementary_id, 8);
458 	assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
459 	assertEqualMem(buff+2048*17+0x50, volumesize2, 8);
460 	failure("Date and Time of Primary Volume and "
461 	    "Date and Time of Supplementary Volume "
462 	    "must be the same.");
463 	assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
464 
465 	/* Terminator. */
466 	failure("Volume Descriptor Set Terminator "
467 	    "should be in 18 Logical Sector.");
468 	assertEqualMem(buff+2048*18, terminator_id, 8);
469 	for (i = 8; i < 2048; i++) {
470 		failure("Body of Volume Descriptor Set Terminator "
471 		    "should be all nulls.");
472 		assertEqualInt(buff[2048*18+i], 0);
473 	}
474 
475 	/* "file1"  Contents is zisofs data. */
476 	failure("file1 image should be zisofs'ed.");
477 	assertEqualMem(buff+2048*31, zisofs_magic, 8);
478 	/* "file2"  Contents is not zisofs data. */
479 	memset(data, 'a', sizeof(data));
480 	failure("file2 image should not be zisofs'ed.");
481 	assertEqualMem(buff+2048*51, data, 1024);
482 	memset(data, 'b', sizeof(data));
483 	failure("file2 image should not be zisofs'ed.");
484 	assertEqualMem(buff+2048*51+1024, data, 1024);
485 	/* "file3"  Contents is zisofs data. */
486 	failure("file3 image should be zisofs'ed.");
487 	assertEqualMem(buff+2048*52, zisofs_magic, 8);
488 	/* "file4"  Contents is zisofs data. */
489 	failure("file4 image should be zisofs'ed.");
490 	assertEqualMem(buff+2048*53, zisofs_magic, 8);
491 
492 	/*
493 	 * Read ISO image.
494 	 */
495 	assert((a = archive_read_new()) != NULL);
496 	assertEqualIntA(a, 0, archive_read_support_format_all(a));
497 	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
498 	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
499 
500 	/*
501 	 * Read Root Directory
502 	 * Root Directory entry must be in ISO image.
503 	 */
504 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
505 	assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
506 	assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
507 	assertEqualString(".", archive_entry_pathname(ae));
508 	assert((S_IFDIR | 0555) == archive_entry_mode(ae));
509 	assertEqualInt(2048, archive_entry_size(ae));
510 
511 	/*
512 	 * Read "file1" which has 256K bytes random data.
513 	 */
514 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
515 	assertEqualInt(2, archive_entry_atime(ae));
516 	assertEqualInt(4, archive_entry_ctime(ae));
517 	assertEqualInt(5, archive_entry_mtime(ae));
518 	assertEqualString("file1", archive_entry_pathname(ae));
519 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
520 	assertEqualInt(256*1024, archive_entry_size(ae));
521 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
522 
523 	/*
524 	 * Read "file2" which has 2048 bytes data.
525 	 */
526 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
527 	assertEqualInt(2, archive_entry_atime(ae));
528 	assertEqualInt(4, archive_entry_ctime(ae));
529 	assertEqualInt(5, archive_entry_mtime(ae));
530 	assertEqualString("file2", archive_entry_pathname(ae));
531 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
532 	assertEqualInt(2048, archive_entry_size(ae));
533 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
534 	memset(data, 'a', sizeof(data));
535 	assertEqualMem(buff2, data, 1024);
536 
537 	/*
538 	 * Read "file3" which has 2049 bytes data.
539 	 */
540 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
541 	assertEqualInt(2, archive_entry_atime(ae));
542 	assertEqualInt(4, archive_entry_ctime(ae));
543 	assertEqualInt(5, archive_entry_mtime(ae));
544 	assertEqualString("file3", archive_entry_pathname(ae));
545 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
546 	assertEqualInt(2049, archive_entry_size(ae));
547 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
548 	memset(data, 'Z', sizeof(data));
549 	assertEqualMem(buff2, data, 1024);
550 
551 	/*
552 	 * Read "file4" which has 32K bytes null data.
553 	 */
554 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
555 	assertEqualInt(2, archive_entry_atime(ae));
556 	assertEqualInt(4, archive_entry_ctime(ae));
557 	assertEqualInt(5, archive_entry_mtime(ae));
558 	assertEqualString("file4", archive_entry_pathname(ae));
559 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
560 	assertEqualInt(32768, archive_entry_size(ae));
561 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
562 	memset(data, 0, sizeof(data));
563 	assertEqualMem(buff2, data, 1024);
564 
565 	/*
566 	 * Verify the end of the archive.
567 	 */
568 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
569 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
570 	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
571 
572 	free(buff);
573 }
574 
575 /*
576  * Make a bootable ISO image with "zisofs" option.
577  */
578 static void
test_write_format_iso9660_zisofs_3(void)579 test_write_format_iso9660_zisofs_3(void)
580 {
581 	unsigned char buff2[1024];
582 	unsigned char nullb[2048];
583 	struct archive *a;
584 	struct archive_entry *ae;
585 	unsigned char *buff;
586 	size_t buffsize = 50 * 2048;
587 	size_t used;
588 	unsigned int i;
589 	int r;
590 
591 	memset(nullb, 0, sizeof(nullb));
592 	buff = malloc(buffsize);
593 	assert(buff != NULL);
594 	if (buff == NULL)
595 		return;
596 
597 	/* ISO9660 format: Create a new archive in memory. */
598 	assert((a = archive_write_new()) != NULL);
599 	assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
600 	assertEqualIntA(a, 0, archive_write_add_filter_none(a));
601 	r = archive_write_set_option(a, NULL, "zisofs", "1");
602 	if (r == ARCHIVE_FATAL) {
603 		skipping("zisofs option not supported on this platform");
604 		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
605 		free(buff);
606 		return;
607 	}
608 	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "boot", "boot.img"));
609 	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
610 	assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
611 
612 	/*
613 	 * "file1" has a bunch of attributes and 256K bytes of null data.
614 	 */
615 	assert((ae = archive_entry_new()) != NULL);
616 	archive_entry_set_atime(ae, 2, 20);
617 	archive_entry_set_birthtime(ae, 3, 30);
618 	archive_entry_set_ctime(ae, 4, 40);
619 	archive_entry_set_mtime(ae, 5, 50);
620 	archive_entry_copy_pathname(ae, "boot.img");
621 	archive_entry_set_mode(ae, S_IFREG | 0755);
622 	archive_entry_set_size(ae, 10*1024);
623 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
624 	archive_entry_free(ae);
625 	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
626 
627 	/*
628 	 * "file2" has a bunch of attributes and 2048 bytes of null data.
629 	 */
630 	assert((ae = archive_entry_new()) != NULL);
631 	archive_entry_set_atime(ae, 2, 20);
632 	archive_entry_set_birthtime(ae, 3, 30);
633 	archive_entry_set_ctime(ae, 4, 40);
634 	archive_entry_set_mtime(ae, 5, 50);
635 	archive_entry_copy_pathname(ae, "file2");
636 	archive_entry_set_mode(ae, S_IFREG | 0755);
637 	archive_entry_set_size(ae, 2048);
638 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
639 	archive_entry_free(ae);
640 	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
641 
642 	/*
643 	 * "file3" has a bunch of attributes and 2049 bytes of null data.
644 	 */
645 	assert((ae = archive_entry_new()) != NULL);
646 	archive_entry_set_atime(ae, 2, 20);
647 	archive_entry_set_birthtime(ae, 3, 30);
648 	archive_entry_set_ctime(ae, 4, 40);
649 	archive_entry_set_mtime(ae, 5, 50);
650 	archive_entry_copy_pathname(ae, "file3");
651 	archive_entry_set_mode(ae, S_IFREG | 0755);
652 	archive_entry_set_size(ae, 2049);
653 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
654 	archive_entry_free(ae);
655 	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
656 
657 	/* Close out the archive. */
658 	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
659 	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
660 
661 	failure("The ISO image size should be 81920 bytes.");
662 	assertEqualInt(used, 2048 * 40);
663 
664 	/* Check System Area. */
665 	for (i = 0; i < 2048 * 16; i++) {
666 		failure("System Area should be all nulls.");
667 		assertEqualInt(buff[i], 0);
668 	}
669 
670 	/* Primary Volume. */
671 	failure("Primary Volume Descriptor should be in 16 Logical Sector.");
672 	assertEqualMem(buff+2048*16, primary_id, 8);
673 	assertEqualMem(buff+2048*16+0x28,
674 	    "CDROM                           ", 32);
675 	assertEqualMem(buff+2048*16+0x50, volumesize3, 8);
676 
677 	/* Boot Volume. */
678 	failure("Boot Volume Descriptor should be in 17 Logical Sector.");
679 	assertEqualMem(buff+2048*17, boot_id, sizeof(boot_id));
680 	for (i = 0x27; i <= 0x46; i++) {
681 		failure("Unused area must be all nulls.");
682 		assert(buff[2048*17+i] == 0);
683 	}
684 	/* First sector of Boot Catalog. */
685 	assert(buff[2048*17+0x47] == 0x20);
686 	assert(buff[2048*17+0x48] == 0x00);
687 	assert(buff[2048*17+0x49] == 0x00);
688 	assert(buff[2048*17+0x4a] == 0x00);
689 	for (i = 0x4a; i <= 0x7ff; i++) {
690 		failure("Unused area must be all nulls.");
691 		assert(buff[2048*17+i] == 0);
692 	}
693 
694 	/* Supplementary Volume. */
695 	failure("Supplementary Volume(Joliet) Descriptor "
696 	    "should be in 18 Logical Sector.");
697 	assertEqualMem(buff+2048*18, supplementary_id, 8);
698 	assertEqualMem(buff+2048*18+0x28, volumeidu16, 32);
699 	assertEqualMem(buff+2048*18+0x50, volumesize3, 8);
700 	failure("Date and Time of Primary Volume and "
701 	    "Date and Time of Supplementary Volume "
702 	    "must be the same.");
703 	assertEqualMem(buff+2048*16+0x32d, buff+2048*18+0x32d, 0x44);
704 
705 	/* Terminator. */
706 	failure("Volume Descriptor Set Terminator "
707 	    "should be in 19 Logical Sector.");
708 	assertEqualMem(buff+2048*19, terminator_id, 8);
709 	for (i = 8; i < 2048; i++) {
710 		failure("Body of Volume Descriptor Set Terminator "
711 		    "should be all nulls.");
712 		assertEqualInt(buff[2048*19+i], 0);
713 	}
714 
715 	/* Check signature of El-Torito. */
716 	assertEqualMem(buff+2048*31, el_torito_signature, 237);
717 	assertEqualMem(buff+2048*31+237, nullb, 2048-237);
718 
719 	/* Check contents of "boot.catalog". */
720 	assertEqualMem(buff+2048*32, boot_catalog, 64);
721 	assertEqualMem(buff+2048*32+64, nullb, 2048-64);
722 
723 	/* Check contents of "boot.img". */
724 	failure("boot.img image should not be zisofs'ed.");
725 	assertEqualMem(buff+2048*33, nullb, 2048);
726 	for (i = 2048*34; i < 2048*38; i += 2048) {
727 		assertEqualMem(buff+i, nullb, 2048);
728 	}
729 
730 	/* "file2"  Contents is not zisofs data. */
731 	failure("file2 image should not be zisofs'ed.");
732 	assertEqualMem(buff+2048*38, nullb, 8);
733 	/* "file3"  Contents is zisofs data. */
734 	failure("file3 image should be zisofs'ed.");
735 	assertEqualMem(buff+2048*39, zisofs_magic, 8);
736 
737 	/*
738 	 * Read ISO image.
739 	 */
740 	assert((a = archive_read_new()) != NULL);
741 	assertEqualIntA(a, 0, archive_read_support_format_all(a));
742 	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
743 	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
744 
745 	/*
746 	 * Read Root Directory
747 	 * Root Directory entry must be in ISO image.
748 	 */
749 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
750 	assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
751 	assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
752 	assertEqualString(".", archive_entry_pathname(ae));
753 	assert((S_IFDIR | 0555) == archive_entry_mode(ae));
754 	assertEqualInt(2048, archive_entry_size(ae));
755 
756 	/*
757 	 * Read "boot.catalog".
758 	 */
759 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
760 	assertEqualString("boot.catalog", archive_entry_pathname(ae));
761 #if !defined(_WIN32) && !defined(__CYGWIN__)
762 	assert((S_IFREG | 0444) == archive_entry_mode(ae));
763 #else
764 	/* On Windows and CYGWIN, always set all exec bit ON by default. */
765 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
766 #endif
767 	assertEqualInt(1, archive_entry_nlink(ae));
768 	assertEqualInt(2*1024, archive_entry_size(ae));
769 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
770 	assertEqualMem(buff2, boot_catalog, 64);
771 
772 	/*
773 	 * Read "boot.img".
774 	 */
775 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
776 	assertEqualInt(2, archive_entry_atime(ae));
777 	assertEqualInt(3, archive_entry_birthtime(ae));
778 	assertEqualInt(4, archive_entry_ctime(ae));
779 	assertEqualInt(5, archive_entry_mtime(ae));
780 	assertEqualString("boot.img", archive_entry_pathname(ae));
781 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
782 	assertEqualInt(1, archive_entry_nlink(ae));
783 	assertEqualInt(10*1024, archive_entry_size(ae));
784 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
785 	assertEqualMem(buff2, nullb, 1024);
786 
787 	/*
788 	 * Read "file2" which has 2048 bytes null data.
789 	 */
790 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
791 	assertEqualInt(2, archive_entry_atime(ae));
792 	assertEqualInt(4, archive_entry_ctime(ae));
793 	assertEqualInt(5, archive_entry_mtime(ae));
794 	assertEqualString("file2", archive_entry_pathname(ae));
795 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
796 	assertEqualInt(2048, archive_entry_size(ae));
797 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
798 	assertEqualMem(buff2, nullb, 1024);
799 
800 	/*
801 	 * Read "file3" which has 2049 bytes null data.
802 	 */
803 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
804 	assertEqualInt(2, archive_entry_atime(ae));
805 	assertEqualInt(4, archive_entry_ctime(ae));
806 	assertEqualInt(5, archive_entry_mtime(ae));
807 	assertEqualString("file3", archive_entry_pathname(ae));
808 	assert((S_IFREG | 0555) == archive_entry_mode(ae));
809 	assertEqualInt(2049, archive_entry_size(ae));
810 	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
811 	assertEqualMem(buff2, nullb, 1024);
812 
813 	/*
814 	 * Verify the end of the archive.
815 	 */
816 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
817 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
818 	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
819 
820 	free(buff);
821 }
822 
DEFINE_TEST(test_write_format_iso9660_zisofs)823 DEFINE_TEST(test_write_format_iso9660_zisofs)
824 {
825 	test_write_format_iso9660_zisofs_1();
826 	test_write_format_iso9660_zisofs_2();
827 	test_write_format_iso9660_zisofs_3();
828 }
829