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 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 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 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 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