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