1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3232153Smm * Copyright (c) 2011 Michihiro NAKAJIMA 4228753Smm * All rights reserved. 5228753Smm * 6228753Smm * Redistribution and use in source and binary forms, with or without 7228753Smm * modification, are permitted provided that the following conditions 8228753Smm * are met: 9228753Smm * 1. Redistributions of source code must retain the above copyright 10228753Smm * notice, this list of conditions and the following disclaimer. 11228753Smm * 2. Redistributions in binary form must reproduce the above copyright 12228753Smm * notice, this list of conditions and the following disclaimer in the 13228753Smm * documentation and/or other materials provided with the distribution. 14228753Smm * 15228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25228753Smm */ 26228753Smm#include "test.h" 27228763Smm__FBSDID("$FreeBSD$"); 28228753Smm 29232153Smm#ifdef HAVE_LIBZ 30232153Smmstatic const int libz_enabled = 1; 31232153Smm#else 32232153Smmstatic const int libz_enabled = 0; 33232153Smm#endif 34232153Smm 35228753Smm/* 36228753Smm * The reference file for this has been manually tweaked so that: 37228753Smm * * file2 has length-at-end but file1 does not 38228753Smm * * file2 has an invalid CRC 39228753Smm */ 40232153Smmstatic void 41232153Smmverify_basic(struct archive *a, int seek_checks) 42228753Smm{ 43228753Smm struct archive_entry *ae; 44228753Smm char *buff[128]; 45228753Smm const void *pv; 46228753Smm size_t s; 47232153Smm int64_t o; 48228753Smm 49232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 50228753Smm assertEqualString("dir/", archive_entry_pathname(ae)); 51228753Smm assertEqualInt(1179604249, archive_entry_mtime(ae)); 52228753Smm assertEqualInt(0, archive_entry_size(ae)); 53232153Smm if (seek_checks) 54232153Smm assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); 55228753Smm assertEqualIntA(a, ARCHIVE_EOF, 56228753Smm archive_read_data_block(a, &pv, &s, &o)); 57228753Smm assertEqualInt((int)s, 0); 58232153Smm 59232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 60228753Smm assertEqualString("file1", archive_entry_pathname(ae)); 61228753Smm assertEqualInt(1179604289, archive_entry_mtime(ae)); 62232153Smm if (seek_checks) 63232153Smm assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 64228753Smm assertEqualInt(18, archive_entry_size(ae)); 65228753Smm failure("archive_read_data() returns number of bytes read"); 66232153Smm if (libz_enabled) { 67232153Smm assertEqualInt(18, archive_read_data(a, buff, 19)); 68232153Smm assertEqualMem(buff, "hello\nhello\nhello\n", 18); 69232153Smm } else { 70232153Smm assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 71232153Smm assertEqualString(archive_error_string(a), 72232153Smm "Unsupported ZIP compression method (deflation)"); 73232153Smm assert(archive_errno(a) != 0); 74228753Smm } 75232153Smm 76232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 77228753Smm assertEqualString("file2", archive_entry_pathname(ae)); 78228753Smm assertEqualInt(1179605932, archive_entry_mtime(ae)); 79232153Smm if (seek_checks) { 80232153Smm assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 81232153Smm assertEqualInt(64, archive_entry_size_is_set(ae)); 82232153Smm } else { 83232153Smm failure("file2 has length-at-end, so we shouldn't see a valid size when streaming"); 84232153Smm assertEqualInt(0, archive_entry_size_is_set(ae)); 85232153Smm } 86232153Smm if (libz_enabled) { 87232153Smm failure("file2 has a bad CRC, so read should fail and not change buff"); 88232153Smm memset(buff, 'a', 19); 89232153Smm assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19)); 90232153Smm assertEqualMem(buff, "aaaaaaaaaaaaaaaaaaa", 19); 91232153Smm } else { 92232153Smm assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 93232153Smm assertEqualString(archive_error_string(a), 94232153Smm "Unsupported ZIP compression method (deflation)"); 95232153Smm assert(archive_errno(a) != 0); 96232153Smm } 97232153Smm assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); 98232153Smm /* Verify the number of files read. */ 99232153Smm failure("the archive file has three files"); 100232153Smm assertEqualInt(3, archive_file_count(a)); 101248616Smm assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 102232153Smm assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); 103232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 104232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 105228753Smm} 106228753Smm 107232153Smmstatic void 108232153Smmtest_basic(void) 109232153Smm{ 110232153Smm const char *refname = "test_read_format_zip.zip"; 111232153Smm struct archive *a; 112232153Smm char *p; 113232153Smm size_t s; 114228753Smm 115232153Smm extract_reference_file(refname); 116232153Smm 117232153Smm /* Verify with seeking reader. */ 118232153Smm assert((a = archive_read_new()) != NULL); 119232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 120232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 121232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 122232153Smm verify_basic(a, 1); 123232153Smm 124232153Smm /* Verify with streaming reader. */ 125232153Smm p = slurpfile(&s, refname); 126232153Smm assert((a = archive_read_new()) != NULL); 127232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 128232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 129232153Smm assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); 130232153Smm verify_basic(a, 0); 131232153Smm} 132232153Smm 133232153Smm/* 134232153Smm * Read Info-ZIP New Unix Extra Field 0x7875 "ux". 135232153Smm * Currently stores Unix UID/GID up to 32 bits. 136232153Smm */ 137232153Smmstatic void 138232153Smmverify_info_zip_ux(struct archive *a, int seek_checks) 139232153Smm{ 140232153Smm struct archive_entry *ae; 141232153Smm char *buff[128]; 142232153Smm 143232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 144232153Smm assertEqualString("file1", archive_entry_pathname(ae)); 145232153Smm assertEqualInt(1300668680, archive_entry_mtime(ae)); 146232153Smm assertEqualInt(18, archive_entry_size(ae)); 147232153Smm if (seek_checks) 148232153Smm assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); 149232153Smm failure("zip reader should read Info-ZIP New Unix Extra Field"); 150232153Smm assertEqualInt(1001, archive_entry_uid(ae)); 151232153Smm assertEqualInt(1001, archive_entry_gid(ae)); 152232153Smm if (libz_enabled) { 153232153Smm failure("archive_read_data() returns number of bytes read"); 154232153Smm assertEqualInt(18, archive_read_data(a, buff, 19)); 155232153Smm assertEqualMem(buff, "hello\nhello\nhello\n", 18); 156232153Smm } else { 157232153Smm assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 158232153Smm assertEqualString(archive_error_string(a), 159232153Smm "Unsupported ZIP compression method (deflation)"); 160232153Smm assert(archive_errno(a) != 0); 161232153Smm } 162232153Smm assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 163232153Smm 164232153Smm /* Verify the number of files read. */ 165232153Smm failure("the archive file has just one file"); 166232153Smm assertEqualInt(1, archive_file_count(a)); 167232153Smm 168248616Smm assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 169232153Smm assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); 170232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 171232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 172232153Smm} 173232153Smm 174232153Smmstatic void 175232153Smmtest_info_zip_ux(void) 176232153Smm{ 177232153Smm const char *refname = "test_read_format_zip_ux.zip"; 178232153Smm struct archive *a; 179232153Smm char *p; 180232153Smm size_t s; 181232153Smm 182232153Smm extract_reference_file(refname); 183232153Smm 184232153Smm /* Verify with seeking reader. */ 185232153Smm assert((a = archive_read_new()) != NULL); 186232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 187232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 188232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 189232153Smm verify_info_zip_ux(a, 1); 190232153Smm 191232153Smm /* Verify with streaming reader. */ 192232153Smm p = slurpfile(&s, refname); 193232153Smm assert((a = archive_read_new()) != NULL); 194232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 195232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 196232153Smm assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); 197232153Smm verify_info_zip_ux(a, 0); 198232153Smm} 199232153Smm 200232153Smm/* 201232153Smm * Verify that test_read_extract correctly works with 202232153Smm * Zip entries that use length-at-end. 203232153Smm */ 204232153Smmstatic void 205232153Smmverify_extract_length_at_end(struct archive *a, int seek_checks) 206232153Smm{ 207232153Smm struct archive_entry *ae; 208232153Smm 209232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 210232153Smm 211232153Smm assertEqualString("hello.txt", archive_entry_pathname(ae)); 212232153Smm if (seek_checks) { 213232153Smm assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); 214232153Smm assert(archive_entry_size_is_set(ae)); 215232153Smm assertEqualInt(6, archive_entry_size(ae)); 216232153Smm } else { 217232153Smm assert(!archive_entry_size_is_set(ae)); 218232153Smm assertEqualInt(0, archive_entry_size(ae)); 219232153Smm } 220232153Smm 221232153Smm if (libz_enabled) { 222232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0)); 223232153Smm assertFileContents("hello\x0A", 6, "hello.txt"); 224232153Smm } else { 225232153Smm assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0)); 226232153Smm assertEqualString(archive_error_string(a), 227232153Smm "Unsupported ZIP compression method (deflation)"); 228232153Smm assert(archive_errno(a) != 0); 229232153Smm } 230232153Smm 231232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 232232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); 233232153Smm} 234232153Smm 235232153Smmstatic void 236232153Smmtest_extract_length_at_end(void) 237232153Smm{ 238232153Smm const char *refname = "test_read_format_zip_length_at_end.zip"; 239232153Smm char *p; 240232153Smm size_t s; 241232153Smm struct archive *a; 242232153Smm 243232153Smm extract_reference_file(refname); 244232153Smm 245232153Smm /* Verify extraction with seeking reader. */ 246232153Smm assert((a = archive_read_new()) != NULL); 247232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 248232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 249232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 250232153Smm verify_extract_length_at_end(a, 1); 251232153Smm 252232153Smm /* Verify extraction with streaming reader. */ 253232153Smm p = slurpfile(&s, refname); 254232153Smm assert((a = archive_read_new()) != NULL); 255232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 256232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 257232153Smm assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); 258232153Smm verify_extract_length_at_end(a, 0); 259232153Smm} 260232153Smm 261232153Smmstatic void 262232153Smmtest_symlink(void) 263232153Smm{ 264232153Smm const char *refname = "test_read_format_zip_symlink.zip"; 265232153Smm char *p; 266232153Smm size_t s; 267232153Smm struct archive *a; 268232153Smm struct archive_entry *ae; 269232153Smm 270232153Smm extract_reference_file(refname); 271232153Smm p = slurpfile(&s, refname); 272232153Smm 273232153Smm /* Symlinks can only be extracted with the seeking reader. */ 274232153Smm assert((a = archive_read_new()) != NULL); 275232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); 276232153Smm assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); 277232153Smm 278232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 279232153Smm assertEqualString("file", archive_entry_pathname(ae)); 280232153Smm assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 281232153Smm 282232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 283232153Smm assertEqualString("symlink", archive_entry_pathname(ae)); 284232153Smm assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); 285232153Smm assertEqualInt(0, archive_entry_size(ae)); 286232153Smm assertEqualString("file", archive_entry_symlink(ae)); 287232153Smm 288232153Smm assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 289232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 290232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); 291232153Smm} 292232153Smm 293232153SmmDEFINE_TEST(test_read_format_zip) 294232153Smm{ 295232153Smm test_basic(); 296232153Smm test_info_zip_ux(); 297232153Smm test_extract_length_at_end(); 298232153Smm test_symlink(); 299232153Smm} 300