2 * Copyright (c) 2003-2007 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
26 __FBSDID("$FreeBSD$");
28 DEFINE_TEST(test_read_pax_truncated)
30 struct archive_entry *ae;
32 size_t used, i, buff_size = 1000000;
33 size_t filedata_size = 100000;
34 char *buff = malloc(buff_size);
35 char *buff2 = malloc(buff_size);
36 char *filedata = malloc(filedata_size);
38 /* Create a new archive in memory. */
39 assert((a = archive_write_new()) != NULL);
40 assertA(0 == archive_write_set_format_pax(a));
41 assertA(0 == archive_write_set_compression_none(a));
42 assertEqualIntA(a, ARCHIVE_OK,
43 archive_write_open_memory(a, buff, buff_size, &used));
48 assert((ae = archive_entry_new()) != NULL);
49 archive_entry_copy_pathname(ae, "file");
50 archive_entry_set_mode(ae, S_IFREG | 0755);
51 for (i = 0; i < filedata_size; i++)
52 filedata[i] = (unsigned char)rand();
53 archive_entry_set_atime(ae, 1, 2);
54 archive_entry_set_ctime(ae, 3, 4);
55 archive_entry_set_mtime(ae, 5, 6);
56 archive_entry_set_size(ae, filedata_size);
57 assertA(0 == archive_write_header(a, ae));
58 archive_entry_free(ae);
59 assertA((ssize_t)filedata_size
60 == archive_write_data(a, filedata, filedata_size));
62 /* Close out the archive. */
63 assertA(0 == archive_write_close(a));
64 #if ARCHIVE_VERSION_NUMBER < 2000000
65 archive_write_finish(a);
67 assertA(0 == archive_write_finish(a));
70 /* Now, read back a truncated version of the archive and
71 * verify that we get an appropriate error. */
72 for (i = 1; i < used + 100; i += 100) {
73 assert((a = archive_read_new()) != NULL);
74 assertA(0 == archive_read_support_format_all(a));
75 assertA(0 == archive_read_support_compression_all(a));
76 assertA(0 == read_open_memory2(a, buff, i, 13));
79 assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
82 failure("Archive truncated to %d bytes", i);
83 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
86 if (i < 1536 + filedata_size) {
87 assertA(ARCHIVE_FATAL == archive_read_data(a, filedata, filedata_size));
90 failure("Archive truncated to %d bytes", i);
91 assertEqualIntA(a, filedata_size,
92 archive_read_data(a, filedata, filedata_size));
95 /* Verify the end of the archive. */
96 /* Archive must be long enough to capture a 512-byte
97 * block of zeroes after the entry. (POSIX requires a
98 * second block of zeros to be written but libarchive
99 * does not return an error if it can't consume
101 if (i < 1536 + 512*((filedata_size + 511)/512) + 512) {
102 failure("i=%d minsize=%d", i,
103 1536 + 512*((filedata_size + 511)/512) + 512);
104 assertEqualIntA(a, ARCHIVE_FATAL,
105 archive_read_next_header(a, &ae));
107 assertEqualIntA(a, ARCHIVE_EOF,
108 archive_read_next_header(a, &ae));
111 assert(0 == archive_read_close(a));
112 #if ARCHIVE_VERSION_NUMBER < 2000000
113 archive_read_finish(a);
115 assert(0 == archive_read_finish(a));
121 /* Same as above, except skip the body instead of reading it. */
122 for (i = 1; i < used + 100; i += 100) {
123 assert((a = archive_read_new()) != NULL);
124 assertA(0 == archive_read_support_format_all(a));
125 assertA(0 == archive_read_support_compression_all(a));
126 assertA(0 == read_open_memory(a, buff, i, 7));
129 assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
132 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
135 if (i < 1536 + 512*((filedata_size+511)/512)) {
136 assertA(ARCHIVE_FATAL == archive_read_data_skip(a));
139 assertA(ARCHIVE_OK == archive_read_data_skip(a));
142 /* Verify the end of the archive. */
143 /* Archive must be long enough to capture a 512-byte
144 * block of zeroes after the entry. (POSIX requires a
145 * second block of zeros to be written but libarchive
146 * does not return an error if it can't consume
148 if (i < 1536 + 512*((filedata_size + 511)/512) + 512) {
149 assertEqualIntA(a, ARCHIVE_FATAL,
150 archive_read_next_header(a, &ae));
152 assertEqualIntA(a, ARCHIVE_EOF,
153 archive_read_next_header(a, &ae));
156 assert(0 == archive_read_close(a));
157 #if ARCHIVE_VERSION_NUMBER < 2000000
158 archive_read_finish(a);
160 assert(0 == archive_read_finish(a));
164 /* Now, damage the archive in various ways and test the responses. */
166 /* Damage the first size field in the pax attributes. */
167 memcpy(buff2, buff, buff_size);
170 buff2[514] = 'A'; /* Non-digit in size. */
171 assert((a = archive_read_new()) != NULL);
172 assertA(0 == archive_read_support_format_all(a));
173 assertA(0 == archive_read_support_compression_all(a));
174 assertA(0 == archive_read_open_memory(a, buff2, used));
175 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
176 assert(0 == archive_read_close(a));
177 #if ARCHIVE_VERSION_NUMBER < 2000000
178 archive_read_finish(a);
180 assert(0 == archive_read_finish(a));
183 /* Damage the size field in the pax attributes. */
184 memcpy(buff2, buff, buff_size);
185 buff2[512] = 'A'; /* First character not a digit. */
186 assert((a = archive_read_new()) != NULL);
187 assertA(0 == archive_read_support_format_all(a));
188 assertA(0 == archive_read_support_compression_all(a));
189 assertA(0 == archive_read_open_memory(a, buff2, used));
190 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
191 assert(0 == archive_read_close(a));
192 #if ARCHIVE_VERSION_NUMBER < 2000000
193 archive_read_finish(a);
195 assert(0 == archive_read_finish(a));
198 /* Damage the size field in the pax attributes. */
199 memcpy(buff2, buff, buff_size);
200 for (i = 512; i < 520; i++) /* Size over 999999. */
203 assert((a = archive_read_new()) != NULL);
204 assertA(0 == archive_read_support_format_all(a));
205 assertA(0 == archive_read_support_compression_all(a));
206 assertA(0 == archive_read_open_memory(a, buff2, used));
207 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
208 assert(0 == archive_read_close(a));
209 #if ARCHIVE_VERSION_NUMBER < 2000000
210 archive_read_finish(a);
212 assert(0 == archive_read_finish(a));
215 /* Damage the size field in the pax attributes. */
216 memcpy(buff2, buff, buff_size);
217 buff2[512] = '9'; /* Valid format, but larger than attribute area. */
221 assert((a = archive_read_new()) != NULL);
222 assertA(0 == archive_read_support_format_all(a));
223 assertA(0 == archive_read_support_compression_all(a));
224 assertA(0 == archive_read_open_memory(a, buff2, used));
225 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
226 assert(0 == archive_read_close(a));
227 #if ARCHIVE_VERSION_NUMBER < 2000000
228 archive_read_finish(a);
230 assert(0 == archive_read_finish(a));
233 /* Damage the size field in the pax attributes. */
234 memcpy(buff2, buff, buff_size);
235 buff2[512] = '1'; /* Too small. */
237 assert((a = archive_read_new()) != NULL);
238 assertA(0 == archive_read_support_format_all(a));
239 assertA(0 == archive_read_support_compression_all(a));
240 assertA(0 == archive_read_open_memory(a, buff2, used));
241 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
242 assert(0 == archive_read_close(a));
243 #if ARCHIVE_VERSION_NUMBER < 2000000
244 archive_read_finish(a);
246 assert(0 == archive_read_finish(a));
249 /* Damage the size field in the pax attributes. */
250 memcpy(buff2, buff, buff_size);
251 buff2[512] = ' '; /* No size given. */
252 assert((a = archive_read_new()) != NULL);
253 assertA(0 == archive_read_support_format_all(a));
254 assertA(0 == archive_read_support_compression_all(a));
255 assertA(0 == archive_read_open_memory(a, buff2, used));
256 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
257 assert(0 == archive_read_close(a));
258 #if ARCHIVE_VERSION_NUMBER < 2000000
259 archive_read_finish(a);
261 assert(0 == archive_read_finish(a));
264 /* Damage the ustar header. */
265 memcpy(buff2, buff, buff_size);
266 buff2[1024]++; /* Break the checksum. */
267 assert((a = archive_read_new()) != NULL);
268 assertA(0 == archive_read_support_format_all(a));
269 assertA(0 == archive_read_support_compression_all(a));
270 assertA(0 == archive_read_open_memory(a, buff2, used));
271 assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
272 assert(0 == archive_read_close(a));
273 #if ARCHIVE_VERSION_NUMBER < 2000000
274 archive_read_finish(a);
276 assert(0 == archive_read_finish(a));
280 * TODO: Damage the ustar header in various ways and fixup the
281 * checksum in order to test boundary cases in the innermost
282 * ustar header parsing.