Blame libarchive/test/test_read_format_gtar_sparse.c

Packit Service 1d0348
/*-
Packit Service 1d0348
 * Copyright (c) 2003-2007 Tim Kientzle
Packit Service 1d0348
 * All rights reserved.
Packit Service 1d0348
 *
Packit Service 1d0348
 * Redistribution and use in source and binary forms, with or without
Packit Service 1d0348
 * modification, are permitted provided that the following conditions
Packit Service 1d0348
 * are met:
Packit Service 1d0348
 * 1. Redistributions of source code must retain the above copyright
Packit Service 1d0348
 *    notice, this list of conditions and the following disclaimer.
Packit Service 1d0348
 * 2. Redistributions in binary form must reproduce the above copyright
Packit Service 1d0348
 *    notice, this list of conditions and the following disclaimer in the
Packit Service 1d0348
 *    documentation and/or other materials provided with the distribution.
Packit Service 1d0348
 *
Packit Service 1d0348
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
Packit Service 1d0348
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Packit Service 1d0348
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Packit Service 1d0348
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit Service 1d0348
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Packit Service 1d0348
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit Service 1d0348
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit Service 1d0348
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit Service 1d0348
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Packit Service 1d0348
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 1d0348
 */
Packit Service 1d0348
#include "test.h"
Packit Service 1d0348
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_gtar_sparse.c 189308 2009-03-03 17:02:51Z kientzle $");
Packit Service 1d0348
Packit Service 1d0348
Packit Service 1d0348
struct contents {
Packit Service 1d0348
	int64_t	o;
Packit Service 1d0348
	size_t	s;
Packit Service 1d0348
	const char *d;
Packit Service 1d0348
};
Packit Service 1d0348
Packit Service 1d0348
struct contents archive_contents_sparse[] = {
Packit Service 1d0348
	{ 1000000, 1, "a" },
Packit Service 1d0348
	{ 2000000, 1, "a" },
Packit Service 1d0348
	{ 3145728, 0, NULL }
Packit Service 1d0348
};
Packit Service 1d0348
Packit Service 1d0348
struct contents archive_contents_sparse2[] = {
Packit Service 1d0348
	{ 1000000, 1, "a" },
Packit Service 1d0348
	{ 2000000, 1, "a" },
Packit Service 1d0348
	{ 3000000, 1, "a" },
Packit Service 1d0348
	{ 4000000, 1, "a" },
Packit Service 1d0348
	{ 5000000, 1, "a" },
Packit Service 1d0348
	{ 6000000, 1, "a" },
Packit Service 1d0348
	{ 7000000, 1, "a" },
Packit Service 1d0348
	{ 8000000, 1, "a" },
Packit Service 1d0348
	{ 9000000, 1, "a" },
Packit Service 1d0348
	{ 10000000, 1, "a" },
Packit Service 1d0348
	{ 11000000, 1, "a" },
Packit Service 1d0348
	{ 12000000, 1, "a" },
Packit Service 1d0348
	{ 13000000, 1, "a" },
Packit Service 1d0348
	{ 14000000, 1, "a" },
Packit Service 1d0348
	{ 15000000, 1, "a" },
Packit Service 1d0348
	{ 16000000, 1, "a" },
Packit Service 1d0348
	{ 17000000, 1, "a" },
Packit Service 1d0348
	{ 18000000, 1, "a" },
Packit Service 1d0348
	{ 19000000, 1, "a" },
Packit Service 1d0348
	{ 20000000, 1, "a" },
Packit Service 1d0348
	{ 21000000, 1, "a" },
Packit Service 1d0348
	{ 22000000, 1, "a" },
Packit Service 1d0348
	{ 23000000, 1, "a" },
Packit Service 1d0348
	{ 24000000, 1, "a" },
Packit Service 1d0348
	{ 25000000, 1, "a" },
Packit Service 1d0348
	{ 26000000, 1, "a" },
Packit Service 1d0348
	{ 27000000, 1, "a" },
Packit Service 1d0348
	{ 28000000, 1, "a" },
Packit Service 1d0348
	{ 29000000, 1, "a" },
Packit Service 1d0348
	{ 30000000, 1, "a" },
Packit Service 1d0348
	{ 31000000, 1, "a" },
Packit Service 1d0348
	{ 32000000, 1, "a" },
Packit Service 1d0348
	{ 33000000, 1, "a" },
Packit Service 1d0348
	{ 34000000, 1, "a" },
Packit Service 1d0348
	{ 35000000, 1, "a" },
Packit Service 1d0348
	{ 36000000, 1, "a" },
Packit Service 1d0348
	{ 37000000, 1, "a" },
Packit Service 1d0348
	{ 38000000, 1, "a" },
Packit Service 1d0348
	{ 39000000, 1, "a" },
Packit Service 1d0348
	{ 40000000, 1, "a" },
Packit Service 1d0348
	{ 41000000, 1, "a" },
Packit Service 1d0348
	{ 42000000, 1, "a" },
Packit Service 1d0348
	{ 43000000, 1, "a" },
Packit Service 1d0348
	{ 44000000, 1, "a" },
Packit Service 1d0348
	{ 45000000, 1, "a" },
Packit Service 1d0348
	{ 46000000, 1, "a" },
Packit Service 1d0348
	{ 47000000, 1, "a" },
Packit Service 1d0348
	{ 48000000, 1, "a" },
Packit Service 1d0348
	{ 49000000, 1, "a" },
Packit Service 1d0348
	{ 50000000, 1, "a" },
Packit Service 1d0348
	{ 51000000, 1, "a" },
Packit Service 1d0348
	{ 52000000, 1, "a" },
Packit Service 1d0348
	{ 53000000, 1, "a" },
Packit Service 1d0348
	{ 54000000, 1, "a" },
Packit Service 1d0348
	{ 55000000, 1, "a" },
Packit Service 1d0348
	{ 56000000, 1, "a" },
Packit Service 1d0348
	{ 57000000, 1, "a" },
Packit Service 1d0348
	{ 58000000, 1, "a" },
Packit Service 1d0348
	{ 59000000, 1, "a" },
Packit Service 1d0348
	{ 60000000, 1, "a" },
Packit Service 1d0348
	{ 61000000, 1, "a" },
Packit Service 1d0348
	{ 62000000, 1, "a" },
Packit Service 1d0348
	{ 63000000, 1, "a" },
Packit Service 1d0348
	{ 64000000, 1, "a" },
Packit Service 1d0348
	{ 65000000, 1, "a" },
Packit Service 1d0348
	{ 66000000, 1, "a" },
Packit Service 1d0348
	{ 67000000, 1, "a" },
Packit Service 1d0348
	{ 68000000, 1, "a" },
Packit Service 1d0348
	{ 69000000, 1, "a" },
Packit Service 1d0348
	{ 70000000, 1, "a" },
Packit Service 1d0348
	{ 71000000, 1, "a" },
Packit Service 1d0348
	{ 72000000, 1, "a" },
Packit Service 1d0348
	{ 73000000, 1, "a" },
Packit Service 1d0348
	{ 74000000, 1, "a" },
Packit Service 1d0348
	{ 75000000, 1, "a" },
Packit Service 1d0348
	{ 76000000, 1, "a" },
Packit Service 1d0348
	{ 77000000, 1, "a" },
Packit Service 1d0348
	{ 78000000, 1, "a" },
Packit Service 1d0348
	{ 79000000, 1, "a" },
Packit Service 1d0348
	{ 80000000, 1, "a" },
Packit Service 1d0348
	{ 81000000, 1, "a" },
Packit Service 1d0348
	{ 82000000, 1, "a" },
Packit Service 1d0348
	{ 83000000, 1, "a" },
Packit Service 1d0348
	{ 84000000, 1, "a" },
Packit Service 1d0348
	{ 85000000, 1, "a" },
Packit Service 1d0348
	{ 86000000, 1, "a" },
Packit Service 1d0348
	{ 87000000, 1, "a" },
Packit Service 1d0348
	{ 88000000, 1, "a" },
Packit Service 1d0348
	{ 89000000, 1, "a" },
Packit Service 1d0348
	{ 90000000, 1, "a" },
Packit Service 1d0348
	{ 91000000, 1, "a" },
Packit Service 1d0348
	{ 92000000, 1, "a" },
Packit Service 1d0348
	{ 93000000, 1, "a" },
Packit Service 1d0348
	{ 94000000, 1, "a" },
Packit Service 1d0348
	{ 95000000, 1, "a" },
Packit Service 1d0348
	{ 96000000, 1, "a" },
Packit Service 1d0348
	{ 97000000, 1, "a" },
Packit Service 1d0348
	{ 98000000, 1, "a" },
Packit Service 1d0348
	{ 99000000, 1, "a" },
Packit Service 1d0348
	{ 99000001, 0, NULL }
Packit Service 1d0348
};
Packit Service 1d0348
Packit Service 1d0348
struct contents archive_contents_nonsparse[] = {
Packit Service 1d0348
	{ 0, 1, "a" },
Packit Service 1d0348
	{ 1, 0, NULL }
Packit Service 1d0348
};
Packit Service 1d0348
Packit Service 1d0348
/*
Packit Service 1d0348
 * Describe an archive with three entries:
Packit Service 1d0348
 *
Packit Service 1d0348
 * File 1: named "sparse"
Packit Service 1d0348
 *   * a length of 3145728 bytes (3MiB)
Packit Service 1d0348
 *   * a single 'a' byte at offset 1000000
Packit Service 1d0348
 *   * a single 'a' byte at offset 2000000
Packit Service 1d0348
 * File 2: named "sparse2"
Packit Service 1d0348
 *   * a single 'a' byte at offset 1,000,000, 2,000,000, ..., 99,000,000
Packit Service 1d0348
 *   * length of 99,000,001
Packit Service 1d0348
 * File 3: named 'non-sparse'
Packit Service 1d0348
 *   * length of 1 byte
Packit Service 1d0348
 *   * contains a single byte 'a'
Packit Service 1d0348
 */
