test_read_pax_truncated.c revision 232153
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 232153 2012-02-25 10:58:02Z 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); 40232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_pax(a)); 41232153Smm assertEqualIntA(a, ARCHIVE_OK, 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); 57232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 58228753Smm archive_entry_free(ae); 59232153Smm assertEqualIntA(a, (int)filedata_size, 60232153Smm (int)archive_write_data(a, filedata, filedata_size)); 61228753Smm 62228753Smm /* Close out the archive. */ 63232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 64232153Smm assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 65228753Smm 66228753Smm /* Now, read back a truncated version of the archive and 67228753Smm * verify that we get an appropriate error. */ 68228753Smm for (i = 1; i < used + 100; i += 100) { 69228753Smm assert((a = archive_read_new()) != NULL); 70232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 71232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 72232153Smm /* If it's truncated very early, the file type detection should fail. */ 73232153Smm if (i < 512) { 74232153Smm assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory2(a, buff, i, 13)); 75232153Smm goto wrap_up; 76232153Smm } else { 77232153Smm assertEqualIntA(a, ARCHIVE_OK, read_open_memory2(a, buff, i, 13)); 78232153Smm } 79228753Smm 80232153Smm /* If it's truncated in a header, the header read should fail. */ 81228753Smm if (i < 1536) { 82228753Smm assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); 83228753Smm goto wrap_up; 84228753Smm } else { 85228753Smm failure("Archive truncated to %d bytes", i); 86228753Smm assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); 87228753Smm } 88228753Smm 89232153Smm /* If it's truncated in the body, the body read should fail. */ 90228753Smm if (i < 1536 + filedata_size) { 91232153Smm assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, filedata, filedata_size)); 92228753Smm goto wrap_up; 93228753Smm } else { 94228753Smm failure("Archive truncated to %d bytes", i); 95228753Smm assertEqualIntA(a, filedata_size, 96228753Smm archive_read_data(a, filedata, filedata_size)); 97228753Smm } 98228753Smm 99228753Smm /* Verify the end of the archive. */ 100228753Smm /* Archive must be long enough to capture a 512-byte 101228753Smm * block of zeroes after the entry. (POSIX requires a 102228753Smm * second block of zeros to be written but libarchive 103228753Smm * does not return an error if it can't consume 104228753Smm * it.) */ 105228753Smm if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { 106228753Smm failure("i=%d minsize=%d", i, 107228753Smm 1536 + 512*((filedata_size + 511)/512) + 512); 108228753Smm assertEqualIntA(a, ARCHIVE_FATAL, 109228753Smm archive_read_next_header(a, &ae)); 110228753Smm } else { 111228753Smm assertEqualIntA(a, ARCHIVE_EOF, 112228753Smm archive_read_next_header(a, &ae)); 113228753Smm } 114228753Smm wrap_up: 115232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 116232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 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); 124232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 125232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 126232153Smm /* If it's truncated very early, file type detection should fail. */ 127232153Smm if (i < 512) { 128232153Smm assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory(a, buff, i, 7)); 129232153Smm goto wrap_up2; 130232153Smm } else { 131232153Smm assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, i, 7)); 132232153Smm } 133228753Smm 134228753Smm if (i < 1536) { 135232153Smm assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); 136228753Smm goto wrap_up2; 137228753Smm } else { 138228753Smm assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); 139228753Smm } 140228753Smm 141228753Smm if (i < 1536 + 512*((filedata_size+511)/512)) { 142232153Smm assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data_skip(a)); 143228753Smm goto wrap_up2; 144228753Smm } else { 145232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); 146228753Smm } 147228753Smm 148228753Smm /* Verify the end of the archive. */ 149228753Smm /* Archive must be long enough to capture a 512-byte 150228753Smm * block of zeroes after the entry. (POSIX requires a 151228753Smm * second block of zeros to be written but libarchive 152228753Smm * does not return an error if it can't consume 153228753Smm * it.) */ 154228753Smm if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { 155228753Smm assertEqualIntA(a, ARCHIVE_FATAL, 156228753Smm archive_read_next_header(a, &ae)); 157228753Smm } else { 158228753Smm assertEqualIntA(a, ARCHIVE_EOF, 159228753Smm archive_read_next_header(a, &ae)); 160228753Smm } 161228753Smm wrap_up2: 162232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 163232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 164228753Smm } 165228753Smm 166228753Smm /* Now, damage the archive in various ways and test the responses. */ 167228753Smm 168228753Smm /* Damage the first size field in the pax attributes. */ 169228753Smm memcpy(buff2, buff, buff_size); 170228753Smm buff2[512] = '9'; 171228753Smm buff2[513] = '9'; 172228753Smm buff2[514] = 'A'; /* Non-digit in size. */ 173228753Smm assert((a = archive_read_new()) != NULL); 174232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 175232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 176232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); 177228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 178232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 179232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 180228753Smm 181228753Smm /* Damage the size field in the pax attributes. */ 182228753Smm memcpy(buff2, buff, buff_size); 183228753Smm buff2[512] = 'A'; /* First character not a digit. */ 184228753Smm assert((a = archive_read_new()) != NULL); 185232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 186232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 187232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); 188228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 189232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 190232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 191228753Smm 192228753Smm /* Damage the size field in the pax attributes. */ 193228753Smm memcpy(buff2, buff, buff_size); 194228753Smm for (i = 512; i < 520; i++) /* Size over 999999. */ 195228753Smm buff2[i] = '9'; 196228753Smm buff2[i] = ' '; 197228753Smm assert((a = archive_read_new()) != NULL); 198232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 199232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 200232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); 201228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 202232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 203232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 204228753Smm 205228753Smm /* Damage the size field in the pax attributes. */ 206228753Smm memcpy(buff2, buff, buff_size); 207228753Smm buff2[512] = '9'; /* Valid format, but larger than attribute area. */ 208228753Smm buff2[513] = '9'; 209228753Smm buff2[514] = '9'; 210228753Smm buff2[515] = ' '; 211228753Smm assert((a = archive_read_new()) != NULL); 212232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 213232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 214232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); 215228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 216232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 217232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 218228753Smm 219228753Smm /* Damage the size field in the pax attributes. */ 220228753Smm memcpy(buff2, buff, buff_size); 221228753Smm buff2[512] = '1'; /* Too small. */ 222228753Smm buff2[513] = ' '; 223228753Smm assert((a = archive_read_new()) != NULL); 224232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 225232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 226232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); 227228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 228232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 229232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 230228753Smm 231228753Smm /* Damage the size field in the pax attributes. */ 232228753Smm memcpy(buff2, buff, buff_size); 233228753Smm buff2[512] = ' '; /* No size given. */ 234228753Smm assert((a = archive_read_new()) != NULL); 235232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 236232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 237232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); 238228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 239232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 240232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 241228753Smm 242228753Smm /* Damage the ustar header. */ 243228753Smm memcpy(buff2, buff, buff_size); 244228753Smm buff2[1024]++; /* Break the checksum. */ 245228753Smm assert((a = archive_read_new()) != NULL); 246232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 247232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 248232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); 249228753Smm assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); 250232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 251232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 252228753Smm 253228753Smm /* 254228753Smm * TODO: Damage the ustar header in various ways and fixup the 255228753Smm * checksum in order to test boundary cases in the innermost 256228753Smm * ustar header parsing. 257228753Smm */ 258228753Smm 259228753Smm free(buff); 260228753Smm free(buff2); 261228753Smm free(filedata); 262228753Smm} 263