test_read_pax_truncated.c revision 228763
1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm#include "test.h" 26228763Smm__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_read_pax_truncated.c 228763 2011-12-21 11:13:29Z mm $"); 27228753Smm 28228753SmmDEFINE_TEST(test_read_pax_truncated) 29228753Smm{ 30228753Smm struct archive_entry *ae; 31228753Smm struct archive *a; 32228753Smm size_t used, i, buff_size = 1000000; 33228753Smm size_t filedata_size = 100000; 34228753Smm char *buff = malloc(buff_size); 35228753Smm char *buff2 = malloc(buff_size); 36228753Smm char *filedata = malloc(filedata_size); 37228753Smm 38228753Smm /* Create a new archive in memory. */ 39228753Smm assert((a = archive_write_new()) != NULL); 40228753Smm assertA(0 == archive_write_set_format_pax(a)); 41228753Smm assertA(0 == archive_write_set_compression_none(a)); 42228753Smm assertEqualIntA(a, ARCHIVE_OK, 43228753Smm archive_write_open_memory(a, buff, buff_size, &used)); 44228753Smm 45228753Smm /* 46228753Smm * Write a file to it. 47228753Smm */ 48228753Smm assert((ae = archive_entry_new()) != NULL); 49228753Smm archive_entry_copy_pathname(ae, "file"); 50228753Smm archive_entry_set_mode(ae, S_IFREG | 0755); 51228753Smm for (i = 0; i < filedata_size; i++) 52228753Smm filedata[i] = (unsigned char)rand(); 53228753Smm archive_entry_set_atime(ae, 1, 2); 54228753Smm archive_entry_set_ctime(ae, 3, 4); 55228753Smm archive_entry_set_mtime(ae, 5, 6); 56228753Smm archive_entry_set_size(ae, filedata_size); 57228753Smm assertA(0 == archive_write_header(a, ae)); 58228753Smm archive_entry_free(ae); 59228753Smm assertA((ssize_t)filedata_size 60228753Smm == archive_write_data(a, filedata, filedata_size)); 61228753Smm 62228753Smm /* Close out the archive. */ 63228753Smm assertA(0 == archive_write_close(a)); 64228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 65228753Smm archive_write_finish(a); 66228753Smm#else 67228753Smm assertA(0 == archive_write_finish(a)); 68228753Smm#endif 69228753Smm 70228753Smm /* Now, read back a truncated version of the archive and 71228753Smm * verify that we get an appropriate error. */ 72228753Smm for (i = 1; i < used + 100; i += 100) { 73228753Smm assert((a = archive_read_new()) != NULL); 74228753Smm assertA(0 == archive_read_support_format_all(a)); 75228753Smm assertA(0 == archive_read_support_compression_all(a)); 76228753Smm assertA(0 == read_open_memory2(a, buff, i, 13)); 77228753Smm 78228753Smm if (i < 1536) { 79228753Smm assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); 80228753Smm goto wrap_up; 81228753Smm } else { 82228753Smm failure("Archive truncated to %d bytes", i); 83228753Smm assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); 84228753Smm } 85228753Smm 86228753Smm if (i < 1536 + filedata_size) { 87228753Smm assertA(ARCHIVE_FATAL == archive_read_data(a, filedata, filedata_size)); 88228753Smm goto wrap_up; 89228753Smm } else { 90228753Smm failure("Archive truncated to %d bytes", i); 91228753Smm assertEqualIntA(a, filedata_size, 92228753Smm archive_read_data(a, filedata, filedata_size)); 93228753Smm } 94228753Smm 95228753Smm /* Verify the end of the archive. */ 96228753Smm /* Archive must be long enough to capture a 512-byte 97228753Smm * block of zeroes after the entry. (POSIX requires a 98228753Smm * second block of zeros to be written but libarchive 99228753Smm * does not return an error if it can't consume 100228753Smm * it.) */ 101228753Smm if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { 102228753Smm failure("i=%d minsize=%d", i, 103228753Smm 1536 + 512*((filedata_size + 511)/512) + 512); 104228753Smm assertEqualIntA(a, ARCHIVE_FATAL, 105228753Smm archive_read_next_header(a, &ae)); 106228753Smm } else { 107228753Smm assertEqualIntA(a, ARCHIVE_EOF, 108228753Smm archive_read_next_header(a, &ae)); 109228753Smm } 110228753Smm wrap_up: 111228753Smm assert(0 == archive_read_close(a)); 112228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 113228753Smm archive_read_finish(a); 114228753Smm#else 115228753Smm assert(0 == archive_read_finish(a)); 116228753Smm#endif 117228753Smm } 118228753Smm 119228753Smm 120228753Smm 121228753Smm /* Same as above, except skip the body instead of reading it. */ 122228753Smm for (i = 1; i < used + 100; i += 100) { 123228753Smm assert((a = archive_read_new()) != NULL); 124228753Smm assertA(0 == archive_read_support_format_all(a)); 125228753Smm assertA(0 == archive_read_support_compression_all(a)); 126228753Smm assertA(0 == read_open_memory(a, buff, i, 7)); 127228753Smm 128228753Smm if (i < 1536) { 129228753Smm assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae)); 130228753Smm goto wrap_up2; 131228753Smm } else { 132228753Smm assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); 133228753Smm } 134228753Smm 135228753Smm if (i < 1536 + 512*((filedata_size+511)/512)) { 136228753Smm assertA(ARCHIVE_FATAL == archive_read_data_skip(a)); 137228753Smm goto wrap_up2; 138228753Smm } else { 139228753Smm assertA(ARCHIVE_OK == archive_read_data_skip(a)); 140228753Smm } 141228753Smm 142228753Smm /* Verify the end of the archive. */ 143228753Smm /* Archive must be long enough to capture a 512-byte 144228753Smm * block of zeroes after the entry. (POSIX requires a 145228753Smm * second block of zeros to be written but libarchive 146228753Smm * does not return an error if it can't consume 147228753Smm * it.) */ 148228753Smm if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { 149228753Smm assertEqualIntA(a, ARCHIVE_FATAL, 150228753Smm archive_read_next_header(a, &ae)); 151228753Smm } else { 152228753Smm assertEqualIntA(a, ARCHIVE_EOF, 153228753Smm archive_read_next_header(a, &ae)); 154228753Smm } 155228753Smm wrap_up2: 156228753Smm assert(0 == archive_read_close(a)); 157228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 158228753Smm archive_read_finish(a); 159228753Smm#else 160228753Smm assert(0 == archive_read_finish(a)); 161228753Smm#endif 162228753Smm } 163228753Smm 164228753Smm /* Now, damage the archive in various ways and test the responses. */ 165228753Smm 166228753Smm /* Damage the first size field in the pax attributes. */ 167228753Smm memcpy(buff2, buff, buff_size); 168228753Smm buff2[512] = '9'; 169228753Smm buff2[513] = '9'; 170228753Smm buff2[514] = 'A'; /* Non-digit in size. */ 171228753Smm assert((a = archive_read_new()) != NULL); 172228753Smm assertA(0 == archive_read_support_format_all(a)); 173228753Smm assertA(0 == archive_read_support_compression_all(a)); 174228753Smm assertA(0 == archive_read_open_memory(a, buff2, used)); 175228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 176228753Smm assert(0 == archive_read_close(a)); 177228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 178228753Smm archive_read_finish(a); 179228753Smm#else 180228753Smm assert(0 == archive_read_finish(a)); 181228753Smm#endif 182228753Smm 183228753Smm /* Damage the size field in the pax attributes. */ 184228753Smm memcpy(buff2, buff, buff_size); 185228753Smm buff2[512] = 'A'; /* First character not a digit. */ 186228753Smm assert((a = archive_read_new()) != NULL); 187228753Smm assertA(0 == archive_read_support_format_all(a)); 188228753Smm assertA(0 == archive_read_support_compression_all(a)); 189228753Smm assertA(0 == archive_read_open_memory(a, buff2, used)); 190228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 191228753Smm assert(0 == archive_read_close(a)); 192228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 193228753Smm archive_read_finish(a); 194228753Smm#else 195228753Smm assert(0 == archive_read_finish(a)); 196228753Smm#endif 197228753Smm 198228753Smm /* Damage the size field in the pax attributes. */ 199228753Smm memcpy(buff2, buff, buff_size); 200228753Smm for (i = 512; i < 520; i++) /* Size over 999999. */ 201228753Smm buff2[i] = '9'; 202228753Smm buff2[i] = ' '; 203228753Smm assert((a = archive_read_new()) != NULL); 204228753Smm assertA(0 == archive_read_support_format_all(a)); 205228753Smm assertA(0 == archive_read_support_compression_all(a)); 206228753Smm assertA(0 == archive_read_open_memory(a, buff2, used)); 207228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 208228753Smm assert(0 == archive_read_close(a)); 209228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 210228753Smm archive_read_finish(a); 211228753Smm#else 212228753Smm assert(0 == archive_read_finish(a)); 213228753Smm#endif 214228753Smm 215228753Smm /* Damage the size field in the pax attributes. */ 216228753Smm memcpy(buff2, buff, buff_size); 217228753Smm buff2[512] = '9'; /* Valid format, but larger than attribute area. */ 218228753Smm buff2[513] = '9'; 219228753Smm buff2[514] = '9'; 220228753Smm buff2[515] = ' '; 221228753Smm assert((a = archive_read_new()) != NULL); 222228753Smm assertA(0 == archive_read_support_format_all(a)); 223228753Smm assertA(0 == archive_read_support_compression_all(a)); 224228753Smm assertA(0 == archive_read_open_memory(a, buff2, used)); 225228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 226228753Smm assert(0 == archive_read_close(a)); 227228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 228228753Smm archive_read_finish(a); 229228753Smm#else 230228753Smm assert(0 == archive_read_finish(a)); 231228753Smm#endif 232228753Smm 233228753Smm /* Damage the size field in the pax attributes. */ 234228753Smm memcpy(buff2, buff, buff_size); 235228753Smm buff2[512] = '1'; /* Too small. */ 236228753Smm buff2[513] = ' '; 237228753Smm assert((a = archive_read_new()) != NULL); 238228753Smm assertA(0 == archive_read_support_format_all(a)); 239228753Smm assertA(0 == archive_read_support_compression_all(a)); 240228753Smm assertA(0 == archive_read_open_memory(a, buff2, used)); 241228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 242228753Smm assert(0 == archive_read_close(a)); 243228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 244228753Smm archive_read_finish(a); 245228753Smm#else 246228753Smm assert(0 == archive_read_finish(a)); 247228753Smm#endif 248228753Smm 249228753Smm /* Damage the size field in the pax attributes. */ 250228753Smm memcpy(buff2, buff, buff_size); 251228753Smm buff2[512] = ' '; /* No size given. */ 252228753Smm assert((a = archive_read_new()) != NULL); 253228753Smm assertA(0 == archive_read_support_format_all(a)); 254228753Smm assertA(0 == archive_read_support_compression_all(a)); 255228753Smm assertA(0 == archive_read_open_memory(a, buff2, used)); 256228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 257228753Smm assert(0 == archive_read_close(a)); 258228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 259228753Smm archive_read_finish(a); 260228753Smm#else 261228753Smm assert(0 == archive_read_finish(a)); 262228753Smm#endif 263228753Smm 264228753Smm /* Damage the ustar header. */ 265228753Smm memcpy(buff2, buff, buff_size); 266228753Smm buff2[1024]++; /* Break the checksum. */ 267228753Smm assert((a = archive_read_new()) != NULL); 268228753Smm assertA(0 == archive_read_support_format_all(a)); 269228753Smm assertA(0 == archive_read_support_compression_all(a)); 270228753Smm assertA(0 == archive_read_open_memory(a, buff2, used)); 271228753Smm assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); 272228753Smm assert(0 == archive_read_close(a)); 273228753Smm#if ARCHIVE_VERSION_NUMBER < 2000000 274228753Smm archive_read_finish(a); 275228753Smm#else 276228753Smm assert(0 == archive_read_finish(a)); 277228753Smm#endif 278228753Smm 279228753Smm /* 280228753Smm * TODO: Damage the ustar header in various ways and fixup the 281228753Smm * checksum in order to test boundary cases in the innermost 282228753Smm * ustar header parsing. 283228753Smm */ 284228753Smm 285228753Smm free(buff); 286228753Smm free(buff2); 287228753Smm free(filedata); 288228753Smm} 289