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