1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 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: head/lib/libarchive/test/test_read_pax_truncated.c 189483 2009-03-07 03:34:34Z kientzle $"); 27 28 DEFINE_TEST(test_read_pax_truncated) 29 { 30 struct archive_entry *ae; 31 struct archive *a; 32 size_t used, i, buff_size = 1000000; 33 size_t filedata_size = 100000; 34 char *buff = malloc(buff_size); 35 char *buff2 = malloc(buff_size); 36 char *filedata = malloc(filedata_size); 37 38 /* Create a new archive in memory. */ 39 assert((a = archive_write_new()) != NULL); 40 assertA(0 == archive_write_set_format_pax(a)); 41 assertA(0 == archive_write_set_compression_none(a)); 42 assertEqualIntA(a, ARCHIVE_OK, 43 archive_write_open_memory(a, buff, buff_size, &used)); 44 45 /* 46 * Write a file to it. 47 */ 48 assert((ae = archive_entry_new()) != NULL); 49 archive_entry_copy_pathname(ae, "file"); 50 archive_entry_set_mode(ae, S_IFREG | 0755); 51 for (i = 0; i < filedata_size; i++) 52 filedata[i] = (unsigned char)rand(); 53 archive_entry_set_atime(ae, 1, 2); 54 archive_entry_set_ctime(ae, 3, 4); 55 archive_entry_set_mtime(ae, 5, 6); 56 archive_entry_set_size(ae, filedata_size); 57 assertA(0 == archive_write_header(a, ae)); 58 archive_entry_free(ae); 59 assertA((ssize_t)filedata_size 60 == archive_write_data(a, filedata, filedata_size)); 61 62 /* Close out the archive. */ 63 assertA(0 == archive_write_close(a)); 64 #if ARCHIVE_VERSION_NUMBER < 2000000 65 archive_write_finish(a); 66 #else 67 assertA(0 == archive_write_finish(a)); 68 #endif 69 70 /* Now, read back a truncated version of the archive and 71 * verify that we get an appropriate error. */ 72 for (i = 1; i < used + 100; i += 100) { 73 assert((a = archive_read_new()) != NULL); 74 assertA(0 == archive_read_support_format_all(a)); 75 assertA(0 == archive_read_support_compression_all(a)); 76 assertA(0 == read_open_memory2(a, buff, i, 13)); 77 78 if (i < 1536) { 79 assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); 80 goto wrap_up; 81 } else { 82 failure("Archive truncated to %d bytes", i); 83 assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); 84 } 85 86 if (i < 1536 + filedata_size) { 87 assertA(ARCHIVE_FATAL == archive_read_data(a, filedata, filedata_size)); 88 goto wrap_up; 89 } else { 90 failure("Archive truncated to %d bytes", i); 91 assertEqualIntA(a, filedata_size, 92 archive_read_data(a, filedata, filedata_size)); 93 } 94 95 /* Verify the end of the archive. */ 96 /* Archive must be long enough to capture a 512-byte 97 * block of zeroes after the entry. (POSIX requires a 98 * second block of zeros to be written but libarchive 99 * does not return an error if it can't consume 100 * it.) */ 101 if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { 102 failure("i=%d minsize=%d", i, 103 1536 + 512*((filedata_size + 511)/512) + 512); 104 assertEqualIntA(a, ARCHIVE_FATAL, 105 archive_read_next_header(a, &ae)); 106 } else { 107 assertEqualIntA(a, ARCHIVE_EOF, 108 archive_read_next_header(a, &ae)); 109 } 110 wrap_up: 111 assert(0 == archive_read_close(a)); 112 #if ARCHIVE_VERSION_NUMBER < 2000000 113 archive_read_finish(a); 114 #else 115 assert(0 == archive_read_finish(a)); 116 #endif 117 } 118 119 120 121 /* Same as above, except skip the body instead of reading it. */ 122 for (i = 1; i < used + 100; i += 100) { 123 assert((a = archive_read_new()) != NULL); 124 assertA(0 == archive_read_support_format_all(a)); 125 assertA(0 == archive_read_support_compression_all(a)); 126 assertA(0 == read_open_memory(a, buff, i, 7)); 127 128 if (i < 1536) { 129 assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae)); 130 goto wrap_up2; 131 } else { 132 assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); 133 } 134 135 if (i < 1536 + 512*((filedata_size+511)/512)) { 136 assertA(ARCHIVE_FATAL == archive_read_data_skip(a)); 137 goto wrap_up2; 138 } else { 139 assertA(ARCHIVE_OK == archive_read_data_skip(a)); 140 } 141 142 /* Verify the end of the archive. */ 143 /* Archive must be long enough to capture a 512-byte 144 * block of zeroes after the entry. (POSIX requires a 145 * second block of zeros to be written but libarchive 146 * does not return an error if it can't consume 147 * it.) */ 148 if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { 149 assertEqualIntA(a, ARCHIVE_FATAL, 150 archive_read_next_header(a, &ae)); 151 } else { 152 assertEqualIntA(a, ARCHIVE_EOF, 153 archive_read_next_header(a, &ae)); 154 } 155 wrap_up2: 156 assert(0 == archive_read_close(a)); 157 #if ARCHIVE_VERSION_NUMBER < 2000000 158 archive_read_finish(a); 159 #else 160 assert(0 == archive_read_finish(a)); 161 #endif 162 } 163 164 /* Now, damage the archive in various ways and test the responses. */ 165 166 /* Damage the first size field in the pax attributes. */ 167 memcpy(buff2, buff, buff_size); 168 buff2[512] = '9'; 169 buff2[513] = '9'; 170 buff2[514] = 'A'; /* Non-digit in size. */ 171 assert((a = archive_read_new()) != NULL); 172 assertA(0 == archive_read_support_format_all(a)); 173 assertA(0 == archive_read_support_compression_all(a)); 174 assertA(0 == archive_read_open_memory(a, buff2, used)); 175 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 176 assert(0 == archive_read_close(a)); 177 #if ARCHIVE_VERSION_NUMBER < 2000000 178 archive_read_finish(a); 179 #else 180 assert(0 == archive_read_finish(a)); 181 #endif 182 183 /* Damage the size field in the pax attributes. */ 184 memcpy(buff2, buff, buff_size); 185 buff2[512] = 'A'; /* First character not a digit. */ 186 assert((a = archive_read_new()) != NULL); 187 assertA(0 == archive_read_support_format_all(a)); 188 assertA(0 == archive_read_support_compression_all(a)); 189 assertA(0 == archive_read_open_memory(a, buff2, used)); 190 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 191 assert(0 == archive_read_close(a)); 192 #if ARCHIVE_VERSION_NUMBER < 2000000 193 archive_read_finish(a); 194 #else 195 assert(0 == archive_read_finish(a)); 196 #endif 197 198 /* Damage the size field in the pax attributes. */ 199 memcpy(buff2, buff, buff_size); 200 for (i = 512; i < 520; i++) /* Size over 999999. */ 201 buff2[i] = '9'; 202 buff2[i] = ' '; 203 assert((a = archive_read_new()) != NULL); 204 assertA(0 == archive_read_support_format_all(a)); 205 assertA(0 == archive_read_support_compression_all(a)); 206 assertA(0 == archive_read_open_memory(a, buff2, used)); 207 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 208 assert(0 == archive_read_close(a)); 209 #if ARCHIVE_VERSION_NUMBER < 2000000 210 archive_read_finish(a); 211 #else 212 assert(0 == archive_read_finish(a)); 213 #endif 214 215 /* Damage the size field in the pax attributes. */ 216 memcpy(buff2, buff, buff_size); 217 buff2[512] = '9'; /* Valid format, but larger than attribute area. */ 218 buff2[513] = '9'; 219 buff2[514] = '9'; 220 buff2[515] = ' '; 221 assert((a = archive_read_new()) != NULL); 222 assertA(0 == archive_read_support_format_all(a)); 223 assertA(0 == archive_read_support_compression_all(a)); 224 assertA(0 == archive_read_open_memory(a, buff2, used)); 225 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 226 assert(0 == archive_read_close(a)); 227 #if ARCHIVE_VERSION_NUMBER < 2000000 228 archive_read_finish(a); 229 #else 230 assert(0 == archive_read_finish(a)); 231 #endif 232 233 /* Damage the size field in the pax attributes. */ 234 memcpy(buff2, buff, buff_size); 235 buff2[512] = '1'; /* Too small. */ 236 buff2[513] = ' '; 237 assert((a = archive_read_new()) != NULL); 238 assertA(0 == archive_read_support_format_all(a)); 239 assertA(0 == archive_read_support_compression_all(a)); 240 assertA(0 == archive_read_open_memory(a, buff2, used)); 241 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 242 assert(0 == archive_read_close(a)); 243 #if ARCHIVE_VERSION_NUMBER < 2000000 244 archive_read_finish(a); 245 #else 246 assert(0 == archive_read_finish(a)); 247 #endif 248 249 /* Damage the size field in the pax attributes. */ 250 memcpy(buff2, buff, buff_size); 251 buff2[512] = ' '; /* No size given. */ 252 assert((a = archive_read_new()) != NULL); 253 assertA(0 == archive_read_support_format_all(a)); 254 assertA(0 == archive_read_support_compression_all(a)); 255 assertA(0 == archive_read_open_memory(a, buff2, used)); 256 assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 257 assert(0 == archive_read_close(a)); 258 #if ARCHIVE_VERSION_NUMBER < 2000000 259 archive_read_finish(a); 260 #else 261 assert(0 == archive_read_finish(a)); 262 #endif 263 264 /* Damage the ustar header. */ 265 memcpy(buff2, buff, buff_size); 266 buff2[1024]++; /* Break the checksum. */ 267 assert((a = archive_read_new()) != NULL); 268 assertA(0 == archive_read_support_format_all(a)); 269 assertA(0 == archive_read_support_compression_all(a)); 270 assertA(0 == archive_read_open_memory(a, buff2, used)); 271 assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); 272 assert(0 == archive_read_close(a)); 273 #if ARCHIVE_VERSION_NUMBER < 2000000 274 archive_read_finish(a); 275 #else 276 assert(0 == archive_read_finish(a)); 277 #endif 278 279 /* 280 * TODO: Damage the ustar header in various ways and fixup the 281 * checksum in order to test boundary cases in the innermost 282 * ustar header parsing. 283 */ 284 285 free(buff); 286 free(buff2); 287 free(filedata); 288 } 289