Packit Service 1d0348
Packit Service 1d0348
struct archive_contents {
Packit Service 1d0348
	const char *filename;
Packit Service 1d0348
	struct contents *contents;
Packit Service 1d0348
} files[] = {
Packit Service 1d0348
	{ "sparse", archive_contents_sparse },
Packit Service 1d0348
	{ "sparse2", archive_contents_sparse2 },
Packit Service 1d0348
	{ "non-sparse", archive_contents_nonsparse },
Packit Service 1d0348
	{ NULL, NULL }
Packit Service 1d0348
};
Packit Service 1d0348
Packit Service 1d0348
static void
Packit Service 1d0348
verify_archive_file(const char *name, struct archive_contents *ac)
Packit Service 1d0348
{
Packit Service 1d0348
	struct archive_entry *ae;
Packit Service 1d0348
	int err;
Packit Service 1d0348
	/* data, size, offset of next expected block. */
Packit Service 1d0348
	struct contents expect;
Packit Service 1d0348
	/* data, size, offset of block read from archive. */
Packit Service 1d0348
	struct contents actual;
Packit Service 1d0348
	const void *p;
Packit Service 1d0348
	struct archive *a;
Packit Service 1d0348
Packit Service 1d0348
	extract_reference_file(name);
Packit Service 1d0348
Packit Service 1d0348
	assert((a = archive_read_new()) != NULL);
Packit Service 1d0348
	assert(0 == archive_read_support_filter_all(a));
Packit Service 1d0348
	assert(0 == archive_read_support_format_tar(a));
Packit Service 1d0348
	failure("Can't open %s", name);
Packit Service 1d0348
	assert(0 == archive_read_open_filename(a, name, 3));
Packit Service 1d0348
Packit Service 1d0348
	while (ac->filename != NULL) {
Packit Service 1d0348
		struct contents *cts = ac->contents;
Packit Service 1d0348
Packit Service 1d0348
		if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) {
Packit Service 1d0348
			assertEqualInt(ARCHIVE_OK, archive_read_free(a));
Packit Service 1d0348
			return;
Packit Service 1d0348
		}
Packit Service 1d0348
		failure("Name mismatch in archive %s", name);
Packit Service 1d0348
		assertEqualString(ac->filename, archive_entry_pathname(ae));
Packit Service 1d0348
		assertEqualInt(archive_entry_is_encrypted(ae), 0);
Packit Service 1d0348
		assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
Packit Service 1d0348
Packit Service 1d0348
		expect = *cts++;
Packit Service 1d0348
		while (0 == (err = archive_read_data_block(a,
Packit Service 1d0348
				 &p, &actual.s, &actual.o))) {
Packit Service 1d0348
			actual.d = p;
Packit Service 1d0348
			while (actual.s > 0) {
Packit Service 1d0348
				char c = *actual.d;
Packit Service 1d0348
				if(actual.o < expect.o) {
Packit Service 1d0348
					/*
Packit Service 1d0348
					 * Any byte before the expected
Packit Service 1d0348
					 * data must be NULL.
Packit Service 1d0348
					 */
Packit Service 1d0348
					failure("%s: pad at offset %d "
Packit Service 1d0348
					    "should be zero", name, actual.o);
Packit Service 1d0348
					assertEqualInt(c, 0);
Packit Service 1d0348
				} else if (actual.o == expect.o) {
Packit Service 1d0348
					/*
Packit Service 1d0348
					 * Data at matching offsets must match.
Packit Service 1d0348
					 */
Packit Service 1d0348
					assertEqualInt(c, *expect.d);
Packit Service 1d0348
					expect.d++;
Packit Service 1d0348
					expect.o++;
Packit Service 1d0348
					expect.s--;
Packit Service 1d0348
					/* End of expected? step to next expected. */
Packit Service 1d0348
					if (expect.s <= 0)
Packit Service 1d0348
						expect = *cts++;
Packit Service 1d0348
				} else {
Packit Service 1d0348
					/*
Packit Service 1d0348
					 * We found data beyond that expected.
Packit Service 1d0348
					 */
Packit Service 1d0348
					failure("%s: Unexpected trailing data",
Packit Service 1d0348
					    name);
Packit Service 1d0348
					assert(actual.o <= expect.o);
Packit Service 1d0348
					archive_read_free(a);
Packit Service 1d0348
					return;
Packit Service 1d0348
				}
Packit Service 1d0348
				actual.d++;
Packit Service 1d0348
				actual.o++;
Packit Service 1d0348
				actual.s--;
Packit Service 1d0348
			}
Packit Service 1d0348
		}
Packit Service 1d0348
		failure("%s: should be end of entry", name);
Packit Service 1d0348
		assertEqualIntA(a, err, ARCHIVE_EOF);
Packit Service 1d0348
		failure("%s: Size returned at EOF must be zero", name);
Packit Service 1d0348
		assertEqualInt((int)actual.s, 0);
Packit Service 1d0348
		failure("%s: Offset of final empty chunk must be same as file size", name);
Packit Service 1d0348
		assertEqualInt(actual.o, expect.o);
Packit Service 1d0348
		/* Step to next file description. */
Packit Service 1d0348
		++ac;
Packit Service 1d0348
	}
