1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * Copyright (c) 2011 Michihiro NAKAJIMA 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 #include "test.h" 27 __FBSDID("$FreeBSD$"); 28 29 /* 30 * The reference file for this has been manually tweaked so that: 31 * * file2 has length-at-end but file1 does not 32 * * file2 has an invalid CRC 33 */ 34 static void 35 verify_basic(struct archive *a, int seek_checks) 36 { 37 struct archive_entry *ae; 38 char *buff[128]; 39 const void *pv; 40 size_t s; 41 int64_t o; 42 43 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 44 assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a)); 45 assertEqualString("dir/", archive_entry_pathname(ae)); 46 assertEqualInt(1179604249, archive_entry_mtime(ae)); 47 assertEqualInt(0, archive_entry_size(ae)); 48 if (seek_checks) 49 assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); 50 assertEqualInt(archive_entry_is_encrypted(ae), 0); 51 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 52 assertEqualIntA(a, ARCHIVE_EOF, 53 archive_read_data_block(a, &pv, &s, &o)); 54 assertEqualInt((int)s, 0); 55 56 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 57 assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); 58 assertEqualString("file1", archive_entry_pathname(ae)); 59 assertEqualInt(1179604289, archive_entry_mtime(ae)); 60 if (seek_checks) 61 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 62 assertEqualInt(18, archive_entry_size(ae)); 63 assertEqualInt(archive_entry_is_encrypted(ae), 0); 64 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 65 failure("archive_read_data() returns number of bytes read"); 66 if (archive_zlib_version() != NULL) { 67 assertEqualInt(18, archive_read_data(a, buff, 19)); 68 assertEqualMem(buff, "hello\nhello\nhello\n", 18); 69 } else { 70 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 71 assertEqualString(archive_error_string(a), 72 "Unsupported ZIP compression method (deflation)"); 73 assert(archive_errno(a) != 0); 74 } 75 76 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 77 assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); 78 assertEqualString("file2", archive_entry_pathname(ae)); 79 assertEqualInt(1179605932, archive_entry_mtime(ae)); 80 assertEqualInt(archive_entry_is_encrypted(ae), 0); 81 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 82 if (seek_checks) { 83 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 84 } 85 assert(archive_entry_size_is_set(ae)); 86 assertEqualInt(18, archive_entry_size(ae)); 87 if (archive_zlib_version() != NULL) { 88 failure("file2 has a bad CRC, so read should fail and not change buff"); 89 memset(buff, 'a', 19); 90 assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19)); 91 assertEqualMem(buff, "aaaaaaaaaaaaaaaaaaa", 19); 92 } else { 93 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 94 assertEqualString(archive_error_string(a), 95 "Unsupported ZIP compression method (deflation)"); 96 assert(archive_errno(a) != 0); 97 } 98 assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); 99 assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); 100 /* Verify the number of files read. */ 101 failure("the archive file has three files"); 102 assertEqualInt(3, archive_file_count(a)); 103 assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 104 assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); 105 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 106 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 107 } 108 109 static void 110 test_basic(void) 111 { 112 const char *refname = "test_read_format_zip.zip"; 113 struct archive *a; 114 char *p; 115 size_t s; 116 117 extract_reference_file(refname); 118 119 /* Verify with seeking reader. */ 120 assert((a = archive_read_new()) != NULL); 121 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 122 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 123 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 124 verify_basic(a, 1); 125 126 /* Verify with streaming reader. */ 127 p = slurpfile(&s, refname); 128 assert((a = archive_read_new()) != NULL); 129 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 130 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 131 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); 132 verify_basic(a, 0); 133 free(p); 134 } 135 136 /* 137 * Read Info-ZIP New Unix Extra Field 0x7875 "ux". 138 * Currently stores Unix UID/GID up to 32 bits. 139 */ 140 static void 141 verify_info_zip_ux(struct archive *a, int seek_checks) 142 { 143 struct archive_entry *ae; 144 char *buff[128]; 145 146 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 147 assertEqualString("file1", archive_entry_pathname(ae)); 148 assertEqualInt(1300668680, archive_entry_mtime(ae)); 149 assertEqualInt(18, archive_entry_size(ae)); 150 assertEqualInt(archive_entry_is_encrypted(ae), 0); 151 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 152 if (seek_checks) 153 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); 154 failure("zip reader should read Info-ZIP New Unix Extra Field"); 155 assertEqualInt(1001, archive_entry_uid(ae)); 156 assertEqualInt(1001, archive_entry_gid(ae)); 157 if (archive_zlib_version() != NULL) { 158 failure("archive_read_data() returns number of bytes read"); 159 assertEqualInt(18, archive_read_data(a, buff, 19)); 160 assertEqualMem(buff, "hello\nhello\nhello\n", 18); 161 } else { 162 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 163 assertEqualString(archive_error_string(a), 164 "Unsupported ZIP compression method (deflation)"); 165 assert(archive_errno(a) != 0); 166 } 167 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 168 169 /* Verify the number of files read. */ 170 failure("the archive file has just one file"); 171 assertEqualInt(1, archive_file_count(a)); 172 173 assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 174 assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); 175 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 176 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 177 } 178 179 static void 180 test_info_zip_ux(void) 181 { 182 const char *refname = "test_read_format_zip_ux.zip"; 183 struct archive *a; 184 char *p; 185 size_t s; 186 187 extract_reference_file(refname); 188 189 /* Verify with seeking reader. */ 190 assert((a = archive_read_new()) != NULL); 191 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 192 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 193 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 194 verify_info_zip_ux(a, 1); 195 196 /* Verify with streaming reader. */ 197 p = slurpfile(&s, refname); 198 assert((a = archive_read_new()) != NULL); 199 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 200 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 201 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); 202 verify_info_zip_ux(a, 0); 203 free(p); 204 } 205 206 /* 207 * Verify that test_read_extract correctly works with 208 * Zip entries that use length-at-end. 209 */ 210 static void 211 verify_extract_length_at_end(struct archive *a, int seek_checks) 212 { 213 struct archive_entry *ae; 214 215 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 216 217 assertEqualInt(archive_entry_is_encrypted(ae), 0); 218 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 219 assertEqualString("hello.txt", archive_entry_pathname(ae)); 220 if (seek_checks) { 221 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); 222 assert(archive_entry_size_is_set(ae)); 223 assertEqualInt(6, archive_entry_size(ae)); 224 } else { 225 assert(!archive_entry_size_is_set(ae)); 226 assertEqualInt(0, archive_entry_size(ae)); 227 } 228 229 if (archive_zlib_version() != NULL) { 230 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0)); 231 assertFileContents("hello\x0A", 6, "hello.txt"); 232 } else { 233 assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0)); 234 assertEqualString(archive_error_string(a), 235 "Unsupported ZIP compression method (deflation)"); 236 assert(archive_errno(a) != 0); 237 } 238 239 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 240 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); 241 } 242 243 static void 244 test_extract_length_at_end(void) 245 { 246 const char *refname = "test_read_format_zip_length_at_end.zip"; 247 char *p; 248 size_t s; 249 struct archive *a; 250 251 extract_reference_file(refname); 252 253 /* Verify extraction with seeking reader. */ 254 assert((a = archive_read_new()) != NULL); 255 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 256 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 257 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 258 verify_extract_length_at_end(a, 1); 259 260 /* Verify extraction with streaming reader. */ 261 p = slurpfile(&s, refname); 262 assert((a = archive_read_new()) != NULL); 263 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 264 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 265 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); 266 verify_extract_length_at_end(a, 0); 267 free(p); 268 } 269 270 static void 271 test_symlink(void) 272 { 273 const char *refname = "test_read_format_zip_symlink.zip"; 274 char *p; 275 size_t s; 276 struct archive *a; 277 struct archive_entry *ae; 278 279 extract_reference_file(refname); 280 p = slurpfile(&s, refname); 281 282 /* Symlinks can only be extracted with the seeking reader. */ 283 assert((a = archive_read_new()) != NULL); 284 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); 285 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); 286 287 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 288 assertEqualString("file", archive_entry_pathname(ae)); 289 assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 290 assertEqualInt(archive_entry_is_encrypted(ae), 0); 291 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 292 293 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 294 assertEqualString("symlink", archive_entry_pathname(ae)); 295 assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); 296 assertEqualInt(0, archive_entry_size(ae)); 297 assertEqualString("file", archive_entry_symlink(ae)); 298 assertEqualInt(archive_entry_is_encrypted(ae), 0); 299 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 300 301 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 302 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 303 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); 304 305 free(p); 306 } 307 308 DEFINE_TEST(test_read_format_zip) 309 { 310 test_basic(); 311 test_info_zip_ux(); 312 test_extract_length_at_end(); 313 test_symlink(); 314 } 315