1 /*-
2 * Copyright (c) 2010 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 __FBSDID("$FreeBSD");
27
28 /*
29 Execute the following command to rebuild the data for this program:
30 tail -n +44 test_read_format_cab.c | /bin/sh
31 And following works are:
32 1. Move /tmp/cab/cab.zip to Windows PC
33 2. Extract cab.zip
34 3. Open command prompt and change current directory where you extracted cab.zip
35 4. Execute cab.bat
36 5. Then you will see that there is a cabinet file, test.cab
37 6. Move test.cab to posix platform
38 7. Extract test.cab with this version of bsdtar
39 8. Execute the following command to make uuencoded files.
40 uuencode test_read_format_cab_1.cab test_read_format_cab_1.cab > test_read_format_cab_1.cab.uu
41 uuencode test_read_format_cab_2.cab test_read_format_cab_2.cab > test_read_format_cab_2.cab.uu
42 uuencode test_read_format_cab_3.cab test_read_format_cab_3.cab > test_read_format_cab_3.cab.uu
43
44 #!/bin/sh
45 #
46 # How to make test data.
47 #
48 # Temporary directory.
49 base=/tmp/cab
50 # Owner id
51 owner=1001
52 # Group id
53 group=1001
54 #
55 # Make contents of a cabinet file.
56 #
57 rm -rf ${base}
58 mkdir ${base}
59 mkdir ${base}/dir1
60 mkdir ${base}/dir2
61 #
62 touch ${base}/empty
63 cat > ${base}/dir1/file1 << END
64 file 1 contents
65 hello
66 hello
67 hello
68 END
69 #
70 cat > ${base}/dir2/file2 << END
71 file 2 contents
72 hello
73 hello
74 hello
75 hello
76 hello
77 hello
78 END
79 #
80 dd if=/dev/zero of=${base}/zero bs=1 count=33000 > /dev/null 2>&1
81 #
82 cab1=test_read_format_cab_1.cab
83 cab2=test_read_format_cab_2.cab
84 cab3=test_read_format_cab_3.cab
85 #
86 #
87 cat > ${base}/mkcab1 << END
88 .Set Compress=OFF
89 .Set DiskDirectory1=.
90 .Set InfDate=1980-01-02
91 .Set InfTime=00:00:00
92 .Set CabinetName1=${cab1}
93 empty
94 .Set DestinationDir=dir1
95 dir1/file1
96 .Set DestinationDir=dir2
97 dir2/file2
98 END
99 #
100 cat > ${base}/mkcab2 << END
101 .Set CompressionType=MSZIP
102 .Set DiskDirectory1=.
103 .Set InfDate=1980-01-02
104 .Set InfTime=00:00:00
105 .Set CabinetName1=${cab2}
106 empty
107 zero
108 .Set DestinationDir=dir1
109 dir1/file1
110 .Set DestinationDir=dir2
111 dir2/file2
112 END
113 #
114 cat > ${base}/mkcab3 << END
115 .Set CompressionType=LZX
116 .Set DiskDirectory1=.
117 .Set InfDate=1980-01-02
118 .Set InfTime=00:00:00
119 .Set CabinetName1=${cab3}
120 empty
121 zero
122 .Set DestinationDir=dir1
123 dir1/file1
124 .Set DestinationDir=dir2
125 dir2/file2
126 END
127 #
128 cat > ${base}/mkcab4 << END
129 .Set CompressionType=MSZIP
130 .Set DiskDirectory1=.
131 .Set CabinetName1=test.cab
132 ${cab1}
133 ${cab2}
134 ${cab3}
135 END
136 #
137 cat > ${base}/cab.bat << END
138 makecab.exe /F mkcab1
139 makecab.exe /F mkcab2
140 makecab.exe /F mkcab3
141 makecab.exe /F mkcab4
142 del setup.inf setup.rpt
143 del empty zero dir1\file1 dir2\file2 mkcab1 mkcab2 mkcab3 mkcab4
144 del ${cab1} ${cab2} ${cab3}
145 rmdir dir1 dir2
146 END
147 #
148 f=cab.zip
149 (cd ${base}; zip -q -c $f empty zero dir1/file1 dir2/file2 mkcab1 mkcab2 mkcab3 mkcab4 cab.bat)
150 #
151 exit 1
152 */
153
154 static const char file1[] = {
155 " file 1 contents\n"
156 "hello\n"
157 "hello\n"
158 "hello\n"
159 };
160 #define file1_size (sizeof(file1)-1)
161 static const char file2[] = {
162 " file 2 contents\n"
163 "hello\n"
164 "hello\n"
165 "hello\n"
166 "hello\n"
167 "hello\n"
168 "hello\n"
169 };
170 #define file2_size (sizeof(file2)-1)
171
172 enum comp_type {
173 STORE = 0,
174 MSZIP,
175 LZX
176 };
177 static void
verify(const char * refname,enum comp_type comp)178 verify(const char *refname, enum comp_type comp)
179 {
180 struct archive_entry *ae;
181 struct archive *a;
182 char buff[128];
183 char zero[128];
184 size_t s;
185
186 memset(zero, 0, sizeof(zero));
187 extract_reference_file(refname);
188 assert((a = archive_read_new()) != NULL);
189 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
190 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
191 assertEqualIntA(a, ARCHIVE_OK,
192 archive_read_open_filename(a, refname, 10240));
193
194 /* Verify regular empty. */
195 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
196 assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
197 assertEqualString("empty", archive_entry_pathname(ae));
198 assertEqualInt(0, archive_entry_uid(ae));
199 assertEqualInt(0, archive_entry_gid(ae));
200 assertEqualInt(0, archive_entry_size(ae));
201 assertEqualInt(archive_entry_is_encrypted(ae), 0);
202 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
203
204 if (comp != STORE) {
205 /* Verify regular zero.
206 * Maximum CFDATA size is 32768, so we need over 32768 bytes
207 * file to check if we properly handle multiple CFDATA.
208 */
209 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
210 assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
211 assertEqualString("zero", archive_entry_pathname(ae));
212 assertEqualInt(0, archive_entry_uid(ae));
213 assertEqualInt(0, archive_entry_gid(ae));
214 assertEqualInt(archive_entry_is_encrypted(ae), 0);
215 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
216 assertEqualInt(33000, archive_entry_size(ae));
217 for (s = 0; s + sizeof(buff) < 33000; s+= sizeof(buff)) {
218 ssize_t rsize = archive_read_data(a, buff, sizeof(buff));
219 if (comp == MSZIP && rsize == ARCHIVE_FATAL && archive_zlib_version() == NULL) {
220 skipping("Skipping CAB format(MSZIP) check: %s",
221 archive_error_string(a));
222 goto finish;
223 }
224 assertEqualInt(sizeof(buff), rsize);
225 assertEqualMem(buff, zero, sizeof(buff));
226 }
227 assertEqualInt(33000 - s, archive_read_data(a, buff, 33000 - s));
228 assertEqualMem(buff, zero, 33000 - s);
229 }
230
231 /* Verify regular file1. */
232 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
233 assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
234 assertEqualString("dir1/file1", archive_entry_pathname(ae));
235 assertEqualInt(0, archive_entry_uid(ae));
236 assertEqualInt(0, archive_entry_gid(ae));
237 assertEqualInt(archive_entry_is_encrypted(ae), 0);
238 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
239 assertEqualInt(file1_size, archive_entry_size(ae));
240 assertEqualInt(file1_size, archive_read_data(a, buff, file1_size));
241 assertEqualMem(buff, file1, file1_size);
242
243 /* Verify regular file2. */
244 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
245 assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
246 assertEqualString("dir2/file2", archive_entry_pathname(ae));
247 assertEqualInt(0, archive_entry_uid(ae));
248 assertEqualInt(0, archive_entry_gid(ae));
249 assertEqualInt(archive_entry_is_encrypted(ae), 0);
250 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
251 assertEqualInt(file2_size, archive_entry_size(ae));
252 assertEqualInt(file2_size, archive_read_data(a, buff, file2_size));
253 assertEqualMem(buff, file2, file2_size);
254
255 /* End of archive. */
256 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
257
258 if (comp != STORE) {
259 assertEqualInt(4, archive_file_count(a));
260 } else {
261 assertEqualInt(3, archive_file_count(a));
262 }
263
264 /* Verify archive format. */
265 assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
266 assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a));
267
268 /* Close the archive. */
269 finish:
270 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
271 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
272 }
273
274 /*
275 * Skip beginning files and Read the last file.
276 */
277 static void
verify2(const char * refname,enum comp_type comp)278 verify2(const char *refname, enum comp_type comp)
279 {
280 struct archive_entry *ae;
281 struct archive *a;
282 char buff[128];
283 char zero[128];
284
285 if (comp == MSZIP && archive_zlib_version() == NULL) {
286 skipping("Skipping CAB format(MSZIP) check for %s",
287 refname);
288 return;
289 }
290 memset(zero, 0, sizeof(zero));
291 extract_reference_file(refname);
292 assert((a = archive_read_new()) != NULL);
293 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
294 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
295 assertEqualIntA(a, ARCHIVE_OK,
296 archive_read_open_filename(a, refname, 10240));
297
298 /* Verify regular empty. */
299 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
300 assertEqualInt(archive_entry_is_encrypted(ae), 0);
301 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
302 if (comp != STORE) {
303 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
304 assertEqualInt(archive_entry_is_encrypted(ae), 0);
305 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
306 }
307 /* Verify regular file1. */
308 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
309 assertEqualInt(archive_entry_is_encrypted(ae), 0);
310 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
311
312 /* Verify regular file2. */
313 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
314 assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
315 assertEqualString("dir2/file2", archive_entry_pathname(ae));
316 assertEqualInt(0, archive_entry_uid(ae));
317 assertEqualInt(0, archive_entry_gid(ae));
318 assertEqualInt(file2_size, archive_entry_size(ae));
319 assertEqualInt(file2_size, archive_read_data(a, buff, file2_size));
320 assertEqualMem(buff, file2, file2_size);
321
322 /* End of archive. */
323 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
324
325 if (comp != STORE) {
326 assertEqualInt(4, archive_file_count(a));
327 } else {
328 assertEqualInt(3, archive_file_count(a));
329 }
330
331 /* Verify archive format. */
332 assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
333 assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a));
334
335 /* Close the archive. */
336 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
337 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
338 }
339
340 /*
341 * Skip all file like 'bsdtar tvf foo.cab'.
342 */
343 static void
verify3(const char * refname,enum comp_type comp)344 verify3(const char *refname, enum comp_type comp)
345 {
346 struct archive_entry *ae;
347 struct archive *a;
348 char zero[128];
349
350 memset(zero, 0, sizeof(zero));
351 extract_reference_file(refname);
352 assert((a = archive_read_new()) != NULL);
353 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
354 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
355 assertEqualIntA(a, ARCHIVE_OK,
356 archive_read_open_filename(a, refname, 10240));
357
358 /* Verify regular empty. */
359 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
360 assertEqualInt(archive_entry_is_encrypted(ae), 0);
361 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
362 if (comp != STORE) {
363 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
364 assertEqualInt(archive_entry_is_encrypted(ae), 0);
365 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
366 }
367 /* Verify regular file1. */
368 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
369 assertEqualInt(archive_entry_is_encrypted(ae), 0);
370 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
371
372 /* Verify regular file2. */
373 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
374 assertEqualInt(archive_entry_is_encrypted(ae), 0);
375 assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
376
377 /* End of archive. */
378 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
379
380 if (comp != STORE) {
381 assertEqualInt(4, archive_file_count(a));
382 } else {
383 assertEqualInt(3, archive_file_count(a));
384 }
385
386 /* Verify archive format. */
387 assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
388 assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a));
389
390 /* Close the archive. */
391 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
392 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
393 }
394
DEFINE_TEST(test_read_format_cab)395 DEFINE_TEST(test_read_format_cab)
396 {
397 /* Verify Cabinet file in no compression. */
398 verify("test_read_format_cab_1.cab", STORE);
399 verify2("test_read_format_cab_1.cab", STORE);
400 verify3("test_read_format_cab_1.cab", STORE);
401 /* Verify Cabinet file in MSZIP. */
402 verify("test_read_format_cab_2.cab", MSZIP);
403 verify2("test_read_format_cab_2.cab", MSZIP);
404 verify3("test_read_format_cab_2.cab", MSZIP);
405 /* Verify Cabinet file in LZX. */
406 verify("test_read_format_cab_3.cab", LZX);
407 verify2("test_read_format_cab_3.cab", LZX);
408 verify3("test_read_format_cab_3.cab", LZX);
409 }
410
411