1231200Smm/*-
2231200Smm * Copyright (c) 2009-2011 Michihiro NAKAJIMA
3231200Smm * All rights reserved.
4231200Smm *
5231200Smm * Redistribution and use in source and binary forms, with or without
6231200Smm * modification, are permitted provided that the following conditions
7231200Smm * are met:
8231200Smm * 1. Redistributions of source code must retain the above copyright
9231200Smm *    notice, this list of conditions and the following disclaimer.
10231200Smm * 2. Redistributions in binary form must reproduce the above copyright
11231200Smm *    notice, this list of conditions and the following disclaimer in the
12231200Smm *    documentation and/or other materials provided with the distribution.
13231200Smm *
14231200Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15231200Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16231200Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17231200Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18231200Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19231200Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20231200Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21231200Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22231200Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23231200Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24231200Smm */
25231200Smm#include "test.h"
26231200Smm
27231200Smm/*
28231200Smm * Check that an "empty" ISO 9660 image is correctly created.
29231200Smm */
30231200Smm
31231200Smmstatic const unsigned char primary_id[] = {
32231200Smm    0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
33231200Smm};
34231200Smmstatic const unsigned char volumesize[] = {
35231200Smm    0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5
36231200Smm};
37231200Smmstatic const unsigned char volumeidu16[] = {
38231200Smm    0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f,
39231200Smm    0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
40231200Smm    0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
41231200Smm    0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20
42231200Smm};
43231200Smmstatic const unsigned char supplementary_id[] = {
44231200Smm    0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
45231200Smm};
46231200Smmstatic const unsigned char terminator_id[] = {
47231200Smm    0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
48231200Smm};
49231200Smm
50231200SmmDEFINE_TEST(test_write_format_iso9660_empty)
51231200Smm{
52231200Smm	struct archive *a;
53231200Smm	struct archive_entry *ae;
54231200Smm	unsigned char *buff;
55231200Smm	size_t buffsize = 190 * 2048;
56231200Smm	size_t used;
57231200Smm	unsigned int i;
58231200Smm
59231200Smm	buff = malloc(buffsize);
60231200Smm	assert(buff != NULL);
61248616Smm	if (buff == NULL)
62248616Smm		return;
63231200Smm
64231200Smm	/* ISO9660 format: Create a new archive in memory. */
65231200Smm	assert((a = archive_write_new()) != NULL);
66231200Smm	assertA(0 == archive_write_set_format_iso9660(a));
67248616Smm	assertA(0 == archive_write_add_filter_none(a));
68231200Smm	assertA(0 == archive_write_set_bytes_per_block(a, 1));
69231200Smm	assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
70231200Smm	assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
71231200Smm
72231200Smm	/* Add "." entry which must be ignored. */
73231200Smm	assert((ae = archive_entry_new()) != NULL);
74231200Smm	archive_entry_set_atime(ae, 2, 0);
75231200Smm	archive_entry_set_ctime(ae, 4, 0);
76231200Smm	archive_entry_set_mtime(ae, 5, 0);
77231200Smm	archive_entry_copy_pathname(ae, ".");
78231200Smm	archive_entry_set_mode(ae, S_IFDIR | 0755);
79231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
80231200Smm	archive_entry_free(ae);
81231200Smm
82231200Smm	/* Add ".." entry which must be ignored. */
83231200Smm	assert((ae = archive_entry_new()) != NULL);
84231200Smm	archive_entry_set_atime(ae, 2, 0);
85231200Smm	archive_entry_set_ctime(ae, 4, 0);
86231200Smm	archive_entry_set_mtime(ae, 5, 0);
87231200Smm	archive_entry_copy_pathname(ae, "..");
88231200Smm	archive_entry_set_mode(ae, S_IFDIR | 0755);
89231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
90231200Smm	archive_entry_free(ae);
91231200Smm
92231200Smm	/* Add "/" entry which must be ignored. */
93231200Smm	assert((ae = archive_entry_new()) != NULL);
94231200Smm	archive_entry_set_atime(ae, 2, 0);
95231200Smm	archive_entry_set_ctime(ae, 4, 0);
96231200Smm	archive_entry_set_mtime(ae, 5, 0);
97231200Smm	archive_entry_copy_pathname(ae, "/");
98231200Smm	archive_entry_set_mode(ae, S_IFDIR | 0755);
99231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
100231200Smm	archive_entry_free(ae);
101231200Smm
102231200Smm	/* Add "../" entry which must be ignored. */
103231200Smm	assert((ae = archive_entry_new()) != NULL);
104231200Smm	archive_entry_set_atime(ae, 2, 0);
105231200Smm	archive_entry_set_ctime(ae, 4, 0);
106231200Smm	archive_entry_set_mtime(ae, 5, 0);
107231200Smm	archive_entry_copy_pathname(ae, "../");
108231200Smm	archive_entry_set_mode(ae, S_IFDIR | 0755);
109231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
110231200Smm	archive_entry_free(ae);
111231200Smm
112231200Smm	/* Add "../../." entry which must be ignored. */
113231200Smm	assert((ae = archive_entry_new()) != NULL);
114231200Smm	archive_entry_set_atime(ae, 2, 0);
115231200Smm	archive_entry_set_ctime(ae, 4, 0);
116231200Smm	archive_entry_set_mtime(ae, 5, 0);
117231200Smm	archive_entry_copy_pathname(ae, "../../.");
118231200Smm	archive_entry_set_mode(ae, S_IFDIR | 0755);
119231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
120231200Smm	archive_entry_free(ae);
121231200Smm
122231200Smm	/* Add "..//.././" entry which must be ignored. */
123231200Smm	assert((ae = archive_entry_new()) != NULL);
124231200Smm	archive_entry_set_atime(ae, 2, 0);
125231200Smm	archive_entry_set_ctime(ae, 4, 0);
126231200Smm	archive_entry_set_mtime(ae, 5, 0);
127231200Smm	archive_entry_copy_pathname(ae, "..//.././");
128231200Smm	archive_entry_set_mode(ae, S_IFDIR | 0755);
129231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
130231200Smm	archive_entry_free(ae);
131231200Smm
132231200Smm	/* Close out the archive. */
133231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
134231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
135231200Smm
136231200Smm	assert(used == 2048 * 181);
137231200Smm	/* Check System Area. */
138231200Smm	for (i = 0; i < 2048 * 16; i++) {
139231200Smm		failure("System Area should be all nulls.");
140231200Smm		assert(buff[i] == 0);
141231200Smm	}
142231200Smm
143231200Smm	/* Primary Volume. */
144231200Smm	failure("Primary Volume Descriptor should be in 16 Logical Sector.");
145231200Smm	assertEqualMem(buff+2048*16, primary_id, 8);
146231200Smm	assertEqualMem(buff+2048*16+0x28,
147231200Smm	    "CDROM                           ", 32);
148231200Smm	assertEqualMem(buff+2048*16+0x50, volumesize, 8);
149231200Smm
150231200Smm	/* Supplementary Volume. */
151231200Smm	failure("Supplementary Volume(Joliet) Descriptor "
152231200Smm	    "should be in 17 Logical Sector.");
153231200Smm	assertEqualMem(buff+2048*17, supplementary_id, 8);
154231200Smm	assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
155231200Smm	assertEqualMem(buff+2048*17+0x50, volumesize, 8);
156231200Smm	failure("Date and Time of Primary Volume and "
157231200Smm	    "Date and Time of Supplementary Volume "
158231200Smm	    "must be the same.");
159231200Smm	assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
160231200Smm
161231200Smm	/* Terminator. */
162231200Smm	failure("Volume Descriptor Set Terminator "
163231200Smm	    "should be in 18 Logical Sector.");
164231200Smm	assertEqualMem(buff+2048*18, terminator_id, 8);
165231200Smm	for (i = 8; i < 2048; i++) {
166231200Smm		failure("Body of Volume Descriptor Set Terminator "
167231200Smm		    "should be all nulls.");
168231200Smm		assert(buff[2048*18+i] == 0);
169231200Smm	}
170231200Smm
171231200Smm	/* Padding data. */
172231200Smm	for (i = 0; i < 2048*150; i++) {
173231200Smm		failure("Padding data should be all nulls.");
174231200Smm		assert(buff[2048*31+i] == 0);
175231200Smm	}
176231200Smm
177231200Smm	/*
178231200Smm	 * Read ISO image.
179231200Smm	 */
180231200Smm	assert((a = archive_read_new()) != NULL);
181231200Smm	assertEqualIntA(a, 0, archive_read_support_format_all(a));
182231200Smm	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
183231200Smm	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
184231200Smm
185231200Smm	/*
186231200Smm	 * Read Root Directory
187231200Smm	 * Root Directory entry must be in ISO image.
188231200Smm	 */
189231200Smm	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
190231200Smm	assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
191231200Smm	assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
192231200Smm	assertEqualString(".", archive_entry_pathname(ae));
193231200Smm	assert((S_IFDIR | 0555) == archive_entry_mode(ae));
194231200Smm	assertEqualInt(2048, archive_entry_size(ae));
195231200Smm
196231200Smm	/*
197231200Smm	 * Verify the end of the archive.
198231200Smm	 */
199231200Smm	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
200231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
201231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
202231200Smm
203231200Smm	free(buff);
204231200Smm}
205