1231200Smm/*- 2231200Smm * Copyright (c) 2010 Michihiro NAKAJIMA 3231200Smm * All rights reserved. 4231200Smm * 5231200Smm * Redistribution and use in source and binary forms, with or without 6231200Smm * modification, are permitted provided that the following conditions 7231200Smm * are met: 8231200Smm * 1. Redistributions of source code must retain the above copyright 9231200Smm * notice, this list of conditions and the following disclaimer. 10231200Smm * 2. Redistributions in binary form must reproduce the above copyright 11231200Smm * notice, this list of conditions and the following disclaimer in the 12231200Smm * documentation and/or other materials provided with the distribution. 13231200Smm * 14231200Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15231200Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16231200Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17231200Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18231200Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19231200Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20231200Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21231200Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22231200Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23231200Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24231200Smm */ 25231200Smm#include "test.h" 26231200Smm__FBSDID("$FreeBSD"); 27231200Smm 28231200Smm/* 29231200SmmExecute the following command to rebuild the data for this program: 30231200Smm tail -n +44 test_read_format_cab.c | /bin/sh 31231200SmmAnd following works are: 32231200Smm1. Move /tmp/cab/cab.zip to Windows PC 33231200Smm2. Extract cab.zip 34231200Smm3. Open command prompt and change current directory where you extracted cab.zip 35231200Smm4. Execute cab.bat 36231200Smm5. Then you will see that there is a cabinet file, test.cab 37231200Smm6. Move test.cab to posix platform 38231200Smm7. Extract test.cab with this version of bsdtar 39231200Smm8. Execute the following command to make uuencoded files. 40231200Smm uuencode test_read_format_cab_1.cab test_read_format_cab_1.cab > test_read_format_cab_1.cab.uu 41231200Smm uuencode test_read_format_cab_2.cab test_read_format_cab_2.cab > test_read_format_cab_2.cab.uu 42231200Smm uuencode test_read_format_cab_3.cab test_read_format_cab_3.cab > test_read_format_cab_3.cab.uu 43231200Smm 44231200Smm#!/bin/sh 45231200Smm# 46231200Smm# How to make test data. 47231200Smm# 48231200Smm# Temporary directory. 49231200Smmbase=/tmp/cab 50231200Smm# Owner id 51231200Smmowner=1001 52231200Smm# Group id 53231200Smmgroup=1001 54231200Smm# 55231200Smm# Make contents of a cabinet file. 56231200Smm# 57231200Smmrm -rf ${base} 58231200Smmmkdir ${base} 59231200Smmmkdir ${base}/dir1 60231200Smmmkdir ${base}/dir2 61231200Smm# 62231200Smmtouch ${base}/empty 63231200Smmcat > ${base}/dir1/file1 << END 64231200Smm file 1 contents 65231200Smmhello 66231200Smmhello 67231200Smmhello 68231200SmmEND 69231200Smm# 70231200Smmcat > ${base}/dir2/file2 << END 71231200Smm file 2 contents 72231200Smmhello 73231200Smmhello 74231200Smmhello 75231200Smmhello 76231200Smmhello 77231200Smmhello 78231200SmmEND 79231200Smm# 80231200Smmdd if=/dev/zero of=${base}/zero bs=1 count=33000 > /dev/null 2>&1 81231200Smm# 82231200Smmcab1=test_read_format_cab_1.cab 83231200Smmcab2=test_read_format_cab_2.cab 84231200Smmcab3=test_read_format_cab_3.cab 85231200Smm# 86231200Smm# 87231200Smmcat > ${base}/mkcab1 << END 88231200Smm.Set Compress=OFF 89231200Smm.Set DiskDirectory1=. 90231200Smm.Set InfDate=1980-01-02 91231200Smm.Set InfTime=00:00:00 92231200Smm.Set CabinetName1=${cab1} 93231200Smmempty 94231200Smm.Set DestinationDir=dir1 95231200Smmdir1/file1 96231200Smm.Set DestinationDir=dir2 97231200Smmdir2/file2 98231200SmmEND 99231200Smm# 100231200Smmcat > ${base}/mkcab2 << END 101231200Smm.Set CompressionType=MSZIP 102231200Smm.Set DiskDirectory1=. 103231200Smm.Set InfDate=1980-01-02 104231200Smm.Set InfTime=00:00:00 105231200Smm.Set CabinetName1=${cab2} 106231200Smmempty 107231200Smmzero 108231200Smm.Set DestinationDir=dir1 109231200Smmdir1/file1 110231200Smm.Set DestinationDir=dir2 111231200Smmdir2/file2 112231200SmmEND 113231200Smm# 114231200Smmcat > ${base}/mkcab3 << END 115231200Smm.Set CompressionType=LZX 116231200Smm.Set DiskDirectory1=. 117231200Smm.Set InfDate=1980-01-02 118231200Smm.Set InfTime=00:00:00 119231200Smm.Set CabinetName1=${cab3} 120231200Smmempty 121231200Smmzero 122231200Smm.Set DestinationDir=dir1 123231200Smmdir1/file1 124231200Smm.Set DestinationDir=dir2 125231200Smmdir2/file2 126231200SmmEND 127231200Smm# 128231200Smmcat > ${base}/mkcab4 << END 129231200Smm.Set CompressionType=MSZIP 130231200Smm.Set DiskDirectory1=. 131231200Smm.Set CabinetName1=test.cab 132231200Smm${cab1} 133231200Smm${cab2} 134231200Smm${cab3} 135231200SmmEND 136231200Smm# 137231200Smmcat > ${base}/cab.bat << END 138231200Smmmakecab.exe /F mkcab1 139231200Smmmakecab.exe /F mkcab2 140231200Smmmakecab.exe /F mkcab3 141231200Smmmakecab.exe /F mkcab4 142231200Smmdel setup.inf setup.rpt 143231200Smmdel empty zero dir1\file1 dir2\file2 mkcab1 mkcab2 mkcab3 mkcab4 144231200Smmdel ${cab1} ${cab2} ${cab3} 145231200Smmrmdir dir1 dir2 146231200SmmEND 147231200Smm# 148231200Smmf=cab.zip 149231200Smm(cd ${base}; zip -q -c $f empty zero dir1/file1 dir2/file2 mkcab1 mkcab2 mkcab3 mkcab4 cab.bat) 150231200Smm# 151231200Smmexit 1 152231200Smm*/ 153231200Smm 154231200Smmstatic const char file1[] = { 155231200Smm" file 1 contents\n" 156231200Smm"hello\n" 157231200Smm"hello\n" 158231200Smm"hello\n" 159231200Smm}; 160231200Smm#define file1_size (sizeof(file1)-1) 161231200Smmstatic const char file2[] = { 162231200Smm" file 2 contents\n" 163231200Smm"hello\n" 164231200Smm"hello\n" 165231200Smm"hello\n" 166231200Smm"hello\n" 167231200Smm"hello\n" 168231200Smm"hello\n" 169231200Smm}; 170231200Smm#define file2_size (sizeof(file2)-1) 171231200Smm 172231200Smmenum comp_type { 173231200Smm STORE = 0, 174231200Smm MSZIP, 175231200Smm LZX 176231200Smm}; 177231200Smmstatic void 178231200Smmverify(const char *refname, enum comp_type comp) 179231200Smm{ 180231200Smm struct archive_entry *ae; 181231200Smm struct archive *a; 182231200Smm char buff[128]; 183231200Smm char zero[128]; 184231200Smm size_t s; 185231200Smm 186231200Smm memset(zero, 0, sizeof(zero)); 187231200Smm extract_reference_file(refname); 188231200Smm assert((a = archive_read_new()) != NULL); 189231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 190231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 191231200Smm assertEqualIntA(a, ARCHIVE_OK, 192231200Smm archive_read_open_filename(a, refname, 10240)); 193231200Smm 194231200Smm /* Verify regular empty. */ 195231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 196238856Smm assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); 197231200Smm assertEqualString("empty", archive_entry_pathname(ae)); 198231200Smm assertEqualInt(0, archive_entry_uid(ae)); 199231200Smm assertEqualInt(0, archive_entry_gid(ae)); 200231200Smm assertEqualInt(0, archive_entry_size(ae)); 201299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 202299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 203231200Smm 204231200Smm if (comp != STORE) { 205231200Smm /* Verify regular zero. 206231200Smm * Maximum CFDATA size is 32768, so we need over 32768 bytes 207231200Smm * file to check if we properly handle multiple CFDATA. 208231200Smm */ 209231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 210238856Smm assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); 211231200Smm assertEqualString("zero", archive_entry_pathname(ae)); 212231200Smm assertEqualInt(0, archive_entry_uid(ae)); 213231200Smm assertEqualInt(0, archive_entry_gid(ae)); 214299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 215299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 216231200Smm assertEqualInt(33000, archive_entry_size(ae)); 217231200Smm for (s = 0; s + sizeof(buff) < 33000; s+= sizeof(buff)) { 218231200Smm ssize_t rsize = archive_read_data(a, buff, sizeof(buff)); 219299529Smm if (comp == MSZIP && rsize == ARCHIVE_FATAL && archive_zlib_version() == NULL) { 220231200Smm skipping("Skipping CAB format(MSZIP) check: %s", 221231200Smm archive_error_string(a)); 222231200Smm goto finish; 223231200Smm } 224231200Smm assertEqualInt(sizeof(buff), rsize); 225231200Smm assertEqualMem(buff, zero, sizeof(buff)); 226231200Smm } 227231200Smm assertEqualInt(33000 - s, archive_read_data(a, buff, 33000 - s)); 228231200Smm assertEqualMem(buff, zero, 33000 - s); 229231200Smm } 230231200Smm 231231200Smm /* Verify regular file1. */ 232231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 233238856Smm assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); 234231200Smm assertEqualString("dir1/file1", archive_entry_pathname(ae)); 235231200Smm assertEqualInt(0, archive_entry_uid(ae)); 236231200Smm assertEqualInt(0, archive_entry_gid(ae)); 237299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 238299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 239231200Smm assertEqualInt(file1_size, archive_entry_size(ae)); 240231200Smm assertEqualInt(file1_size, archive_read_data(a, buff, file1_size)); 241231200Smm assertEqualMem(buff, file1, file1_size); 242231200Smm 243231200Smm /* Verify regular file2. */ 244231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 245238856Smm assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); 246231200Smm assertEqualString("dir2/file2", archive_entry_pathname(ae)); 247231200Smm assertEqualInt(0, archive_entry_uid(ae)); 248231200Smm assertEqualInt(0, archive_entry_gid(ae)); 249299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 250299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 251231200Smm assertEqualInt(file2_size, archive_entry_size(ae)); 252231200Smm assertEqualInt(file2_size, archive_read_data(a, buff, file2_size)); 253231200Smm assertEqualMem(buff, file2, file2_size); 254231200Smm 255231200Smm /* End of archive. */ 256231200Smm assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 257231200Smm 258231200Smm if (comp != STORE) { 259231200Smm assertEqualInt(4, archive_file_count(a)); 260231200Smm } else { 261231200Smm assertEqualInt(3, archive_file_count(a)); 262231200Smm } 263231200Smm 264231200Smm /* Verify archive format. */ 265248616Smm assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 266231200Smm assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); 267231200Smm 268231200Smm /* Close the archive. */ 269231200Smmfinish: 270231200Smm assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 271231200Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 272231200Smm} 273231200Smm 274238856Smm/* 275238856Smm * Skip beginning files and Read the last file. 276238856Smm */ 277238856Smmstatic void 278238856Smmverify2(const char *refname, enum comp_type comp) 279238856Smm{ 280238856Smm struct archive_entry *ae; 281238856Smm struct archive *a; 282238856Smm char buff[128]; 283238856Smm char zero[128]; 284238856Smm 285299529Smm if (comp == MSZIP && archive_zlib_version() == NULL) { 286248616Smm skipping("Skipping CAB format(MSZIP) check for %s", 287248616Smm refname); 288248616Smm return; 289248616Smm } 290238856Smm memset(zero, 0, sizeof(zero)); 291238856Smm extract_reference_file(refname); 292238856Smm assert((a = archive_read_new()) != NULL); 293238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 294238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 295238856Smm assertEqualIntA(a, ARCHIVE_OK, 296238856Smm archive_read_open_filename(a, refname, 10240)); 297238856Smm 298238856Smm /* Verify regular empty. */ 299238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 300299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 301299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 302238856Smm if (comp != STORE) { 303238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 304299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 305299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 306238856Smm } 307238856Smm /* Verify regular file1. */ 308238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 309299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 310299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 311238856Smm 312238856Smm /* Verify regular file2. */ 313238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 314238856Smm assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); 315238856Smm assertEqualString("dir2/file2", archive_entry_pathname(ae)); 316238856Smm assertEqualInt(0, archive_entry_uid(ae)); 317238856Smm assertEqualInt(0, archive_entry_gid(ae)); 318238856Smm assertEqualInt(file2_size, archive_entry_size(ae)); 319238856Smm assertEqualInt(file2_size, archive_read_data(a, buff, file2_size)); 320238856Smm assertEqualMem(buff, file2, file2_size); 321238856Smm 322238856Smm /* End of archive. */ 323238856Smm assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 324238856Smm 325238856Smm if (comp != STORE) { 326238856Smm assertEqualInt(4, archive_file_count(a)); 327238856Smm } else { 328238856Smm assertEqualInt(3, archive_file_count(a)); 329238856Smm } 330238856Smm 331238856Smm /* Verify archive format. */ 332248616Smm assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 333238856Smm assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); 334238856Smm 335238856Smm /* Close the archive. */ 336238856Smm assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 337238856Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 338238856Smm} 339238856Smm 340238856Smm/* 341238856Smm * Skip all file like 'bsdtar tvf foo.cab'. 342238856Smm */ 343238856Smmstatic void 344238856Smmverify3(const char *refname, enum comp_type comp) 345238856Smm{ 346238856Smm struct archive_entry *ae; 347238856Smm struct archive *a; 348238856Smm char zero[128]; 349238856Smm 350238856Smm memset(zero, 0, sizeof(zero)); 351238856Smm extract_reference_file(refname); 352238856Smm assert((a = archive_read_new()) != NULL); 353238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 354238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 355238856Smm assertEqualIntA(a, ARCHIVE_OK, 356238856Smm archive_read_open_filename(a, refname, 10240)); 357238856Smm 358238856Smm /* Verify regular empty. */ 359238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 360299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 361299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 362238856Smm if (comp != STORE) { 363238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 364299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 365299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 366238856Smm } 367238856Smm /* Verify regular file1. */ 368238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 369299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 370299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 371238856Smm 372238856Smm /* Verify regular file2. */ 373238856Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 374299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 375299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 376238856Smm 377238856Smm /* End of archive. */ 378238856Smm assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 379238856Smm 380238856Smm if (comp != STORE) { 381238856Smm assertEqualInt(4, archive_file_count(a)); 382238856Smm } else { 383238856Smm assertEqualInt(3, archive_file_count(a)); 384238856Smm } 385238856Smm 386238856Smm /* Verify archive format. */ 387248616Smm assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 388238856Smm assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); 389238856Smm 390238856Smm /* Close the archive. */ 391238856Smm assertEqualInt(ARCHIVE_OK, archive_read_close(a)); 392238856Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 393238856Smm} 394238856Smm 395231200SmmDEFINE_TEST(test_read_format_cab) 396231200Smm{ 397231200Smm /* Verify Cabinet file in no compression. */ 398231200Smm verify("test_read_format_cab_1.cab", STORE); 399238856Smm verify2("test_read_format_cab_1.cab", STORE); 400238856Smm verify3("test_read_format_cab_1.cab", STORE); 401231200Smm /* Verify Cabinet file in MSZIP. */ 402231200Smm verify("test_read_format_cab_2.cab", MSZIP); 403238856Smm verify2("test_read_format_cab_2.cab", MSZIP); 404238856Smm verify3("test_read_format_cab_2.cab", MSZIP); 405231200Smm /* Verify Cabinet file in LZX. */ 406231200Smm verify("test_read_format_cab_3.cab", LZX); 407238856Smm verify2("test_read_format_cab_3.cab", LZX); 408238856Smm verify3("test_read_format_cab_3.cab", LZX); 409231200Smm} 410231200Smm 411