Packit Service 1d0348
Packit Service 1d0348
	err = archive_read_next_header(a, &ae);
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_EOF, err);
Packit Service 1d0348
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
Packit Service 1d0348
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
Packit Service 1d0348
}
Packit Service 1d0348
Packit Service 1d0348
Packit Service 1d0348
DEFINE_TEST(test_read_format_gtar_sparse)
Packit Service 1d0348
{
Packit Service 1d0348
	/* Two archives that use the "GNU tar sparse format". */
Packit Service 1d0348
	verify_archive_file("test_read_format_gtar_sparse_1_13.tar", files);
Packit Service 1d0348
	verify_archive_file("test_read_format_gtar_sparse_1_17.tar", files);
Packit Service 1d0348
Packit Service 1d0348
	/*
Packit Service 1d0348
	 * libarchive < 1.9 doesn't support the newer --posix sparse formats
Packit Service 1d0348
	 * from GNU tar 1.15 and later.
Packit Service 1d0348
	 */
Packit Service 1d0348
Packit Service 1d0348
	/*
Packit Service 1d0348
	 * An archive created by GNU tar 1.17 using --posix --sparse-format=0.1
Packit Service 1d0348
	 */
Packit Service 1d0348
	verify_archive_file(
Packit Service 1d0348
		"test_read_format_gtar_sparse_1_17_posix00.tar",
Packit Service 1d0348
		files);
Packit Service 1d0348
	/*
Packit Service 1d0348
	 * An archive created by GNU tar 1.17 using --posix --sparse-format=0.1
Packit Service 1d0348
	 */
Packit Service 1d0348
	verify_archive_file(
Packit Service 1d0348
		"test_read_format_gtar_sparse_1_17_posix01.tar",
Packit Service 1d0348
		files);
Packit Service 1d0348
	/*
Packit Service 1d0348
	 * An archive created by GNU tar 1.17 using --posix --sparse-format=1.0
Packit Service 1d0348
	 */
Packit Service 1d0348
	verify_archive_file(
Packit Service 1d0348
		"test_read_format_gtar_sparse_1_17_posix10.tar",
Packit Service 1d0348
		files);
Packit Service 1d0348
	/*
Packit Service 1d0348
	 * The last test archive here is a little odd.  First, it's
Packit Service 1d0348
	 * uncompressed, because that exercises some of the block
Packit Service 1d0348
	 * reassembly code a little harder.  Second, it includes some
Packit Service 1d0348
	 * leading comments prior to the sparse block description.
Packit Service 1d0348
	 * GNU tar doesn't do this, but I think it should, so I want
Packit Service 1d0348
	 * to ensure that libarchive correctly ignores such comments.
Packit Service 1d0348
	 * Dump the file, looking for "#!gnu-sparse-format" starting
Packit Service 1d0348
	 * at byte 0x600.
Packit Service 1d0348
	 */
Packit Service 1d0348
	verify_archive_file(
Packit Service 1d0348
		"test_read_format_gtar_sparse_1_17_posix10_modified.tar",
Packit Service 1d0348
		files);
Packit Service 1d0348
}
Packit Service 1d0348
Packit Service 1d0348