test_read_extract.c revision 348607
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: stable/11/contrib/libarchive/libarchive/test/test_read_extract.c 348607 2019-06-04 10:35:54Z mm $"); 27228753Smm 28228753Smm#define BUFF_SIZE 1000000 29228753Smm#define FILE_BUFF_SIZE 100000 30228753Smm 31228753SmmDEFINE_TEST(test_read_extract) 32228753Smm{ 33228753Smm struct archive_entry *ae; 34228753Smm struct archive *a; 35228753Smm size_t used; 36228753Smm int i, numEntries = 0; 37228753Smm char *buff, *file_buff; 38228753Smm 39228753Smm buff = malloc(BUFF_SIZE); 40228753Smm file_buff = malloc(FILE_BUFF_SIZE); 41228753Smm 42228753Smm /* Force the umask to something predictable. */ 43228753Smm assertUmask(022); 44228753Smm 45228753Smm /* Create a new archive in memory containing various types of entries. */ 46228753Smm assert((a = archive_write_new()) != NULL); 47228753Smm assertA(0 == archive_write_set_format_ustar(a)); 48248616Smm assertA(0 == archive_write_add_filter_none(a)); 49228753Smm assertA(0 == archive_write_open_memory(a, buff, BUFF_SIZE, &used)); 50228753Smm /* A directory to be restored with EXTRACT_PERM. */ 51228753Smm ++numEntries; 52228753Smm assert((ae = archive_entry_new()) != NULL); 53228753Smm archive_entry_copy_pathname(ae, "dir_0775"); 54228753Smm archive_entry_set_mode(ae, S_IFDIR | 0775); 55228753Smm assertA(0 == archive_write_header(a, ae)); 56228753Smm archive_entry_free(ae); 57228753Smm /* A regular file. */ 58228753Smm ++numEntries; 59228753Smm assert((ae = archive_entry_new()) != NULL); 60228753Smm archive_entry_copy_pathname(ae, "file"); 61228753Smm archive_entry_set_mode(ae, S_IFREG | 0755); 62228753Smm for (i = 0; i < FILE_BUFF_SIZE; i++) 63228753Smm file_buff[i] = (unsigned char)rand(); 64228753Smm archive_entry_set_size(ae, FILE_BUFF_SIZE); 65228753Smm assertA(0 == archive_write_header(a, ae)); 66228753Smm assertA(FILE_BUFF_SIZE == archive_write_data(a, file_buff, FILE_BUFF_SIZE)); 67228753Smm archive_entry_free(ae); 68228753Smm /* A directory that should obey umask when restored. */ 69228753Smm ++numEntries; 70228753Smm assert((ae = archive_entry_new()) != NULL); 71228753Smm archive_entry_copy_pathname(ae, "dir"); 72228753Smm archive_entry_set_mode(ae, S_IFDIR | 0777); 73228753Smm assertA(0 == archive_write_header(a, ae)); 74228753Smm archive_entry_free(ae); 75228753Smm /* A file in the directory. */ 76228753Smm ++numEntries; 77228753Smm assert((ae = archive_entry_new()) != NULL); 78228753Smm archive_entry_copy_pathname(ae, "dir/file"); 79228753Smm archive_entry_set_mode(ae, S_IFREG | 0700); 80228753Smm assertA(0 == archive_write_header(a, ae)); 81228753Smm archive_entry_free(ae); 82228753Smm /* A file in a dir that is not already in the archive. */ 83228753Smm ++numEntries; 84228753Smm assert((ae = archive_entry_new()) != NULL); 85228753Smm archive_entry_copy_pathname(ae, "dir2/file"); 86228753Smm archive_entry_set_mode(ae, S_IFREG | 0000); 87228753Smm assertA(0 == archive_write_header(a, ae)); 88228753Smm archive_entry_free(ae); 89228753Smm /* A dir with a trailing /. */ 90228753Smm ++numEntries; 91228753Smm assert((ae = archive_entry_new()) != NULL); 92228753Smm archive_entry_copy_pathname(ae, "dir3/."); 93228753Smm archive_entry_set_mode(ae, S_IFDIR | 0710); 94228753Smm assertA(0 == archive_write_header(a, ae)); 95228753Smm archive_entry_free(ae); 96228753Smm /* Multiple dirs with a single entry. */ 97228753Smm ++numEntries; 98228753Smm assert((ae = archive_entry_new()) != NULL); 99228753Smm archive_entry_copy_pathname(ae, "dir4/a/../b/../c/"); 100228753Smm archive_entry_set_mode(ae, S_IFDIR | 0711); 101228753Smm assertA(0 == archive_write_header(a, ae)); 102228753Smm archive_entry_free(ae); 103228753Smm /* A symlink. */ 104228753Smm if (canSymlink()) { 105228753Smm ++numEntries; 106228753Smm assert((ae = archive_entry_new()) != NULL); 107228753Smm archive_entry_copy_pathname(ae, "symlink"); 108228753Smm archive_entry_set_mode(ae, AE_IFLNK | 0755); 109228753Smm archive_entry_set_symlink(ae, "file"); 110228753Smm assertA(0 == archive_write_header(a, ae)); 111228753Smm archive_entry_free(ae); 112228753Smm } 113228753Smm /* Close out the archive. */ 114232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 115232153Smm assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 116228753Smm 117228753Smm /* Extract the entries to disk. */ 118228753Smm assert((a = archive_read_new()) != NULL); 119228753Smm assertA(0 == archive_read_support_format_all(a)); 120232153Smm assertA(0 == archive_read_support_filter_all(a)); 121228753Smm assertA(0 == archive_read_open_memory(a, buff, BUFF_SIZE)); 122228753Smm /* Restore first entry with _EXTRACT_PERM. */ 123228753Smm failure("Error reading first entry", i); 124228753Smm assertA(0 == archive_read_next_header(a, &ae)); 125228753Smm assertA(0 == archive_read_extract(a, ae, ARCHIVE_EXTRACT_PERM)); 126228753Smm /* Rest of entries get restored with no flags. */ 127228753Smm for (i = 1; i < numEntries; i++) { 128228753Smm failure("Error reading entry %d", i); 129228753Smm assertA(0 == archive_read_next_header(a, &ae)); 130228753Smm failure("Failed to extract entry %d: %s", i, 131228753Smm archive_entry_pathname(ae)); 132228753Smm assertA(0 == archive_read_extract(a, ae, 0)); 133228753Smm } 134228753Smm assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); 135232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 136232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 137228753Smm 138228753Smm /* Test the entries on disk. */ 139228753Smm /* This first entry was extracted with ARCHIVE_EXTRACT_PERM, 140228753Smm * so the permissions should have been restored exactly, 141228753Smm * including resetting the gid bit on those platforms 142228753Smm * where gid is inherited by subdirs. */ 143228753Smm failure("This was 0775 in archive, and should be 0775 on disk"); 144228753Smm assertIsDir("dir_0775", 0775); 145228753Smm /* Everything else was extracted without ARCHIVE_EXTRACT_PERM, 146228753Smm * so there may be some sloppiness about gid bits on directories. */ 147228753Smm assertIsReg("file", 0755); 148228753Smm assertFileSize("file", FILE_BUFF_SIZE); 149228753Smm assertFileContents(file_buff, FILE_BUFF_SIZE, "file"); 150228753Smm /* If EXTRACT_PERM wasn't used, be careful to ignore sgid bit 151228753Smm * when checking dir modes, as some systems inherit sgid bit 152228753Smm * from the parent dir. */ 153228753Smm failure("This was 0777 in archive, but umask should make it 0755"); 154228753Smm assertIsDir("dir", 0755); 155228753Smm assertIsReg("dir/file", 0700); 156228753Smm assertIsDir("dir2", 0755); 157228753Smm assertIsReg("dir2/file", 0000); 158228753Smm assertIsDir("dir3", 0710); 159228753Smm assertIsDir("dir4", 0755); 160228753Smm assertIsDir("dir4/a", 0755); 161228753Smm assertIsDir("dir4/b", 0755); 162228753Smm assertIsDir("dir4/c", 0711); 163228753Smm if (canSymlink()) 164348607Smm assertIsSymlink("symlink", "file", 0); 165228753Smm 166228753Smm free(buff); 167228753Smm free(file_buff); 168228753Smm} 169