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("dir/", archive_entry_pathname(ae)); 45 assertEqualInt(1179604249, archive_entry_mtime(ae)); 46 assertEqualInt(0, archive_entry_size(ae)); 47 if (seek_checks) 48 assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); 49 assertEqualInt(archive_entry_is_encrypted(ae), 0); 50 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 51 assertEqualIntA(a, ARCHIVE_EOF, 52 archive_read_data_block(a, &pv, &s, &o)); 53 assertEqualInt((int)s, 0); 54 55 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 56 assertEqualString("file1", archive_entry_pathname(ae)); 57 assertEqualInt(1179604289, archive_entry_mtime(ae)); 58 if (seek_checks) 59 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 60 assertEqualInt(18, archive_entry_size(ae)); 61 assertEqualInt(archive_entry_is_encrypted(ae), 0); 62 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 63 failure("archive_read_data() returns number of bytes read"); 64 if (archive_zlib_version() != NULL) { 65 assertEqualInt(18, archive_read_data(a, buff, 19)); 66 assertEqualMem(buff, "hello\nhello\nhello\n", 18); 67 } else { 68 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 69 assertEqualString(archive_error_string(a), 70 "Unsupported ZIP compression method (deflation)"); 71 assert(archive_errno(a) != 0); 72 } 73 74 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 75 assertEqualString("file2", archive_entry_pathname(ae)); 76 assertEqualInt(1179605932, archive_entry_mtime(ae)); 77 assertEqualInt(archive_entry_is_encrypted(ae), 0); 78 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 79 if (seek_checks) { 80 assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 81 } 82 assert(archive_entry_size_is_set(ae)); 83 assertEqualInt(18, archive_entry_size(ae)); 84 if (archive_zlib_version() != NULL) { 85 failure("file2 has a bad CRC, so read should fail and not change buff"); 86 memset(buff, 'a', 19); 87 assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19)); 88 assertEqualMem(buff, "aaaaaaaaaaaaaaaaaaa", 19); 89 } else { 90 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 91 assertEqualString(archive_error_string(a), 92 "Unsupported ZIP compression method (deflation)"); 93 assert(archive_errno(a) != 0); 94 } 95 assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); 96 /* Verify the number of files read. */ 97 failure("the archive file has three files"); 98 assertEqualInt(3, archive_file_count(a)); 99 assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 100 assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); 101 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 102 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 103 } 104 105 static void 106 test_basic(void) 107 { 108 const char *refname = "test_read_format_zip.zip"; 109 struct archive *a; 110 char *p; 111 size_t s; 112 113 extract_reference_file(refname); 114 115 /* Verify with seeking reader. */ 116 assert((a = archive_read_new()) != NULL); 117 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 118 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 119 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 120 verify_basic(a, 1); 121 122 /* Verify with streaming reader. */ 123 p = slurpfile(&s, refname); 124 assert((a = archive_read_new()) != NULL); 125 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 126 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 127 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); 128 verify_basic(a, 0); 129 } 130 131 /* 132 * Read Info-ZIP New Unix Extra Field 0x7875 "ux". 133 * Currently stores Unix UID/GID up to 32 bits. 134 */ 135 static void 136 verify_info_zip_ux(struct archive *a, int seek_checks) 137 { 138 struct archive_entry *ae; 139 char *buff[128]; 140 141 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 142 assertEqualString("file1", archive_entry_pathname(ae)); 143 assertEqualInt(1300668680, archive_entry_mtime(ae)); 144 assertEqualInt(18, archive_entry_size(ae)); 145 assertEqualInt(archive_entry_is_encrypted(ae), 0); 146 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 147 if (seek_checks) 148 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); 149 failure("zip reader should read Info-ZIP New Unix Extra Field"); 150 assertEqualInt(1001, archive_entry_uid(ae)); 151 assertEqualInt(1001, archive_entry_gid(ae)); 152 if (archive_zlib_version() != NULL) { 153 failure("archive_read_data() returns number of bytes read"); 154 assertEqualInt(18, archive_read_data(a, buff, 19)); 155 assertEqualMem(buff, "hello\nhello\nhello\n", 18); 156 } else { 157 assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); 158 assertEqualString(archive_error_string(a), 159 "Unsupported ZIP compression method (deflation)"); 160 assert(archive_errno(a) != 0); 161 } 162 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 163 164 /* Verify the number of files read. */ 165 failure("the archive file has just one file"); 166 assertEqualInt(1, archive_file_count(a)); 167 168 assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); 169 assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); 170 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 171 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 172 } 173 174 static void 175 test_info_zip_ux(void) 176 { 177 const char *refname = "test_read_format_zip_ux.zip"; 178 struct archive *a; 179 char *p; 180 size_t s; 181 182 extract_reference_file(refname); 183 184 /* Verify with seeking reader. */ 185 assert((a = archive_read_new()) != NULL); 186 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 187 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 188 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 189 verify_info_zip_ux(a, 1); 190 191 /* Verify with streaming reader. */ 192 p = slurpfile(&s, refname); 193 assert((a = archive_read_new()) != NULL); 194 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 195 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 196 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); 197 verify_info_zip_ux(a, 0); 198 } 199 200 /* 201 * Verify that test_read_extract correctly works with 202 * Zip entries that use length-at-end. 203 */ 204 static void 205 verify_extract_length_at_end(struct archive *a, int seek_checks) 206 { 207 struct archive_entry *ae; 208 209 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 210 211 assertEqualInt(archive_entry_is_encrypted(ae), 0); 212 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 213 assertEqualString("hello.txt", archive_entry_pathname(ae)); 214 if (seek_checks) { 215 assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); 216 assert(archive_entry_size_is_set(ae)); 217 assertEqualInt(6, archive_entry_size(ae)); 218 } else { 219 assert(!archive_entry_size_is_set(ae)); 220 assertEqualInt(0, archive_entry_size(ae)); 221 } 222 223 if (archive_zlib_version() != NULL) { 224 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0)); 225 assertFileContents("hello\x0A", 6, "hello.txt"); 226 } else { 227 assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0)); 228 assertEqualString(archive_error_string(a), 229 "Unsupported ZIP compression method (deflation)"); 230 assert(archive_errno(a) != 0); 231 } 232 233 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 234 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); 235 } 236 237 static void 238 test_extract_length_at_end(void) 239 { 240 const char *refname = "test_read_format_zip_length_at_end.zip"; 241 char *p; 242 size_t s; 243 struct archive *a; 244 245 extract_reference_file(refname); 246 247 /* Verify extraction with seeking reader. */ 248 assert((a = archive_read_new()) != NULL); 249 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 250 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 251 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); 252 verify_extract_length_at_end(a, 1); 253 254 /* Verify extraction with streaming reader. */ 255 p = slurpfile(&s, refname); 256 assert((a = archive_read_new()) != NULL); 257 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 258 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 259 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); 260 verify_extract_length_at_end(a, 0); 261 } 262 263 static void 264 test_symlink(void) 265 { 266 const char *refname = "test_read_format_zip_symlink.zip"; 267 char *p; 268 size_t s; 269 struct archive *a; 270 struct archive_entry *ae; 271 272 extract_reference_file(refname); 273 p = slurpfile(&s, refname); 274 275 /* Symlinks can only be extracted with the seeking reader. */ 276 assert((a = archive_read_new()) != NULL); 277 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); 278 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); 279 280 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 281 assertEqualString("file", archive_entry_pathname(ae)); 282 assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 283 assertEqualInt(archive_entry_is_encrypted(ae), 0); 284 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 285 286 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 287 assertEqualString("symlink", archive_entry_pathname(ae)); 288 assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); 289 assertEqualInt(0, archive_entry_size(ae)); 290 assertEqualString("file", archive_entry_symlink(ae)); 291 assertEqualInt(archive_entry_is_encrypted(ae), 0); 292 assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); 293 294 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 295 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 296 assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); 297 } 298 299 DEFINE_TEST(test_read_format_zip) 300 { 301 test_basic(); 302 test_info_zip_ux(); 303 test_extract_length_at_end(); 304 test_symlink(); 305 } 306