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