test_write_format_cpio.c revision 368707
1289284Srpaulo/*- 2289284Srpaulo * Copyright (c) 2003-2007 Tim Kientzle 3289284Srpaulo * All rights reserved. 4289284Srpaulo * 5289284Srpaulo * Redistribution and use in source and binary forms, with or without 6289284Srpaulo * modification, are permitted provided that the following conditions 7289284Srpaulo * are met: 8289284Srpaulo * 1. Redistributions of source code must retain the above copyright 9289284Srpaulo * notice, this list of conditions and the following disclaimer. 10289284Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 11289284Srpaulo * notice, this list of conditions and the following disclaimer in the 12289284Srpaulo * documentation and/or other materials provided with the distribution. 13289284Srpaulo * 14289284Srpaulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15289284Srpaulo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16289284Srpaulo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17289284Srpaulo * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18289284Srpaulo * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19289284Srpaulo * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20289284Srpaulo * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21289284Srpaulo * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22289284Srpaulo * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23289284Srpaulo * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24289284Srpaulo */ 25289284Srpaulo#include "test.h" 26289284Srpaulo__FBSDID("$FreeBSD: stable/11/contrib/libarchive/libarchive/test/test_write_format_cpio.c 368707 2020-12-16 22:25:20Z mm $"); 27289284Srpaulo 28289284Srpaulostatic void 29289284Srpaulotest_format(int (*set_format)(struct archive *)) 30289284Srpaulo{ 31289284Srpaulo char filedata[64]; 32289284Srpaulo struct archive_entry *ae; 33289284Srpaulo struct archive *a; 34289284Srpaulo char *p; 35289284Srpaulo size_t used; 36289284Srpaulo size_t buffsize = 1000000; 37289284Srpaulo char *buff; 38289284Srpaulo int damaged = 0; 39289284Srpaulo 40289284Srpaulo buff = malloc(buffsize); 41289284Srpaulo 42289284Srpaulo /* Create a new archive in memory. */ 43289284Srpaulo assert((a = archive_write_new()) != NULL); 44289284Srpaulo assertA(0 == (*set_format)(a)); 45289284Srpaulo assertA(0 == archive_write_add_filter_none(a)); 46289284Srpaulo assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); 47337817Scy 48289284Srpaulo /* 49289284Srpaulo * Write a file to it. 50289284Srpaulo */ 51289284Srpaulo assert((ae = archive_entry_new()) != NULL); 52289284Srpaulo archive_entry_set_mtime(ae, 1, 10); 53289284Srpaulo assert(1 == archive_entry_mtime(ae)); 54289284Srpaulo assert(10 == archive_entry_mtime_nsec(ae)); 55289284Srpaulo p = strdup("file"); 56289284Srpaulo archive_entry_copy_pathname(ae, p); 57289284Srpaulo strcpy(p, "XXXX"); 58289284Srpaulo free(p); 59289284Srpaulo assertEqualString("file", archive_entry_pathname(ae)); 60289284Srpaulo archive_entry_set_mode(ae, S_IFREG | 0755); 61289284Srpaulo assert((S_IFREG | 0755) == archive_entry_mode(ae)); 62289284Srpaulo archive_entry_set_size(ae, 8); 63289284Srpaulo 64289284Srpaulo assertA(0 == archive_write_header(a, ae)); 65289284Srpaulo archive_entry_free(ae); 66289284Srpaulo assertA(8 == archive_write_data(a, "12345678", 9)); 67289284Srpaulo 68289284Srpaulo /* 69289284Srpaulo * Write another file to it. 70289284Srpaulo */ 71289284Srpaulo assert((ae = archive_entry_new()) != NULL); 72289284Srpaulo archive_entry_set_mtime(ae, 1, 10); 73289284Srpaulo assert(1 == archive_entry_mtime(ae)); 74289284Srpaulo assert(10 == archive_entry_mtime_nsec(ae)); 75289284Srpaulo p = strdup("file2"); 76289284Srpaulo archive_entry_copy_pathname(ae, p); 77289284Srpaulo strcpy(p, "XXXX"); 78289284Srpaulo free(p); 79289284Srpaulo assertEqualString("file2", archive_entry_pathname(ae)); 80289284Srpaulo archive_entry_set_mode(ae, S_IFREG | 0755); 81289284Srpaulo assert((S_IFREG | 0755) == archive_entry_mode(ae)); 82289284Srpaulo archive_entry_set_size(ae, 4); 83289284Srpaulo 84289284Srpaulo assertA(0 == archive_write_header(a, ae)); 85289284Srpaulo archive_entry_free(ae); 86289284Srpaulo assertA(4 == archive_write_data(a, "1234", 5)); 87289284Srpaulo 88289284Srpaulo /* 89289284Srpaulo * Write a file with a name, filetype, and size. 90289284Srpaulo */ 91289284Srpaulo assert((ae = archive_entry_new()) != NULL); 92289284Srpaulo archive_entry_copy_pathname(ae, "name"); 93289284Srpaulo archive_entry_set_size(ae, 0); 94289284Srpaulo archive_entry_set_filetype(ae, AE_IFREG); 95289284Srpaulo assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); 96289284Srpaulo assert(archive_error_string(a) == NULL); 97289284Srpaulo archive_entry_free(ae); 98289284Srpaulo 99289284Srpaulo /* 100289284Srpaulo * Write a file with a name and filetype but no size. 101289284Srpaulo */ 102289284Srpaulo assert((ae = archive_entry_new()) != NULL); 103289284Srpaulo archive_entry_copy_pathname(ae, "name"); 104289284Srpaulo archive_entry_unset_size(ae); 105289284Srpaulo archive_entry_set_filetype(ae, AE_IFREG); 106289284Srpaulo assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); 107289284Srpaulo assert(archive_error_string(a) != NULL); 108289284Srpaulo archive_entry_free(ae); 109289284Srpaulo 110289284Srpaulo /* 111289284Srpaulo * Write a file with a name and size but no filetype. 112289284Srpaulo */ 113289284Srpaulo assert((ae = archive_entry_new()) != NULL); 114289284Srpaulo archive_entry_copy_pathname(ae, "name"); 115289284Srpaulo archive_entry_set_size(ae, 0); 116289284Srpaulo assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); 117289284Srpaulo assert(archive_error_string(a) != NULL); 118289284Srpaulo archive_entry_free(ae); 119289284Srpaulo 120289284Srpaulo /* 121289284Srpaulo * Write a file with a size and filetype but no name. 122289284Srpaulo */ 123289284Srpaulo assert((ae = archive_entry_new()) != NULL); 124289284Srpaulo archive_entry_set_size(ae, 0); 125289284Srpaulo archive_entry_set_filetype(ae, AE_IFREG); 126289284Srpaulo assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); 127289284Srpaulo assert(archive_error_string(a) != NULL); 128289284Srpaulo archive_entry_free(ae); 129289284Srpaulo 130289284Srpaulo /* 131289284Srpaulo * Write a directory to it. 132289284Srpaulo */ 133289284Srpaulo assert((ae = archive_entry_new()) != NULL); 134289284Srpaulo archive_entry_set_mtime(ae, 11, 110); 135289284Srpaulo archive_entry_copy_pathname(ae, "dir"); 136289284Srpaulo archive_entry_set_mode(ae, S_IFDIR | 0755); 137289284Srpaulo archive_entry_set_size(ae, 512); 138289284Srpaulo 139289284Srpaulo assertA(0 == archive_write_header(a, ae)); 140289284Srpaulo assertEqualInt(0, archive_entry_size(ae)); 141289284Srpaulo archive_entry_free(ae); 142289284Srpaulo assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); 143289284Srpaulo 144289284Srpaulo /* 145289284Srpaulo * Write a character device to it. 146289284Srpaulo */ 147289284Srpaulo assert((ae = archive_entry_new()) != NULL); 148289284Srpaulo archive_entry_copy_pathname(ae, "tty0"); 149289284Srpaulo archive_entry_set_mode(ae, S_IFCHR | 0600); 150289284Srpaulo archive_entry_set_size(ae, 0); 151289284Srpaulo archive_entry_set_rdev(ae, 1024); 152289284Srpaulo assertA(0 == archive_write_header(a, ae)); 153289284Srpaulo archive_entry_free(ae); 154289284Srpaulo 155289284Srpaulo 156289284Srpaulo /* Close out the archive. */ 157289284Srpaulo assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 158289284Srpaulo assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 159289284Srpaulo 160289284Srpaulo /* 161289284Srpaulo * Damage the second entry to test the search-ahead recovery. 162289284Srpaulo * TODO: Move the damage-recovery checking to a separate test; 163289284Srpaulo * it doesn't really belong in this write test. 164289284Srpaulo */ 165289284Srpaulo { 166289284Srpaulo int i; 167289284Srpaulo for (i = 80; i < 150; i++) { 168289284Srpaulo if (memcmp(buff + i, "07070", 5) == 0) { 169289284Srpaulo damaged = 1; 170289284Srpaulo buff[i] = 'X'; 171289284Srpaulo break; 172289284Srpaulo } 173289284Srpaulo } 174289284Srpaulo } 175289284Srpaulo failure("Unable to locate the second header for damage-recovery test."); 176289284Srpaulo assert(damaged == 1); 177289284Srpaulo 178289284Srpaulo /* 179289284Srpaulo * Now, read the data back. 180289284Srpaulo */ 181289284Srpaulo assert((a = archive_read_new()) != NULL); 182289284Srpaulo assertA(0 == archive_read_support_format_all(a)); 183289284Srpaulo assertA(0 == archive_read_support_filter_all(a)); 184337817Scy assertA(0 == archive_read_open_memory(a, buff, used)); 185337817Scy 186289284Srpaulo if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) { 187289284Srpaulo archive_read_free(a); 188289284Srpaulo return; 189289284Srpaulo } 190289284Srpaulo 191289284Srpaulo assertEqualInt(1, archive_entry_mtime(ae)); 192289284Srpaulo /* Not the same as above: cpio doesn't store hi-res times. */ 193289284Srpaulo assert(0 == archive_entry_mtime_nsec(ae)); 194289284Srpaulo assert(0 == archive_entry_atime(ae)); 195289284Srpaulo assert(0 == archive_entry_ctime(ae)); 196289284Srpaulo assertEqualString("file", archive_entry_pathname(ae)); 197289284Srpaulo assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); 198289284Srpaulo assertEqualInt(8, archive_entry_size(ae)); 199289284Srpaulo assertA(8 == archive_read_data(a, filedata, 10)); 200289284Srpaulo assertEqualMem(filedata, "12345678", 8); 201289284Srpaulo 202289284Srpaulo /* 203289284Srpaulo * The second file can't be read because we damaged its header. 204289284Srpaulo */ 205289284Srpaulo 206289284Srpaulo /* 207289284Srpaulo * Read the third file back. 208289284Srpaulo * ARCHIVE_WARN here because the damaged entry was skipped. 209289284Srpaulo */ 210289284Srpaulo assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); 211289284Srpaulo assertEqualString("name", archive_entry_pathname(ae)); 212289284Srpaulo 213289284Srpaulo /* 214289284Srpaulo * Read the dir entry back. 215289284Srpaulo */ 216289284Srpaulo assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 217289284Srpaulo assertEqualInt(11, archive_entry_mtime(ae)); 218289284Srpaulo assert(0 == archive_entry_mtime_nsec(ae)); 219289284Srpaulo assert(0 == archive_entry_atime(ae)); 220289284Srpaulo assert(0 == archive_entry_ctime(ae)); 221289284Srpaulo assertEqualString("dir", archive_entry_pathname(ae)); 222289284Srpaulo assertEqualInt((S_IFDIR | 0755), archive_entry_mode(ae)); 223289284Srpaulo assertEqualInt(0, archive_entry_size(ae)); 224289284Srpaulo assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); 225289284Srpaulo 226289284Srpaulo /* 227289284Srpaulo * Read the character device entry back. 228289284Srpaulo */ 229289284Srpaulo assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 230289284Srpaulo assertEqualString("tty0", archive_entry_pathname(ae)); 231289284Srpaulo assertEqualInt((S_IFCHR | 0600), archive_entry_mode(ae)); 232289284Srpaulo assertEqualInt(0, archive_entry_size(ae)); 233289284Srpaulo assertEqualInt(1024, archive_entry_rdev(ae)); 234289284Srpaulo 235289284Srpaulo /* Verify the end of the archive. */ 236289284Srpaulo assertEqualIntA(a, 1, archive_read_next_header(a, &ae)); 237289284Srpaulo assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 238289284Srpaulo assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 239289284Srpaulo 240289284Srpaulo free(buff); 241289284Srpaulo} 242289284Srpaulo 243289284Srpaulostatic void 244289284Srpaulotest_big_entries(int (*set_format)(struct archive *), int64_t size, int expected) 245289284Srpaulo{ 246289284Srpaulo struct archive_entry *ae; 247289284Srpaulo struct archive *a; 248289284Srpaulo size_t buffsize = 1000000; 249289284Srpaulo size_t used; 250289284Srpaulo char *buff; 251289284Srpaulo 252289284Srpaulo buff = malloc(buffsize); 253289284Srpaulo 254289284Srpaulo /* Create a new archive in memory. */ 255289284Srpaulo assert((a = archive_write_new()) != NULL); 256289284Srpaulo assertA(0 == (*set_format)(a)); 257289284Srpaulo assertA(0 == archive_write_add_filter_none(a)); 258289284Srpaulo assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); 259289284Srpaulo 260289284Srpaulo assert((ae = archive_entry_new()) != NULL); 261289284Srpaulo archive_entry_copy_pathname(ae, "file"); 262289284Srpaulo archive_entry_set_size(ae, size); 263289284Srpaulo archive_entry_set_filetype(ae, AE_IFREG); 264289284Srpaulo assertEqualInt(expected, archive_write_header(a, ae)); 265289284Srpaulo if (expected != ARCHIVE_OK) 266289284Srpaulo assert(archive_error_string(a) != NULL); 267289284Srpaulo 268289284Srpaulo archive_entry_free(ae); 269289284Srpaulo archive_write_free(a); 270289284Srpaulo free(buff); 271289284Srpaulo} 272289284Srpaulo 273289284Srpaulo 274289284SrpauloDEFINE_TEST(test_write_format_cpio) 275289284Srpaulo{ 276289284Srpaulo int64_t size_4g = ((int64_t)1) << 32; 277289284Srpaulo int64_t size_8g = ((int64_t)1) << 33; 278289284Srpaulo 279289284Srpaulo test_format(archive_write_set_format_cpio); 280289284Srpaulo test_format(archive_write_set_format_cpio_newc); 281289284Srpaulo 282289284Srpaulo test_big_entries(archive_write_set_format_cpio, 283289284Srpaulo size_8g - 1, ARCHIVE_OK); 284289284Srpaulo test_big_entries(archive_write_set_format_cpio, 285289284Srpaulo size_8g, ARCHIVE_FAILED); 286289284Srpaulo test_big_entries(archive_write_set_format_cpio_newc, 287289284Srpaulo size_4g - 1, ARCHIVE_OK); 288289284Srpaulo test_big_entries(archive_write_set_format_cpio_newc, 289289284Srpaulo size_4g, ARCHIVE_FAILED); 290289284Srpaulo} 291289284Srpaulo