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_format_gtar_sparse.c 358088 2020-02-19 01:50:47Z mm $"); 27228753Smm 28228753Smm 29228753Smmstruct contents { 30232153Smm int64_t o; 31228753Smm size_t s; 32228753Smm const char *d; 33228753Smm}; 34228753Smm 35228753Smmstruct contents archive_contents_sparse[] = { 36228753Smm { 1000000, 1, "a" }, 37228753Smm { 2000000, 1, "a" }, 38228753Smm { 3145728, 0, NULL } 39228753Smm}; 40228753Smm 41228753Smmstruct contents archive_contents_sparse2[] = { 42228753Smm { 1000000, 1, "a" }, 43228753Smm { 2000000, 1, "a" }, 44228753Smm { 3000000, 1, "a" }, 45228753Smm { 4000000, 1, "a" }, 46228753Smm { 5000000, 1, "a" }, 47228753Smm { 6000000, 1, "a" }, 48228753Smm { 7000000, 1, "a" }, 49228753Smm { 8000000, 1, "a" }, 50228753Smm { 9000000, 1, "a" }, 51228753Smm { 10000000, 1, "a" }, 52228753Smm { 11000000, 1, "a" }, 53228753Smm { 12000000, 1, "a" }, 54228753Smm { 13000000, 1, "a" }, 55228753Smm { 14000000, 1, "a" }, 56228753Smm { 15000000, 1, "a" }, 57228753Smm { 16000000, 1, "a" }, 58228753Smm { 17000000, 1, "a" }, 59228753Smm { 18000000, 1, "a" }, 60228753Smm { 19000000, 1, "a" }, 61228753Smm { 20000000, 1, "a" }, 62228753Smm { 21000000, 1, "a" }, 63228753Smm { 22000000, 1, "a" }, 64228753Smm { 23000000, 1, "a" }, 65228753Smm { 24000000, 1, "a" }, 66228753Smm { 25000000, 1, "a" }, 67228753Smm { 26000000, 1, "a" }, 68228753Smm { 27000000, 1, "a" }, 69228753Smm { 28000000, 1, "a" }, 70228753Smm { 29000000, 1, "a" }, 71228753Smm { 30000000, 1, "a" }, 72228753Smm { 31000000, 1, "a" }, 73228753Smm { 32000000, 1, "a" }, 74228753Smm { 33000000, 1, "a" }, 75228753Smm { 34000000, 1, "a" }, 76228753Smm { 35000000, 1, "a" }, 77228753Smm { 36000000, 1, "a" }, 78228753Smm { 37000000, 1, "a" }, 79228753Smm { 38000000, 1, "a" }, 80228753Smm { 39000000, 1, "a" }, 81228753Smm { 40000000, 1, "a" }, 82228753Smm { 41000000, 1, "a" }, 83228753Smm { 42000000, 1, "a" }, 84228753Smm { 43000000, 1, "a" }, 85228753Smm { 44000000, 1, "a" }, 86228753Smm { 45000000, 1, "a" }, 87228753Smm { 46000000, 1, "a" }, 88228753Smm { 47000000, 1, "a" }, 89228753Smm { 48000000, 1, "a" }, 90228753Smm { 49000000, 1, "a" }, 91228753Smm { 50000000, 1, "a" }, 92228753Smm { 51000000, 1, "a" }, 93228753Smm { 52000000, 1, "a" }, 94228753Smm { 53000000, 1, "a" }, 95228753Smm { 54000000, 1, "a" }, 96228753Smm { 55000000, 1, "a" }, 97228753Smm { 56000000, 1, "a" }, 98228753Smm { 57000000, 1, "a" }, 99228753Smm { 58000000, 1, "a" }, 100228753Smm { 59000000, 1, "a" }, 101228753Smm { 60000000, 1, "a" }, 102228753Smm { 61000000, 1, "a" }, 103228753Smm { 62000000, 1, "a" }, 104228753Smm { 63000000, 1, "a" }, 105228753Smm { 64000000, 1, "a" }, 106228753Smm { 65000000, 1, "a" }, 107228753Smm { 66000000, 1, "a" }, 108228753Smm { 67000000, 1, "a" }, 109228753Smm { 68000000, 1, "a" }, 110228753Smm { 69000000, 1, "a" }, 111228753Smm { 70000000, 1, "a" }, 112228753Smm { 71000000, 1, "a" }, 113228753Smm { 72000000, 1, "a" }, 114228753Smm { 73000000, 1, "a" }, 115228753Smm { 74000000, 1, "a" }, 116228753Smm { 75000000, 1, "a" }, 117228753Smm { 76000000, 1, "a" }, 118228753Smm { 77000000, 1, "a" }, 119228753Smm { 78000000, 1, "a" }, 120228753Smm { 79000000, 1, "a" }, 121228753Smm { 80000000, 1, "a" }, 122228753Smm { 81000000, 1, "a" }, 123228753Smm { 82000000, 1, "a" }, 124228753Smm { 83000000, 1, "a" }, 125228753Smm { 84000000, 1, "a" }, 126228753Smm { 85000000, 1, "a" }, 127228753Smm { 86000000, 1, "a" }, 128228753Smm { 87000000, 1, "a" }, 129228753Smm { 88000000, 1, "a" }, 130228753Smm { 89000000, 1, "a" }, 131228753Smm { 90000000, 1, "a" }, 132228753Smm { 91000000, 1, "a" }, 133228753Smm { 92000000, 1, "a" }, 134228753Smm { 93000000, 1, "a" }, 135228753Smm { 94000000, 1, "a" }, 136228753Smm { 95000000, 1, "a" }, 137228753Smm { 96000000, 1, "a" }, 138228753Smm { 97000000, 1, "a" }, 139228753Smm { 98000000, 1, "a" }, 140228753Smm { 99000000, 1, "a" }, 141228753Smm { 99000001, 0, NULL } 142228753Smm}; 143228753Smm 144228753Smmstruct contents archive_contents_nonsparse[] = { 145228753Smm { 0, 1, "a" }, 146228753Smm { 1, 0, NULL } 147228753Smm}; 148228753Smm 149228753Smm/* 150228753Smm * Describe an archive with three entries: 151228753Smm * 152228753Smm * File 1: named "sparse" 153228753Smm * * a length of 3145728 bytes (3MiB) 154228753Smm * * a single 'a' byte at offset 1000000 155228753Smm * * a single 'a' byte at offset 2000000 156228753Smm * File 2: named "sparse2" 157228753Smm * * a single 'a' byte at offset 1,000,000, 2,000,000, ..., 99,000,000 158228753Smm * * length of 99,000,001 159228753Smm * File 3: named 'non-sparse' 160228753Smm * * length of 1 byte 161228753Smm * * contains a single byte 'a' 162228753Smm */ 163228753Smm 164228753Smmstruct archive_contents { 165228753Smm const char *filename; 166228753Smm struct contents *contents; 167228753Smm} files[] = { 168228753Smm { "sparse", archive_contents_sparse }, 169228753Smm { "sparse2", archive_contents_sparse2 }, 170228753Smm { "non-sparse", archive_contents_nonsparse }, 171228753Smm { NULL, NULL } 172228753Smm}; 173228753Smm 174228753Smmstatic void 175228753Smmverify_archive_file(const char *name, struct archive_contents *ac) 176228753Smm{ 177228753Smm struct archive_entry *ae; 178228753Smm int err; 179228753Smm /* data, size, offset of next expected block. */ 180228753Smm struct contents expect; 181228753Smm /* data, size, offset of block read from archive. */ 182228753Smm struct contents actual; 183228753Smm const void *p; 184228753Smm struct archive *a; 185228753Smm 186228753Smm extract_reference_file(name); 187228753Smm 188228753Smm assert((a = archive_read_new()) != NULL); 189232153Smm assert(0 == archive_read_support_filter_all(a)); 190228753Smm assert(0 == archive_read_support_format_tar(a)); 191228753Smm failure("Can't open %s", name); 192228753Smm assert(0 == archive_read_open_filename(a, name, 3)); 193228753Smm 194228753Smm while (ac->filename != NULL) { 195228753Smm struct contents *cts = ac->contents; 196228753Smm 197228753Smm if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) { 198232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 199228753Smm return; 200228753Smm } 201228753Smm failure("Name mismatch in archive %s", name); 202228753Smm assertEqualString(ac->filename, archive_entry_pathname(ae)); 203299529Smm assertEqualInt(archive_entry_is_encrypted(ae), 0); 204299529Smm assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 205228753Smm 206228753Smm expect = *cts++; 207228753Smm while (0 == (err = archive_read_data_block(a, 208228753Smm &p, &actual.s, &actual.o))) { 209228753Smm actual.d = p; 210228753Smm while (actual.s > 0) { 211228753Smm char c = *actual.d; 212228753Smm if(actual.o < expect.o) { 213228753Smm /* 214228753Smm * Any byte before the expected 215228753Smm * data must be NULL. 216228753Smm */ 217358088Smm failure("%s: pad at offset %jd " 218358088Smm "should be zero", name, 219358088Smm (intmax_t)actual.o); 220228753Smm assertEqualInt(c, 0); 221228753Smm } else if (actual.o == expect.o) { 222228753Smm /* 223228753Smm * Data at matching offsets must match. 224228753Smm */ 225228753Smm assertEqualInt(c, *expect.d); 226228753Smm expect.d++; 227228753Smm expect.o++; 228228753Smm expect.s--; 229228753Smm /* End of expected? step to next expected. */ 230228753Smm if (expect.s <= 0) 231228753Smm expect = *cts++; 232228753Smm } else { 233228753Smm /* 234228753Smm * We found data beyond that expected. 235228753Smm */ 236228753Smm failure("%s: Unexpected trailing data", 237228753Smm name); 238228753Smm assert(actual.o <= expect.o); 239232153Smm archive_read_free(a); 240228753Smm return; 241228753Smm } 242228753Smm actual.d++; 243228753Smm actual.o++; 244228753Smm actual.s--; 245228753Smm } 246228753Smm } 247228753Smm failure("%s: should be end of entry", name); 248228753Smm assertEqualIntA(a, err, ARCHIVE_EOF); 249228753Smm failure("%s: Size returned at EOF must be zero", name); 250228753Smm assertEqualInt((int)actual.s, 0); 251228753Smm failure("%s: Offset of final empty chunk must be same as file size", name); 252228753Smm assertEqualInt(actual.o, expect.o); 253228753Smm /* Step to next file description. */ 254228753Smm ++ac; 255228753Smm } 256228753Smm 257228753Smm err = archive_read_next_header(a, &ae); 258228753Smm assertEqualIntA(a, ARCHIVE_EOF, err); 259228753Smm 260232153Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 261232153Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 262228753Smm} 263228753Smm 264228753Smm 265228753SmmDEFINE_TEST(test_read_format_gtar_sparse) 266228753Smm{ 267228753Smm /* Two archives that use the "GNU tar sparse format". */ 268228753Smm verify_archive_file("test_read_format_gtar_sparse_1_13.tar", files); 269228753Smm verify_archive_file("test_read_format_gtar_sparse_1_17.tar", files); 270228753Smm 271228753Smm /* 272228753Smm * libarchive < 1.9 doesn't support the newer --posix sparse formats 273228753Smm * from GNU tar 1.15 and later. 274228753Smm */ 275232153Smm 276228753Smm /* 277228753Smm * An archive created by GNU tar 1.17 using --posix --sparse-format=0.1 278228753Smm */ 279228753Smm verify_archive_file( 280228753Smm "test_read_format_gtar_sparse_1_17_posix00.tar", 281228753Smm files); 282228753Smm /* 283228753Smm * An archive created by GNU tar 1.17 using --posix --sparse-format=0.1 284228753Smm */ 285228753Smm verify_archive_file( 286228753Smm "test_read_format_gtar_sparse_1_17_posix01.tar", 287228753Smm files); 288228753Smm /* 289228753Smm * An archive created by GNU tar 1.17 using --posix --sparse-format=1.0 290228753Smm */ 291228753Smm verify_archive_file( 292228753Smm "test_read_format_gtar_sparse_1_17_posix10.tar", 293228753Smm files); 294228753Smm /* 295228753Smm * The last test archive here is a little odd. First, it's 296228753Smm * uncompressed, because that exercises some of the block 297228753Smm * reassembly code a little harder. Second, it includes some 298228753Smm * leading comments prior to the sparse block description. 299228753Smm * GNU tar doesn't do this, but I think it should, so I want 300228753Smm * to ensure that libarchive correctly ignores such comments. 301228753Smm * Dump the file, looking for "#!gnu-sparse-format" starting 302228753Smm * at byte 0x600. 303228753Smm */ 304228753Smm verify_archive_file( 305228753Smm "test_read_format_gtar_sparse_1_17_posix10_modified.tar", 306228753Smm files); 307228753Smm} 308228753Smm 309228753Smm 310