1 /*-
2 * Copyright (c) 2003-2008 Tim Kientzle
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 static char buff2[64];
28
DEFINE_TEST(test_write_format_pax)29 DEFINE_TEST(test_write_format_pax)
30 {
31 size_t buffsize = 1000000;
32 char *buff;
33 struct archive_entry *ae;
34 struct archive *a;
35 size_t used;
36 int i;
37 char nulls[1024];
38 int64_t offset, length;
39 char long_slashes[300 + 1];
40
41 buff = malloc(buffsize); /* million bytes of work area */
42 assert(buff != NULL);
43
44 /* Create a new archive in memory. */
45 assert((a = archive_write_new()) != NULL);
46 assertA(0 == archive_write_set_format_pax(a));
47 assertA(0 == archive_write_add_filter_none(a));
48 assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
49
50 /*
51 * "file" has a bunch of attributes and 8 bytes of data.
52 */
53 assert((ae = archive_entry_new()) != NULL);
54 archive_entry_set_atime(ae, 2, 20);
55 archive_entry_set_birthtime(ae, 3, 30);
56 archive_entry_set_ctime(ae, 4, 40);
57 archive_entry_set_mtime(ae, 5, 50);
58 archive_entry_copy_pathname(ae, "file");
59 archive_entry_set_mode(ae, S_IFREG | 0755);
60 archive_entry_set_size(ae, 8);
61 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
62 archive_entry_free(ae);
63 assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
64
65 /*
66 * "file2" is similar but has birthtime later than mtime.
67 */
68 assert((ae = archive_entry_new()) != NULL);
69 archive_entry_set_atime(ae, 2, 20);
70 archive_entry_set_birthtime(ae, 8, 80);
71 archive_entry_set_ctime(ae, 4, 40);
72 archive_entry_set_mtime(ae, 5, 50);
73 archive_entry_copy_pathname(ae, "file2");
74 archive_entry_set_mode(ae, S_IFREG | 0755);
75 archive_entry_set_size(ae, 8);
76 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
77 archive_entry_free(ae);
78 assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
79
80 /*
81 * "file3" is sparse file and has hole size of which is
82 * 1024000 bytes, and has 8 bytes data after the hole.
83 *
84 * Pad the filename to make it larger than the ustar limit.
85 * It should still read back correctly.
86 */
87 assert((ae = archive_entry_new()) != NULL);
88 archive_entry_set_atime(ae, 2, 20);
89 archive_entry_set_birthtime(ae, 3, 30);
90 archive_entry_set_ctime(ae, 4, 40);
91 archive_entry_set_mtime(ae, 5, 50);
92 archive_entry_copy_pathname(ae, "file3"
93 "_123456789_123456789_123456789_123456789_123456789"
94 "_123456789_123456789_123456789_123456789_123456789"
95 "_123456789_123456789_123456789_123456789_123456789");
96 archive_entry_set_mode(ae, S_IFREG | 0755);
97 archive_entry_set_size(ae, 1024008);
98 archive_entry_sparse_add_entry(ae, 1024000, 8);
99 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
100 archive_entry_free(ae);
101 memset(nulls, 0, sizeof(nulls));
102 for (i = 0; i < 1024000; i += 1024)
103 /* write hole data, which won't be stored into an archive file. */
104 assertEqualIntA(a, 1024, archive_write_data(a, nulls, 1024));
105 assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
106
107 /*
108 * "file4" is similar to "file1" but has a large uid, large gid,
109 * uname and gname are longer than 32 characters
110 */
111 assert((ae = archive_entry_new()) != NULL);
112 archive_entry_set_atime(ae, 2, 20);
113 archive_entry_set_birthtime(ae, 3, 30);
114 archive_entry_set_ctime(ae, 4, 40);
115 archive_entry_set_mtime(ae, 5, 50);
116 archive_entry_copy_pathname(ae, "file4");
117 archive_entry_set_mode(ae, S_IFREG | 0755);
118 archive_entry_set_size(ae, 8);
119 archive_entry_copy_uname(ae,
120 "long-uname123456789012345678901234567890");
121 archive_entry_copy_gname(ae,
122 "long-gname123456789012345678901234567890");
123 archive_entry_set_uid(ae, 536870912);
124 archive_entry_set_gid(ae, 536870913);
125 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
126 archive_entry_free(ae);
127 assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
128
129 /*
130 * A pathname made entirely of '/' characters used to trigger an
131 * out-of-bounds read in the pax writer when the pathname was long
132 * enough to require USTAR name splitting.
133 */
134 memset(long_slashes, '/', 300);
135 long_slashes[300] = '\0';
136 assert((ae = archive_entry_new()) != NULL);
137 archive_entry_set_atime(ae, 2, 20);
138 archive_entry_set_ctime(ae, 4, 40);
139 archive_entry_set_mtime(ae, 5, 50);
140 archive_entry_copy_pathname(ae, long_slashes);
141 archive_entry_set_mode(ae, S_IFREG | 0644);
142 archive_entry_set_size(ae, 0);
143 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
144 archive_entry_free(ae);
145
146 /*
147 * XXX TODO XXX Archive directory, other file types.
148 * Archive extended attributes, ACLs, other metadata.
149 * Verify they get read back correctly.
150 */
151
152 /* Close out the archive. */
153 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
154 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
155
156 /*
157 *
158 * Now, read the data back.
159 *
160 */
161 assert((a = archive_read_new()) != NULL);
162 assertEqualIntA(a, 0, archive_read_support_format_all(a));
163 assertEqualIntA(a, 0, archive_read_support_filter_all(a));
164 assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
165
166 /*
167 * Read "file"
168 */
169 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
170 assertEqualInt(2, archive_entry_atime(ae));
171 assertEqualInt(20, archive_entry_atime_nsec(ae));
172 assertEqualInt(3, archive_entry_birthtime(ae));
173 assertEqualInt(30, archive_entry_birthtime_nsec(ae));
174 assertEqualInt(4, archive_entry_ctime(ae));
175 assertEqualInt(40, archive_entry_ctime_nsec(ae));
176 assertEqualInt(5, archive_entry_mtime(ae));
177 assertEqualInt(50, archive_entry_mtime_nsec(ae));
178 assertEqualString("file", archive_entry_pathname(ae));
179 assert((S_IFREG | 0755) == archive_entry_mode(ae));
180 assertEqualInt(8, archive_entry_size(ae));
181 assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
182 assertEqualMem(buff2, "12345678", 8);
183
184 /*
185 * Read "file2"
186 */
187 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
188 assert(archive_entry_atime_is_set(ae));
189 assertEqualInt(2, archive_entry_atime(ae));
190 assertEqualInt(20, archive_entry_atime_nsec(ae));
191 /* Birthtime > mtime above, so it doesn't get stored at all. */
192 assert(!archive_entry_birthtime_is_set(ae));
193 assertEqualInt(0, archive_entry_birthtime(ae));
194 assertEqualInt(0, archive_entry_birthtime_nsec(ae));
195 assert(archive_entry_ctime_is_set(ae));
196 assertEqualInt(4, archive_entry_ctime(ae));
197 assertEqualInt(40, archive_entry_ctime_nsec(ae));
198 assert(archive_entry_mtime_is_set(ae));
199 assertEqualInt(5, archive_entry_mtime(ae));
200 assertEqualInt(50, archive_entry_mtime_nsec(ae));
201 assertEqualString("file2", archive_entry_pathname(ae));
202 assert((S_IFREG | 0755) == archive_entry_mode(ae));
203 assertEqualInt(8, archive_entry_size(ae));
204 assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
205 assertEqualMem(buff2, "12345678", 8);
206
207 /*
208 * Read "file3"
209 */
210 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
211 assertEqualInt(2, archive_entry_atime(ae));
212 assertEqualInt(20, archive_entry_atime_nsec(ae));
213 assertEqualInt(3, archive_entry_birthtime(ae));
214 assertEqualInt(30, archive_entry_birthtime_nsec(ae));
215 assertEqualInt(4, archive_entry_ctime(ae));
216 assertEqualInt(40, archive_entry_ctime_nsec(ae));
217 assertEqualInt(5, archive_entry_mtime(ae));
218 assertEqualInt(50, archive_entry_mtime_nsec(ae));
219 assertEqualString("file3"
220 "_123456789_123456789_123456789_123456789_123456789"
221 "_123456789_123456789_123456789_123456789_123456789"
222 "_123456789_123456789_123456789_123456789_123456789",
223 archive_entry_pathname(ae));
224 assert((S_IFREG | 0755) == archive_entry_mode(ae));
225 assertEqualInt(1024008, archive_entry_size(ae));
226 assertEqualInt(1, archive_entry_sparse_reset(ae));
227 assertEqualInt(ARCHIVE_OK,
228 archive_entry_sparse_next(ae, &offset, &length));
229 assertEqualInt(1024000, offset);
230 assertEqualInt(8, length);
231 for (i = 0; i < 1024000; i += 1024) {
232 int j;
233 assertEqualIntA(a, 1024, archive_read_data(a, nulls, 1024));
234 for (j = 0; j < 1024; j++)
235 assertEqualInt(0, nulls[j]);
236 }
237 assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
238 assertEqualMem(buff2, "12345678", 8);
239
240 /*
241 * Read "file4
242 */
243 assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
244 assertEqualInt(2, archive_entry_atime(ae));
245 assertEqualInt(20, archive_entry_atime_nsec(ae));
246 assertEqualInt(3, archive_entry_birthtime(ae));
247 assertEqualInt(30, archive_entry_birthtime_nsec(ae));
248 assertEqualInt(4, archive_entry_ctime(ae));
249 assertEqualInt(40, archive_entry_ctime_nsec(ae));
250 assertEqualInt(5, archive_entry_mtime(ae));
251 assertEqualInt(50, archive_entry_mtime_nsec(ae));
252 assertEqualString("file4", archive_entry_pathname(ae));
253 assertEqualString("long-uname123456789012345678901234567890",
254 archive_entry_uname(ae));
255 assertEqualString("long-gname123456789012345678901234567890",
256 archive_entry_gname(ae));
257 assertEqualInt(536870912, archive_entry_uid(ae));
258 assertEqualInt(536870913, archive_entry_gid(ae));
259 assert((S_IFREG | 0755) == archive_entry_mode(ae));
260 assertEqualInt(8, archive_entry_size(ae));
261 assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
262 assertEqualMem(buff2, "12345678", 8);
263
264 /*
265 * Read the all-slash pathname entry.
266 */
267 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
268 assertEqualString(long_slashes, archive_entry_pathname(ae));
269 assertEqualInt(2, archive_entry_atime(ae));
270 assertEqualInt(20, archive_entry_atime_nsec(ae));
271 assertEqualInt(4, archive_entry_ctime(ae));
272 assertEqualInt(40, archive_entry_ctime_nsec(ae));
273 assertEqualInt(5, archive_entry_mtime(ae));
274 assertEqualInt(50, archive_entry_mtime_nsec(ae));
275 assertEqualInt(0, archive_entry_size(ae));
276
277 /*
278 * Verify the end of the archive.
279 */
280 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
281 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
282 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
283
284 free(buff);
285 }
286