test_read_format_cab.c revision 302001
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/*
29Execute the following command to rebuild the data for this program:
30   tail -n +44 test_read_format_cab.c | /bin/sh
31And following works are:
321. Move /tmp/cab/cab.zip to Windows PC
332. Extract cab.zip
343. Open command prompt and change current directory where you extracted cab.zip
354. Execute cab.bat
365. Then you will see that there is a cabinet file, test.cab
376. Move test.cab to posix platform
387. Extract test.cab with this version of bsdtar
398. 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.
49base=/tmp/cab
50# Owner id
51owner=1001
52# Group id
53group=1001
54#
55# Make contents of a cabinet file.
56#
57rm -rf ${base}
58mkdir ${base}
59mkdir ${base}/dir1
60mkdir ${base}/dir2
61#
62touch ${base}/empty
63cat > ${base}/dir1/file1 << END
64                          file 1 contents
65hello
66hello
67hello
68END
69#
70cat > ${base}/dir2/file2 << END
71                          file 2 contents
72hello
73hello
74hello
75hello
76hello
77hello
78END
79#
80dd if=/dev/zero of=${base}/zero bs=1 count=33000 > /dev/null 2>&1
81#
82cab1=test_read_format_cab_1.cab
83cab2=test_read_format_cab_2.cab
84cab3=test_read_format_cab_3.cab
85#
86#
87cat > ${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}
93empty
94.Set DestinationDir=dir1
95dir1/file1
96.Set DestinationDir=dir2
97dir2/file2
98END
99#
100cat > ${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}
106empty
107zero
108.Set DestinationDir=dir1
109dir1/file1
110.Set DestinationDir=dir2
111dir2/file2
112END
113#
114cat > ${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}
120empty
121zero
122.Set DestinationDir=dir1
123dir1/file1
124.Set DestinationDir=dir2
125dir2/file2
126END
127#
128cat > ${base}/mkcab4 << END
129.Set CompressionType=MSZIP
130.Set DiskDirectory1=.
131.Set CabinetName1=test.cab
132${cab1}
133${cab2}
134${cab3}
135END
136#
137cat > ${base}/cab.bat << END
138makecab.exe /F mkcab1
139makecab.exe /F mkcab2
140makecab.exe /F mkcab3
141makecab.exe /F mkcab4
142del setup.inf setup.rpt
143del empty zero dir1\file1 dir2\file2 mkcab1 mkcab2 mkcab3 mkcab4
144del ${cab1} ${cab2} ${cab3}
145rmdir dir1 dir2
146END
147#
148f=cab.zip
149(cd ${base}; zip -q -c $f empty zero dir1/file1 dir2/file2 mkcab1 mkcab2 mkcab3 mkcab4 cab.bat)
150#
151exit 1
152*/
153
154static 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)
161static 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
172enum comp_type {
173	STORE = 0,
174	MSZIP,
175	LZX
176};
177static void
178verify(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. */
269finish:
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 */
277static void
278verify2(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 */
343static void
344verify3(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
395DEFINE_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