summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2007-08-18 21:53:25 +0000
committerkientzle <kientzle@FreeBSD.org>2007-08-18 21:53:25 +0000
commitb151d17a1b0aaf0d64709c302aee875044239826 (patch)
treed3e7b37891858d72b4d4f3eedae2b5c55b4f970b
parent4a30c00d08af3b22a324f08fd2c30788f2a28111 (diff)
downloadFreeBSD-src-b151d17a1b0aaf0d64709c302aee875044239826.zip
FreeBSD-src-b151d17a1b0aaf0d64709c302aee875044239826.tar.gz
This commit updates libarchive to be compatible with
GNU tar 1.17's implementation of --posix --sparse, at the cost of losing compatibility with GNU tar 1.16. Fortunately, the 1.17 implementation actually makes sense, so the libarchive code is now a bit more straightforward than before. Background: GNU tar 1.16 defined a new way to store sparse files in --posix archives. Unfortunately, the implementation incorrectly inserted several blocks of null padding after each such entry. As a result, non-GNU tar implementations saw the archive as truncated after any sparse entry. This was fixed in GNU tar 1.17 at the cost of losing compatibility with GNU tar 1.16 for this new format (which is not the default, so hopefully rarely used). Libarchive recently gained support for reading the GNU tar 1.16 formats; this commit updates it to read the GNU tar 1.17 variant instead. Approved by: re (ksmith for libarchive portion) Approved by: re (blanket for libarchive_test portion) MFC after: 5 days
-rw-r--r--lib/libarchive/archive_read_support_format_tar.c110
-rw-r--r--lib/libarchive/test/test_read_format_gtar_sparse.c673
2 files changed, 600 insertions, 183 deletions
diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c
index 4559412..9d2aef0 100644
--- a/lib/libarchive/archive_read_support_format_tar.c
+++ b/lib/libarchive/archive_read_support_format_tar.c
@@ -72,6 +72,8 @@ static size_t wcslen(const wchar_t *s)
#include "archive_private.h"
#include "archive_read_private.h"
+#define tar_min(a,b) ((a) < (b) ? (a) : (b))
+
/*
* Layout of POSIX 'ustar' tar header.
*/
@@ -172,6 +174,7 @@ static int archive_block_is_null(const unsigned char *p);
static char *base64_decode(const wchar_t *, size_t, size_t *);
static void gnu_add_sparse_entry(struct tar *,
off_t offset, off_t remaining);
+static void gnu_clear_sparse_list(struct tar *);
static int gnu_sparse_old_read(struct archive_read *, struct tar *,
const struct archive_entry_header_gnutar *header);
static void gnu_sparse_old_parse(struct tar *,
@@ -211,7 +214,8 @@ static int pax_attribute(struct tar *, struct archive_entry *,
static int pax_header(struct archive_read *, struct tar *,
struct archive_entry *, char *attr);
static void pax_time(const wchar_t *, int64_t *sec, long *nanos);
-static ssize_t readline(struct archive_read *, struct tar *, const char **);
+static ssize_t readline(struct archive_read *, struct tar *, const char **,
+ ssize_t limit);
static int read_body_to_string(struct archive_read *, struct tar *,
struct archive_string *, const void *h);
static int64_t tar_atol(const char *, unsigned);
@@ -263,14 +267,9 @@ static int
archive_read_format_tar_cleanup(struct archive_read *a)
{
struct tar *tar;
- struct sparse_block *p;
tar = (struct tar *)(a->format->data);
- while (tar->sparse_list != NULL) {
- p = tar->sparse_list;
- tar->sparse_list = p->next;
- free(p);
- }
+ gnu_clear_sparse_list(tar);
archive_string_free(&tar->acl_text);
archive_string_free(&tar->entry_name);
archive_string_free(&tar->entry_linkname);
@@ -423,7 +422,6 @@ archive_read_format_tar_read_header(struct archive_read *a,
const char *p;
int r;
size_t l;
- ssize_t size;
/* Assign default device/inode values. */
archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */
@@ -446,22 +444,6 @@ archive_read_format_tar_read_header(struct archive_read *a,
r = tar_read_header(a, tar, entry);
/*
- * Yuck. See comments for gnu_sparse_10_read for why this
- * is here and not in _read_data where it "should" go.
- */
- if (tar->sparse_gnu_pending
- && tar->sparse_gnu_major == 1
- && tar->sparse_gnu_minor == 0) {
- tar->sparse_gnu_pending = 0;
- /* Read initial sparse map. */
- size = gnu_sparse_10_read(a, tar);
- if (size < 0)
- return (size);
- tar->entry_bytes_remaining -= size;
- tar->entry_padding += size;
- }
-
- /*
* "non-sparse" files are really just sparse files with
* a single block.
*/
@@ -497,11 +479,12 @@ archive_read_format_tar_read_data(struct archive_read *a,
if (tar->sparse_gnu_pending) {
if (tar->sparse_gnu_major == 1 && tar->sparse_gnu_minor == 0) {
- /*
- * <sigh> We should parse the sparse data
- * here, but have to parse it as part of the
- * header because of a bug in GNU tar 1.16.1.
- */
+ tar->sparse_gnu_pending = 0;
+ /* Read initial sparse map. */
+ bytes_read = gnu_sparse_10_read(a, tar);
+ tar->entry_bytes_remaining -= bytes_read;
+ if (bytes_read < 0)
+ return (bytes_read);
} else {
*size = 0;
*offset = 0;
@@ -559,7 +542,6 @@ archive_read_format_tar_skip(struct archive_read *a)
{
off_t bytes_skipped;
struct tar* tar;
- struct sparse_block *p;
tar = (struct tar *)(a->format->data);
@@ -577,12 +559,7 @@ archive_read_format_tar_skip(struct archive_read *a)
tar->entry_padding = 0;
/* Free the sparse list. */
- while (tar->sparse_list != NULL) {
- p = tar->sparse_list;
- tar->sparse_list = p->next;
- free(p);
- }
- tar->sparse_last = NULL;
+ gnu_clear_sparse_list(tar);
return (ARCHIVE_OK);
}
@@ -1650,6 +1627,19 @@ gnu_add_sparse_entry(struct tar *tar, off_t offset, off_t remaining)
p->remaining = remaining;
}
+static void
+gnu_clear_sparse_list(struct tar *tar)
+{
+ struct sparse_block *p;
+
+ while (tar->sparse_list != NULL) {
+ p = tar->sparse_list;
+ tar->sparse_list = p->next;
+ free(p);
+ }
+ tar->sparse_last = NULL;
+}
+
/*
* GNU tar old-format sparse data.
*
@@ -1793,7 +1783,7 @@ gnu_sparse_01_parse(struct tar *tar, const wchar_t *p)
*/
static int64_t
gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
- ssize_t *total_read)
+ ssize_t *remaining)
{
int64_t l, limit, last_digit_limit;
const char *p;
@@ -1804,10 +1794,16 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
limit = INT64_MAX / base;
last_digit_limit = INT64_MAX % base;
- bytes_read = readline(a, tar, &p);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- *total_read += bytes_read;
+ /*
+ * Skip any lines starting with '#'; GNU tar specs
+ * don't require this, but they should.
+ */
+ do {
+ bytes_read = readline(a, tar, &p, tar_min(*remaining, 100));
+ if (bytes_read <= 0)
+ return (ARCHIVE_FATAL);
+ *remaining -= bytes_read;
+ } while (p[0] == '#');
l = 0;
while (bytes_read > 0) {
@@ -1828,32 +1824,39 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
}
/*
- * Returns number of bytes consumed to read the sparse block data.
+ * Returns length (in bytes) of the sparse data description
+ * that was read.
*/
static ssize_t
gnu_sparse_10_read(struct archive_read *a, struct tar *tar)
{
- ssize_t bytes_read = 0;
+ ssize_t remaining, bytes_read;
int entries;
off_t offset, size, to_skip;
+ /* Clear out the existing sparse list. */
+ gnu_clear_sparse_list(tar);
+
+ remaining = tar->entry_bytes_remaining;
+
/* Parse entries. */
- entries = gnu_sparse_10_atol(a, tar, &bytes_read);
+ entries = gnu_sparse_10_atol(a, tar, &remaining);
if (entries < 0)
return (ARCHIVE_FATAL);
/* Parse the individual entries. */
while (entries-- > 0) {
/* Parse offset/size */
- offset = gnu_sparse_10_atol(a, tar, &bytes_read);
+ offset = gnu_sparse_10_atol(a, tar, &remaining);
if (offset < 0)
return (ARCHIVE_FATAL);
- size = gnu_sparse_10_atol(a, tar, &bytes_read);
+ size = gnu_sparse_10_atol(a, tar, &remaining);
if (size < 0)
return (ARCHIVE_FATAL);
/* Add a new sparse entry. */
gnu_add_sparse_entry(tar, offset, size);
}
/* Skip rest of block... */
+ bytes_read = tar->entry_bytes_remaining - remaining;
to_skip = 0x1ff & -bytes_read;
if (to_skip != (a->decompressor->skip)(a, to_skip))
return (ARCHIVE_FATAL);
@@ -2004,7 +2007,8 @@ tar_atol256(const char *_p, unsigned char_cnt)
* when possible.
*/
static ssize_t
-readline(struct archive_read *a, struct tar *tar, const char **start)
+readline(struct archive_read *a, struct tar *tar, const char **start,
+ ssize_t limit)
{
ssize_t bytes_read;
ssize_t total_size = 0;
@@ -2020,12 +2024,24 @@ readline(struct archive_read *a, struct tar *tar, const char **start)
/* If we found '\n' in the read buffer, return pointer to that. */
if (p != NULL) {
bytes_read = 1 + ((const char *)p) - s;
+ if (bytes_read > limit) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Line too long");
+ return (ARCHIVE_FATAL);
+ }
(a->decompressor->consume)(a, bytes_read);
*start = s;
return (bytes_read);
}
/* Otherwise, we need to accumulate in a line buffer. */
for (;;) {
+ if (total_size + bytes_read > limit) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Line too long");
+ return (ARCHIVE_FATAL);
+ }
if (archive_string_ensure(&tar->line, total_size + bytes_read) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate working buffer");
diff --git a/lib/libarchive/test/test_read_format_gtar_sparse.c b/lib/libarchive/test/test_read_format_gtar_sparse.c
index 1f6be50..66824d0 100644
--- a/lib/libarchive/test/test_read_format_gtar_sparse.c
+++ b/lib/libarchive/test/test_read_format_gtar_sparse.c
@@ -25,105 +25,464 @@
#include "test.h"
__FBSDID("$FreeBSD$");
+
+struct contents {
+ off_t o;
+ size_t s;
+ char *d;
+};
+
+struct contents archive_contents_sparse[] = {
+ { 1000000, 1, "a" },
+ { 2000000, 1, "a" },
+ { 3145728, 0, NULL }
+};
+
+struct contents archive_contents_sparse2[] = {
+ { 1000000, 1, "a" },
+ { 2000000, 1, "a" },
+ { 3000000, 1, "a" },
+ { 4000000, 1, "a" },
+ { 5000000, 1, "a" },
+ { 6000000, 1, "a" },
+ { 7000000, 1, "a" },
+ { 8000000, 1, "a" },
+ { 9000000, 1, "a" },
+ { 10000000, 1, "a" },
+ { 11000000, 1, "a" },
+ { 12000000, 1, "a" },
+ { 13000000, 1, "a" },
+ { 14000000, 1, "a" },
+ { 15000000, 1, "a" },
+ { 16000000, 1, "a" },
+ { 17000000, 1, "a" },
+ { 18000000, 1, "a" },
+ { 19000000, 1, "a" },
+ { 20000000, 1, "a" },
+ { 21000000, 1, "a" },
+ { 22000000, 1, "a" },
+ { 23000000, 1, "a" },
+ { 24000000, 1, "a" },
+ { 25000000, 1, "a" },
+ { 26000000, 1, "a" },
+ { 27000000, 1, "a" },
+ { 28000000, 1, "a" },
+ { 29000000, 1, "a" },
+ { 30000000, 1, "a" },
+ { 31000000, 1, "a" },
+ { 32000000, 1, "a" },
+ { 33000000, 1, "a" },
+ { 34000000, 1, "a" },
+ { 35000000, 1, "a" },
+ { 36000000, 1, "a" },
+ { 37000000, 1, "a" },
+ { 38000000, 1, "a" },
+ { 39000000, 1, "a" },
+ { 40000000, 1, "a" },
+ { 41000000, 1, "a" },
+ { 42000000, 1, "a" },
+ { 43000000, 1, "a" },
+ { 44000000, 1, "a" },
+ { 45000000, 1, "a" },
+ { 46000000, 1, "a" },
+ { 47000000, 1, "a" },
+ { 48000000, 1, "a" },
+ { 49000000, 1, "a" },
+ { 50000000, 1, "a" },
+ { 51000000, 1, "a" },
+ { 52000000, 1, "a" },
+ { 53000000, 1, "a" },
+ { 54000000, 1, "a" },
+ { 55000000, 1, "a" },
+ { 56000000, 1, "a" },
+ { 57000000, 1, "a" },
+ { 58000000, 1, "a" },
+ { 59000000, 1, "a" },
+ { 60000000, 1, "a" },
+ { 61000000, 1, "a" },
+ { 62000000, 1, "a" },
+ { 63000000, 1, "a" },
+ { 64000000, 1, "a" },
+ { 65000000, 1, "a" },
+ { 66000000, 1, "a" },
+ { 67000000, 1, "a" },
+ { 68000000, 1, "a" },
+ { 69000000, 1, "a" },
+ { 70000000, 1, "a" },
+ { 71000000, 1, "a" },
+ { 72000000, 1, "a" },
+ { 73000000, 1, "a" },
+ { 74000000, 1, "a" },
+ { 75000000, 1, "a" },
+ { 76000000, 1, "a" },
+ { 77000000, 1, "a" },
+ { 78000000, 1, "a" },
+ { 79000000, 1, "a" },
+ { 80000000, 1, "a" },
+ { 81000000, 1, "a" },
+ { 82000000, 1, "a" },
+ { 83000000, 1, "a" },
+ { 84000000, 1, "a" },
+ { 85000000, 1, "a" },
+ { 86000000, 1, "a" },
+ { 87000000, 1, "a" },
+ { 88000000, 1, "a" },
+ { 89000000, 1, "a" },
+ { 90000000, 1, "a" },
+ { 91000000, 1, "a" },
+ { 92000000, 1, "a" },
+ { 93000000, 1, "a" },
+ { 94000000, 1, "a" },
+ { 95000000, 1, "a" },
+ { 96000000, 1, "a" },
+ { 97000000, 1, "a" },
+ { 98000000, 1, "a" },
+ { 99000000, 1, "a" },
+ { 99000001, 0, NULL }
+};
+
+struct contents archive_contents_nonsparse[] = {
+ { 0, 1, "a" },
+ { 1, 0, NULL }
+};
+
/*
- * Each of the following is an archive containing the following
- * entries:
+ * Describe an archive with three entries:
*
* File 1: named "sparse"
* * a length of 3145728 bytes (3MiB)
* * a single 'a' byte at offset 1000000
* * a single 'a' byte at offset 2000000
- * File 2: named 'non-sparse'
+ * File 2: named "sparse2"
+ * * a single 'a' byte at offset 1,000,000, 2,000,000, ..., 99,000,000
+ * * length of 99,000,001
+ * File 3: named 'non-sparse'
* * length of 1 byte
* * contains a single byte 'a'
*/
-static struct contents {
- off_t o;
- size_t s;
- char *d;
-} archive_contents[] = {
- { 1000000, 1, "a" },
- { 2000000, 1, "a" },
- { 3145728, 0, NULL }
+struct archive_contents {
+ const char *filename;
+ struct contents *contents;
+} files[] = {
+ { "sparse", archive_contents_sparse },
+ { "sparse2", archive_contents_sparse2 },
+ { "non-sparse", archive_contents_nonsparse },
+ { NULL, NULL }
};
-/* Old GNU tar sparse format. */
-static unsigned char archive_old[] = {
-31,139,8,0,215,'[',190,'F',0,3,237,213,223,10,130,'0',20,199,241,'=',202,
-'^',' ',216,'q',211,'=','H','O',224,'E',23,']','d',225,236,253,243,'d','i',
-'P','(',132,'C',162,239,7,'d',219,241,'/',7,253,153,'.','u',155,14,'&','+',
-215,171,'B',208,'Q','b',233,'^','G','U',244,155,17,'W',149,'1',148,193,'i',
-']','b',244,222,216,'}',222,199,26,'\\','S','W',183,214,154,238,'x',154,'=',
-'n','i',255,215,180,5,190,10,162,']','x','t','d',156,247,']','*','>',212,
-'%',12,235,'g',253,'>',159,187,193,'x',194,234,234,245,'/',137,'?',194,251,
-179,173,230,220,236,'R',230,127,192,'B',254,235,'r',202,255,168,249,'/',133,
-23,'c','3',196,213,187,205,243,127,'[','|',127,0,0,0,0,0,0,0,0,0,0,0,252,
-190,27,'H',10,',',253,0,'(',0,0};
+
+/* Old GNU tar sparse format, as created by gtar 1.13 */
+static unsigned char archive_old_gtar_1_13[] = {
+31,139,8,0,30,'%',193,'F',0,3,237,215,'K','n',219,'H',20,133,'a',246,'N',
+180,129,6,170,'n',189,22,210,'+',208,' ',131,12,146,14,',','g',255,'}',201,
+192,142,17,29,'(','A',159,24,'l',160,255,207,3,219,'e',193,186,'$',127,241,
+'q',251,'r','}',186,'}',216,222,'U',169,165,204,222,183,'R','J',']',163,188,
+253,190,139,252,'u',171,'e',206,18,17,189,205,'m','_',')',177,']',254,'z',
+223,177,190,249,'z','{',190,'>',']','.',219,243,199,'O',15,'_',247,179,191,
+255,'k',251,'.','h',179,231,'>','z',221,'#',175,'?',231,'^',10,177,'^',219,
+':',188,172,239,'K',15,223,160,246,'o',175,250,253,211,'_',127,255,191,196,
+255,8,253,0,231,185,29,215,255,'x',215,247,'x','x',253,175,'=',218,221,245,
+'?','j',31,'\\',255,31,'\\',255,'[','o','j','}','E',233,'?',174,255,'Q',202,
+'X','u',212,213,212,'M',194,'~',167,213,'J',31,226,191,197,'\\','e',138,245,
+22,163,'/',181,158,27,161,182,162,'G',12,181,21,'}',214,170,182,'"','G',29,
+'w','[',177,175,143,'Y',213,156,'3','c','Q','s',206,209,170,154,'s',213,':',
+139,'Z',207,157,'-',230,220,227,157,'b',206,154,'{','-',196,156,185,15,218,
+20,'s',214,',','=',196,156,'5',223,'s',138,'9','k',180,213,196,156,'5','V',
+30,'O',177,190,'G',161,230,'l','+',214,'}',21,175,199,191,246,'V',155,154,
+183,207,181,212,188,'#','f','S',243,142,'c',171,239,215,'g','4','U','w',157,
+'3','T',221,'G',196,'j',191,230,'f',23,'1','g',228,';','w','1','g',148,172,
+'H',204,25,181,198,16,'s','F','~','F','T',191,217,196,'R',253,230,185,'j',
+170,'~',143,143,147,154,'3',15,'O','U','s',246,220,0,'5','g',238,132,'P',
+'s',246,'5',167,154,'s',180,161,250,141,177,218,'}',191,223,143,127,30,205,
+'P',29,31,31,127,'5',239,218,191,212,250,'<','6',227,199,245,150,19,'7','1',
+'o','+','3',255,145,'X',175,'Q','U',199,'-',247,210,'}',199,251,233,168,'N',
+213,239,'q',154,18,'s',182,204,189,171,'9','s',247,21,'5','g',198,219,213,
+156,'=',207,130,'j',206,145,225,169,'9',247,'U','5','g','^',247,'T',191,'/',
+167,211,251,245,181,134,154,'3',15,'s','U','s',230,'^',27,15,142,127,223,
+247,136,152,'7','?','<','U','u',220,'3','z',213,'q',207,15,180,234,248,'8',
+253,139,'y','{',134,'7',197,188,'=','s',12,177,'_',243,206,' ',239,'"',196,
+'z',207,'3',134,154,'3','?',133,170,223,'>',242,'D',172,230,28,'#','T',191,
+199,'e','J',205,'9','3','/','5','g','~','l',154,154,'s','e','0','b',206,177,
+167,'\'',230,28,185,'G','U',191,251,177,'W',253,142,'<',209,171,'~',143,203,
+233,131,227,'?',242,196,'t',127,215,176,175,175,'P',247,5,'#','s','Q',247,
+5,'#',195,'T',247,5,'#',15,180,234,'8','O',218,']','u',156,135,161,169,142,
+143,203,191,154,'s',238,'W',0,181,190,127,137,245,227,'f',232,205,'z',145,
+'7','F',248,'%','<',191,195,'A','?','p',208,15,28,244,3,7,253,192,'A','?',
+'p',184,253,208,31,28,244,3,7,253,192,'A','?','p',208,15,28,244,3,7,253,192,
+193,243,'?',206,'D','?','p',208,15,28,244,3,7,253,192,'A','?','p',208,15,
+28,'<',255,227,'L',244,3,7,253,192,'A','?','p',208,15,28,244,3,7,253,192,
+193,243,'?',206,'D','?','p',208,15,28,244,3,7,253,192,'A','?','p',208,15,
+28,'<',255,227,'L',244,3,7,253,192,'A','?','p',208,15,28,244,3,7,253,192,
+193,243,'?',206,'D','?','p',208,15,28,244,3,7,253,192,'A','?','p',208,15,
+28,'<',255,227,'L',244,3,7,253,192,'A','?','p',208,15,28,244,3,7,253,192,
+193,243,'?',206,'D','?','p',208,15,28,244,3,7,253,192,'A','?','p',208,15,
+28,'<',255,227,'L',244,3,7,253,192,'A','?','p',208,15,28,244,3,7,253,192,
+193,243,'?',206,'D','?','p',208,15,28,244,3,7,253,192,'A','?','p',208,15,
+28,'<',255,227,'L',244,3,7,253,192,'A','?','p',208,15,28,244,3,7,253,192,
+193,243,'?',206,'D','?','p',208,15,28,244,227,249,252,247,231,'?','o','_',
+174,'O',183,15,239,247,30,165,150,'2','{',223,'J',')','u',141,242,246,251,
+139,173,150,'9','K','D',244,'6',243,245,'5',127,218,'.',229,253,'F',250,238,
+235,237,249,250,'t',185,'l',207,31,'?','=','|',221,207,254,14,0,0,0,0,0,0,
+0,255,'1',255,0,178,'s',140,'2',0,240,0,0};
+
+/* Old GNU tar sparse format, as created by gtar 1.17 */
+static unsigned char archive_old_gtar_1_17[] = {
+31,139,8,0,30,'%',193,'F',0,3,237,215,']','r',19,'G',20,134,'a','e','\'',
+218,'@',170,186,'O',255,'-','$','+',208,5,23,'\\','@','(',203,236,'?','g',
+134,216,'8',232,139,160,248,'P','M',170,242,'>',20,'%',211,'6',214,153,158,
+'W','#',205,245,211,229,233,250,238,244,'P','%',205,222,183,199,186,'F','y',
+251,184,137,252,'{',170,'e',206,18,17,189,205,'S','~','w',197,'<',157,255,
+'x',236,'X','_','|',190,'>','_',158,206,231,211,243,251,15,'w',127,238,'{',
+223,255,'i',219,22,180,217,235,182,11,127,239,200,235,215,185,'K','!',214,
+'k',255,242,239,151,245,253,235,'{','O',240,250,31,'~',185,203,175,255,149,
+248,31,161,159,'c',']',247,235,127,'<',244,'9',238,'^',255,'k',143,'V',234,
+'?',175,255,17,'5',127,156,235,255,191,'^',255,'[',235,'M',173,175,'(',253,
+219,245,223,'J',25,171,142,186,182,'m','V',207,158,251,223,135,248,'m','1',
+'W',153,'b',189,197,232,'K',173,231,'A',168,163,232,17,'C',29,'E',159,181,
+170,163,200,'Q',199,205,'Q','l',235,'c','V','5',231,172,'}',168,'9',231,'h',
+'U',205,185,'j',157,'E',173,231,'f',139,'9',243,'a','N','1','g',205,']',11,
+'1','g',238,'A',155,'b',206,154,165,135,152,179,230,'s','N','1','g',141,182,
+154,152,179,198,202,243,')',214,183,'(',212,156,'m',197,186,173,226,245,252,
+215,222,'j','S',243,246,185,150,154,'w',196,'l','j',222,177,31,245,237,250,
+140,166,234,174,'s',134,170,'{',143,'X',237,'k',30,'v',17,'s','F','>','s',
+23,'s','F',201,138,196,156,'Q','k',12,'1','g',228,'k','D',245,155,'M',',',
+213,'o','^',171,166,234,'w',127,'9',169,'9',243,244,'T','5','g',207,3,'P',
+'s',230,'&',132,154,179,175,'9',213,156,163,13,213,'o',140,213,'n',251,253,
+'z',254,243,'l',134,234,'x',127,249,171,'y',215,246,'G',173,207,253,'0',190,
+']','o','9','q',19,243,182,'2',243,23,137,245,26,'U','u',220,'r',151,'n',
+';',222,'.','G','u',170,'~',247,203,148,152,179,'e',238,']',205,153,219,'W',
+212,156,25,'o','W','s',246,188,10,170,'9','G',134,167,230,220,'V',213,156,
+249,190,167,250,'}',185,156,222,174,175,'5',212,156,'y',154,171,154,'3','w',
+'m',220,'9',255,'}',219,17,'1','o',190,'x',170,234,184,'g',244,170,227,158,
+'/','h',213,241,'~',249,23,243,246,12,'o',138,'y','{',230,24,'b','_',243,
+147,'A','~',138,16,235,'=',175,24,'j',206,'|',21,170,'~',251,200,11,177,154,
+'s',140,'P',253,238,'o','S','j',206,153,'y',169,'9',243,'e',211,212,156,'+',
+131,17,'s',142,'-','=','1',231,200,29,'U',253,'n',231,'^',245,';',242,'B',
+175,250,221,223,'N',239,156,255,145,23,166,219,'O',13,219,250,10,245,185,
+'`','d','.',234,'s',193,200,'0',213,231,130,145,'\'','Z','u',156,23,237,174,
+':',206,211,208,'T',199,251,219,191,154,'s','n',239,0,'j','}',251,'#',214,
+247,15,'C','o',214,139,252,'`',132,31,194,253,27,28,244,3,7,253,192,'A','?',
+'p',208,15,28,244,3,135,219,15,253,193,'A','?','p',208,15,28,244,3,7,253,
+192,'A','?','p',208,15,28,220,255,227,'H',244,3,7,253,192,'A','?','p',208,
+15,28,244,3,7,253,192,193,253,'?',142,'D','?','p',208,15,28,244,3,7,253,192,
+'A','?','p',208,15,28,220,255,227,'H',244,3,7,253,192,'A','?','p',208,15,
+28,244,3,7,253,192,193,253,'?',142,'D','?','p',208,15,28,244,3,7,253,192,
+'A','?','p',208,15,28,220,255,227,'H',244,3,7,253,192,'A','?','p',208,15,
+28,244,3,7,253,192,193,253,'?',142,'D','?','p',208,15,28,244,3,7,253,192,
+'A','?','p',208,15,28,220,255,227,'H',244,3,7,253,192,'A','?','p',208,15,
+28,244,3,7,253,192,193,253,'?',142,'D','?','p',208,15,28,244,3,7,253,192,
+'A','?','p',208,15,28,220,255,227,'H',244,3,7,253,192,'A','?','p',208,15,
+28,244,3,7,253,192,193,253,'?',142,'D','?','p',208,15,28,244,3,7,253,192,
+'A','?','p',208,15,28,220,255,227,'H',244,3,7,253,192,'A','?',158,143,127,
+'~',252,253,250,233,242,'t','}',247,184,231,'(','i',246,190,'=',214,'5',202,
+219,199,23,167,'Z',230,',',17,209,219,'<',149,'Z','#',234,233,'\\',30,'7',
+210,'W',159,175,207,151,167,243,249,244,252,254,195,221,159,251,222,247,1,
+0,0,0,0,0,0,0,248,15,249,11,162,'$',218,227,0,240,0,0};
#if ARCHIVE_VERSION_STAMP >= 1009000
-/* libarchive < 1.9 doesn't support these. */
-
-/* GNU tar "0.0" posix format, as written by GNU tar 1.15. */
-static unsigned char archive_0_0[] = {
-31,139,8,0,155,'X',190,'F',0,3,237,214,209,'N',131,'0',20,6,'`',174,'y',10,
-'^','@',214,'s',218,'R',184,224,'Z',175,140,'7','>',0,206,'.','Y','t',155,
-'Y','Y','2','}','z','[','u',147,'e','S','4','#','#','l',255,'w',211,164,229,
-'4','%','p',224,'O','G','w',213,250,198,'V',143,'v',233,'R',163,'Y',142,220,
-'K',181,'t','6',234,144,240,'2',165,194,'H','F',139,230,248,'A',9,142,'H',
-'d',218,'(',173,'X',202,'H',144,'T','$',163,'d',221,229,'!','~',178,'r','u',
-181,244,'G','9','v',159,175,'{',217,142,3,193,'&',185,190,189,'O','?',31,
-'z',234,166,'o',182,148,164,180,225,'<',230,172,185,'4','_',205,30,158,23,
-227,'\'','W',202,152,243,230,202,'b','2','q',182,'.',11,'O','f',241,238,134,
-161,234,181,182,174,212,196,'1',23,7,202,200,151,229,134,255,']',183,'=',
-165,'>','X','\'','b',22,'I','U','O','g',182,'$',202,179,220,20,25,153,'0',
-'7','n',206,'i',191,'A',223,'O',160,'_',221,'w',251,190,150,254,231,208,'.',
-155,254,23,'a',158,200,'(',17,'%','\'','i',162,'M',255,251,215,226,215,235,
-218,214,7,218,255,199,170,250,'>',0,12,26,222,159,'~',165,'{',249,'o',190,
-152,'_','u',251,'W','h',203,127,225,155,191,155,255,20,251,'H',136,252,'w',
-2,127,'J','I','J',']','x','J',':','_',221,'w',251,190,214,254,23,244,157,
-255,'L',200,127,172,'%','!',255,157,2,254,191,0,0,0,0,0,0,0,0,0,0,0,231,231,
-29,157,135,'u','Z',0,'(',0,0};
-
-
-/* GNU tar "0.1" posix format, as written by GNU tar 1.15.1 (?) */
-static unsigned char archive_0_1[] = {
-31,139,8,0,6,'Y',190,'F',0,3,237,214,223,'n',130,'0',20,6,'p',174,'y',10,
-30,128,'a',207,161,127,240,130,219,'m','W',203,146,'e',15,208,'9','.',140,
-138,6,'4','1','{',250,21,212,141,205,'l',',',145,'A','0',223,239,166,'M',
-'K',176,210,30,248,162,201,163,221,223,'g',246,'5','+',202,200,'(','N','&',
-229,198,22,'e',230,'u','H','8','Z',202,170,'%',163,'D',179,173,177,'b',143,
-132,'V','F','*',')',133,246,4,197,146,149,23,236,187,'\\',196,'O','v',229,
-214,22,'n',')',151,222,231,248,'_','>',218,145,'`',19,220,'=','<','G',135,
-'M',143,202,249,'[',150,198,'$',149,225,196,'g',221,156,202,'w',171,151,229,
-'z',182,'(',211,248,251,140,']','e',233,161,239,'+','j',206,172,236,'&',157,
-':',177,14,21,'q','H',174,155,24,174,251,199,31,9,133,207,'"',176,219,185,
-187,5,'Q',162,19,'3',213,'2',174,198,'f',205,'1','w','.',253,161,159,212,
-'u',138,'&','n',191,158,234,237,186,157,'/',179,127,'y',5,180,212,'?','W',
-229,'r',170,127,'Q',141,147,'"',18,'^',208,'K',17,157,234,223,29,183,'_',
-175,'k',155,31,'i',253,'_',202,14,189,0,24,'5',156,159,'a','E','g',249,'/',
-'_',231,'7',221,'~',0,218,242,'_',245,206,255,154,255,'$',19,'!',255,245,
-225,'O',233,'K','J',164,175,'+',213,'}',181,159,'k',173,127,'A',159,249,207,
-'T',249,143,'U','L',200,127,'}',192,247,23,0,0,0,0,0,0,0,0,0,0,224,250,188,
-3,249,9,184,142,0,'(',0,0};
-
-
-/* GNU tar "1.0" posix format, as written by GNU tar 1.17. */
-/*
- * Note: This is not the same as the GNU tar "1.0" format
- * written by GNU tar 1.16. The two formats are incompatible.
- *
- * Libarchive follows GNU tar 1.17 here, making it incompatible
- * with GNU tar 1.16.
- */
+/* libarchive < 1.9 does not support this. */
+/* GNU tar "posix" sparse format 0.0, as created by gtar 1.17 */
+static unsigned char archive_0_0_gtar_1_17[] = {
+31,139,8,0,31,'%',193,'F',0,3,237,217,207,'n',218,'X',20,199,'q',214,'<',
+5,'/','0',228,222,'s','}',255,'x',193,'z',186,26,'u',211,7,240,164,174,20,
+205,'$',169,'0',145,'2',243,244,'5','%',205,144,200,193,'p',14,141,203,232,
+251,217,'P','A',14,'8','9',191,'[',253,',',150,'W',31,155,199,15,'m',243,
+185,']','w',203,232,156,148,171,238,'k',179,238,218,217,249,184,'^',170,170,
+237,163,207,209,237,'?','~','W','9',153,'y',151,146,19,145,'*',228,153,243,
+161,'J','2','[','<',158,241,26,222,244,208,'m',154,'u',127,')',214,247,'y',
+250,']',158,31,'/',132,228,197,239,127,'|','Z',238,'v',190,236,'n',254,'m',
+'W',193,'W','1','K',153,'K',218,127,233,238,225,246,207,191,239,175,255,234,
+'V','a','.','e',255,149,251,'/','_',186,'v',179,170,'{','!',205,'_',190,225,
+'v',234,159,'M',219,173,162,151,185,212,3,'c',190,31,'+','Y','N',158,'{',
+190,202,'8','8',231,230,226,22,205,230,230,182,']','y','_',178,'K',193,'e',
+191,'}',238,250,229,'s','n','>',245,6,166,'u',246,195,'>','`',228,252,203,
+246,184,252,'w',254,'S',127,254,'}',14,'a',182,'x',151,'C',244,227,252,247,
+177,'8',248,'s','c',175,'_',232,249,183,'j',166,190,0,'\\','4',242,'3',173,
+229,'[',253,'O',206,247,25,135,255,255,247,193,247,157,239,'U',255,139,'1',
+210,255,222,195,203,'*',247,189,255,213,245,'n','/',3,149,'l','W',0,235,250,
+151,'h',128,178,157,'s',229,244,230,216,207,229,170,':','y',174,234,231,'R',
+'q','\'',207,197,237,156,'?',253,239,146,250,185,24,'O',255,187,148,']',2,
+'O',159,'S',238,175,30,223,'_','p','C','{','w',227,11,28,30,244,227,27,28,
+30,148,241,21,14,15,134,241,29,14,15,'V',227,'K',28,30,'L',227,'[','|','c',
+'p','|',141,195,131,'Y',187,199,162,221,'c',173,220,163,'8',229,30,197,'+',
+247,'(',162,220,163,'T',202,'=','J',165,220,163,'D',229,30,'%',')',247,'(',
+'Y',187,199,162,221,'c',173,220,'c','p',202,'=',6,'Q',238,'1',136,'r',143,
+'!','(',247,24,'*',229,30,'C','T',238,'1','$',229,30,'C',214,238,177,'(',
+247,248,'t',28,'O',191,212,202,')',247,'X',29,209,'o',134,7,143,'(','8',195,
+131,'G','4',156,225,193,'#','*',206,240,224,17,29,'g','x',240,136,146,'3',
+'<','x','D',203,'y','c','P',187,'G','m',207,137,218,158,19,181,'=','\'','j',
+'{','N',212,246,156,168,237,'9','Q',219,'s',162,182,231,'D','m',207,137,218,
+158,19,181,'=','\'','i','{','N',210,246,156,164,237,'9','I',219,'s',146,182,
+231,'$','m',207,'I',218,158,147,180,'=','\'','i','{','N',210,246,156,172,
+237,'9','Y',219,'s',178,182,231,'d','m',207,201,218,158,147,181,'=','\'',
+'k','{','N',214,246,156,172,237,'9','E',219,'s',138,182,231,20,'m',207,')',
+218,158,'S',180,'=',167,'h','{','N',209,246,156,162,237,'9','E',219,'s',138,
+182,231,20,'m',207,169,181,'=',167,214,246,156,'Z',219,'s','j','m',207,169,
+181,'=',167,214,246,156,'Z',219,'s','j','m',207,169,'G','z',142,175,3,'_',
+174,255,'_',236,150,'{',198,'/','{',6,28,252,254,199,'W',18,156,127,245,253,
+191,'8','I','|',255,127,9,248,254,22,22,228,7,22,228,7,22,228,7,22,228,7,
+22,228,7,22,214,252,144,'?','X',144,31,'X',144,31,'X',144,31,'X',144,31,'X',
+144,31,'X',144,31,'X','p',255,143,')',145,31,'X',144,31,'X',144,31,'X',144,
+31,'X',144,31,'X',144,31,'X','p',255,143,')',145,31,'X',144,31,'X',144,31,
+'X',144,31,'X',144,31,'X',144,31,'X','p',255,143,')',145,31,'X',144,31,'X',
+144,31,'X',144,31,'X',144,31,'X',144,31,'X','p',255,143,')',145,31,'X',144,
+31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X','p',255,143,')',145,31,
+'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X','p',255,143,')',
+145,31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X','p',255,
+143,')',145,31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X',
+'p',255,143,')',145,31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,'X',144,
+31,'X','p',255,143,')',145,31,'X',144,31,'X',144,31,'X',144,31,'X',144,31,
+'X',144,31,'X','p',255,143,')',145,31,'X',144,31,'X',144,31,'X',144,31,'X',
+144,31,'X',144,31,'X','p',255,143,')',145,31,'X',144,31,'X',144,31,155,229,
+213,199,230,241,'C',219,'|','n',215,221,'2',':','\'',229,234,238,254,238,
+183,238,'k',179,238,218,'3','}',134,235,165,170,218,'>',250,28,221,254,227,
+'N',255,'o',239,'R','r','"','R',133,'<','s',190,146,232,'g',139,199,'3','}',
+254,'A',15,221,166,'Y',247,151,'b','}',159,167,'_',229,249,241,'B',136,'[',
+'4',155,155,219,'v',229,'}',201,'.',5,151,221,188,127,238,250,245,'s','S',
+'_','\'','~',142,179,31,246,1,163,231,223,237,159,255,212,159,127,137,210,
+159,255,'w','9','D','?',206,127,31,248,131,'?','7',246,250,133,158,127,0,
+0,0,0,0,0,0,0,0,0,0,0,0,192,'e',250,6,'X',180,13,'8',0,24,1,0};
+#endif
+
+#if ARCHIVE_VERSION_STAMP >= 1009000
+/* libarchive < 1.9 does not support this. */
+/* GNU tar "posix" sparse format 0.1, as created by gtar 1.17 */
+static unsigned char archive_0_1_gtar_1_17[] = {
+31,139,8,0,31,'%',193,'F',0,3,237,215,205,'n',26,'W',24,135,'q',214,'\\',
+5,23,224,194,249,'>','3',11,182,'m','V','U',164,170,23,'0','u','f','a','%',
+'v',',',198,150,172,'^','}',135,15,'\'',127,187,9,'T','z',137,167,'D',207,
+'o',195,4,'l','^','0',207,'!',231,',','W',239,187,167,'w','}',247,161,223,
+12,203,236,'\\',244,171,225,190,219,12,253,236,'|',220,168,164,180,189,245,
+'5',';',189,221,9,'9',204,188,'+',197,133,16,'R',172,'3',231,'c',202,'u',
+182,'x',':',227,'k',248,174,199,225,161,219,140,'/',197,250,'<',135,247,242,
+229,246,'B',132,186,248,237,247,'?',151,251,207,'|','9',220,252,221,175,163,
+31,255,250,161,153,135,162,15,221,'=',222,254,245,233,243,245,199,'a',29,
+'_','?',210,221,246,235,253,245,'<','{','}',228,182,187,'_',183,163,'X',174,
+178,15,'W','~',188,'l','j',216,']',31,134,'\\',185,'y','p',139,238,225,'f',
+'|',10,239,155,234,'J','t',213,'o',239,187,'~','y',159,155,'O',253,151,250,
+'9','-','W',227,231,245,199,238,227,250,245,230,'S',255,'C',190,2,'N',172,
+255,176,']','.','_',215,127,25,215,127,246,169,204,22,'o',178,136,158,215,
+255,152,219,209,159,';',245,248,133,174,127,171,'n',234,23,128,139,'F','?',
+211,'Z','~','o',255,23,206,'7',227,212,247,127,241,178,255,'K','n',187,255,
+203,'1',179,255,'{',11,161,249,215,254,175,'m','w',239,'`',220,133,213,'o',
+'o',0,219,246,245,'C','_','w',128,'a',238,'C','[',254,227,'&','0','l',175,
+']',179,223,16,142,215,'5',165,221,'u',26,175,'K',227,'v',215,'y','{',237,
+247,191,'[',198,235,156,247,191,219,236,255,206,251,'k','y',254,'V',158,223,
+';',25,224,189,'L',240,'A','F',248,'(','3','|',146,'!',190,200,20,'_',244,
+'m','T',157,211,232,156,'V',230,4,'\'','s',130,151,'9','!',200,156,144,'d',
+'N','H','2','\'','d',253,'{',21,153,19,170,206,'i','t','N','+','s',162,147,
+'9','1',200,156,24,'d','N',140,186,'9','O',250,193,'d',153,19,139,204,137,
+'U',231,'4','2',231,240,'v',220,225,31,'2','\'',233,231,159,'4',128,244,162,
+0,'M',' ','i',3,'I','#','H','Z','A',210,12,146,'v',144,181,131,172,29,'d',
+237,' ','k',7,'Y',';',200,218,'A',214,14,178,'v',144,181,131,172,29,20,237,
+160,'h',7,'E',';','(',218,'A',209,14,138,'v','P',180,131,162,29,20,237,160,
+'h',7,'U',';',168,218,'A',213,14,170,'v','P',181,131,170,29,'T',237,160,'j',
+7,'U',';','h',180,131,'F',';','h',180,131,'F',';','h',180,131,'F',';','h',
+180,131,230,197,151,193,139,'o',3,237,160,209,14,'Z',237,160,213,14,'Z',237,
+160,213,14,'Z',237,160,213,14,'Z',237,160,213,14,218,231,14,'|',27,255,231,
+231,219,'c',231,191,'s','m',1,142,254,255,239,'S',136,206,191,'>',255,133,
+228,'9',255,']',2,246,239,176,160,31,'X',208,15,',',232,7,22,244,3,11,250,
+129,133,181,31,250,131,5,253,192,130,'~','`','A','?',176,160,31,'X',208,15,
+',',232,7,22,156,255,'1','%',250,129,5,253,192,130,'~','`','A','?',176,160,
+31,'X',208,15,',','8',255,'c','J',244,3,11,250,129,5,253,192,130,'~','`',
+'A','?',176,160,31,'X','p',254,199,148,232,7,22,244,3,11,250,129,5,253,192,
+130,'~','`','A','?',176,224,252,143,')',209,15,',',232,7,22,244,3,11,250,
+129,5,253,192,130,'~','`',193,249,31,'S',162,31,'X',208,15,',',232,7,22,244,
+3,11,250,129,5,253,192,130,243,'?',166,'D','?',176,160,31,'X',208,15,',',
+232,7,22,244,3,11,250,129,5,231,127,'L',137,'~','`','A','?',176,160,31,'X',
+208,15,',',232,7,22,244,3,11,206,255,152,18,253,192,130,'~','`','A','?',176,
+160,31,'X',208,15,',',232,7,22,156,255,'1','%',250,129,5,253,192,130,'~',
+'`','A','?',176,160,31,'X',208,15,',','8',255,'c','J',244,3,11,250,129,5,
+253,192,130,'~','`','A','?',176,160,31,'X','p',254,199,148,232,7,22,244,3,
+11,250,177,'Y',174,222,'w','O',239,250,238,'C',191,25,150,217,185,232,'W',
+'w',159,239,'~',25,238,187,205,208,159,'i',134,27,149,148,182,183,190,'f',
+167,183,'{',227,181,'w',165,184,16,'B','J',227,253,'>',133,152,'g',139,167,
+'3',205,'?',234,'q','x',232,'6',227,'K',177,'>',207,225,173,'|',185,189,16,
+193,'-',186,135,155,219,'~',237,'}','S',']',137,174,186,249,'x',223,245,235,
+251,166,'~',157,248,'1',206,190,216,191,225,228,250,'w',178,254,'c',25,215,
+127,200,193,207,22,'o',178,136,158,215,255,24,252,209,159,';',245,248,133,
+174,127,0,0,0,0,0,240,243,251,7,233,'Q','N','O',0,240,0,0};
+#endif
+
+#if ARCHIVE_VERSION_STAMP >= 1009000
+/* libarchive < 1.9 does not support this. */
+/* GNU tar "posix" sparse format 1.0, as created by gtar 1.17 */
+static unsigned char archive_1_0_gtar_1_17[] = {
+31,139,8,0,' ','%',193,'F',0,3,237,215,205,'n',26,'I',20,134,'a',214,'\\',
+5,'7',16,168,255,234,'^','x',155,'d',21,'E',138,230,2,'Z','I','/',24,197,
+'N',4,142,'d',205,213,'O',1,182,245,217,178,'A',163,'C',220,131,242,'>',155,
+'n',183,'m',14,'?','o',161,174,229,234,243,'p',247,'q',28,190,141,155,237,
+'2',';',23,211,'j',251,'s',216,'l',199,217,249,184,166,164,180,';',250,154,
+157,30,247,130,207,'3',239,'J','q','!',132,148,218,'u',31,'S',142,179,197,
+221,25,159,195,171,'~','m','o',135,'M','{','*',214,199,185,127,'-',143,199,
+11,17,194,226,195,167,191,150,135,207,'|','y','=',252,253,'c','s',229,231,
+207,174,174,'o',218,'U','7',15,'E',175,222,12,215,227,213,225,'|',30,189,
+254,'f','3',14,223,183,235,127,198,171,232,'S',174,161,155,7,183,24,'n',215,
+237,207,189,239,170,'+',209,'U',191,187,246,245,233,'5','7',159,250,205,248,
+3,'-','W',237,131,251,178,255,220,222,175,191,143,191,229,'+',224,196,250,
+143,187,229,242,184,254,'c','i',235,'?',251,28,'f',139,'7','Y','D',15,235,
+191,181,'x',244,239,'N',253,254,'B',215,127,156,247,'M',',',243,236,195,220,
+183,211,174,134,253,249,195,218,'e','U',226,136,'a',234,'\'',128,139,'F',
+'?',211,'Z',190,'v',255,31,206,'7',227,244,253,127,'}','~',255,159,'c',229,
+254,255,'-',252,167,251,255,250,202,253,127,187,'[',8,'/','n',0,250,'~',255,
+'f',248,23,'v',0,129,29,192,255,193,177,251,255,'s','}',5,28,']',255,237,
+'6','3',':',255,252,254,'?',164,202,253,255,'[',232,251,215,'6',0,'a','w',
+238,186,195,'f',160,157,215,148,246,231,169,157,151,206,237,207,243,238,220,
+31,254,183,180,243,156,15,255,219,29,222,132,195,185,'<','~','/',143,239,
+157,12,240,'^','&',248,' ','#','|',148,25,'>',201,16,'_','d',138,'/',250,
+'2',170,206,233,'t','N','/','s',130,147,'9',193,203,156,16,'d','N','H','2',
+'\'','$',153,19,178,190,'_','E',230,132,170,'s',':',157,211,203,156,232,'d',
+'N',12,'2','\'',6,153,19,163,'n',204,146,'~','0','Y',230,196,'"','s','b',
+213,'9',157,204,185,127,'9',238,254,7,153,147,244,243,'O',26,'@','z','R',
+128,'&',144,180,129,164,17,'$',173,' ','i',6,'I',';',200,218,'A',214,14,178,
+'v',144,181,131,172,29,'d',237,' ','k',7,'Y',';',200,218,'A',214,14,138,'v',
+'P',180,131,162,29,20,237,160,'h',7,'E',';','(',218,'A',209,14,138,'v','P',
+180,131,170,29,'T',237,160,'j',7,'U',';',168,218,'A',213,14,170,'v','P',181,
+131,170,29,'t',218,'A',167,29,'t',218,'A',167,29,'t',218,'A',167,29,'t',218,
+'A',247,228,203,224,201,183,129,'v',208,'i',7,189,'v',208,'k',7,189,'v',208,
+'k',7,189,'v',208,'k',7,189,'v',208,'k',7,253,'C',7,190,143,220,'o','X',177,
+127,131,5,253,192,130,'~','`','A','?',176,160,31,'X',208,15,',',172,253,208,
+31,',',232,7,22,244,3,11,250,129,5,253,192,130,'~','`','A','?',176,'`',255,
+143,')',209,15,',',232,7,22,244,3,11,250,129,5,253,192,130,'~','`',193,254,
+31,'S',162,31,'X',208,15,',',232,7,22,244,3,11,250,129,5,253,192,130,253,
+'?',166,'D','?',176,160,31,'X',208,15,',',232,7,22,244,3,11,250,129,5,251,
+127,'L',137,'~','`','A','?',176,160,31,'X',208,15,',',232,7,22,244,3,11,246,
+255,152,18,253,192,130,'~','`','A','?',176,160,31,'X',208,15,',',232,7,22,
+236,255,'1','%',250,129,5,253,192,130,'~','`','A','?',176,160,31,'X',208,
+15,',',216,255,'c','J',244,3,11,250,129,5,253,192,130,'~','`','A','?',176,
+160,31,'X',176,255,199,148,232,7,22,244,3,11,250,129,5,253,192,130,'~','`',
+'A','?',176,'`',255,143,')',209,15,',',232,7,22,244,3,11,250,129,5,253,192,
+130,'~','`',193,254,31,'S',162,31,'X',208,15,',',232,7,22,244,3,11,250,129,
+5,253,192,130,253,'?',166,'D','?',176,160,31,'X',208,143,205,'r',245,'y',
+184,251,'8',14,223,198,205,'v',153,157,139,'i','u',243,227,230,221,246,231,
+176,217,142,'g',154,225,154,146,210,238,232,'k','v','z','<','h',231,222,149,
+226,'B',8,')',181,235,'>',133,'v','X',220,157,'i',254,'Q',191,182,183,195,
+166,'=',21,235,227,220,191,148,199,227,133,8,'n','1',220,174,175,199,'+',
+239,187,234,'J','t',213,205,219,181,175,207,175,'M',253,'<',241,'{',156,'}',
+177,191,224,228,250,'w',178,254,'c','i',235,'?',228,224,'g',139,'7','Y','D',
+15,235,191,5,127,244,239,'N',253,254,'B',215,'?',0,0,0,128,'?',199,191,200,
+'e','(',171,0,240,0,0};
+#endif
+
/*
- * This test archive is uncompressed, as that exercises some of the
- * code better than compressed does. (The uncompression layers try to
- * work with large blocks and the parsing code in libarchive has sections that
- * have to work harder if reads return small pieces of data.)
+ * The following test archive is a little odd. First, it's uncompressed,
+ * because that exercises some of the block reassembly code a little harder.
+ * Second, it includes some leading comments prior to the sparse block
+ * description. GNU tar doesn't do this, but I think it should, so I
+ * want to ensure that libarchive correctly ignores such comments.
*/
-static unsigned char archive_1_0[] = {
+#if ARCHIVE_VERSION_STAMP >= 1009000
+
+/* Because it's uncompressed, I've made this archive a bit simpler. */
+struct archive_contents files_1_0b[] = {
+ { "sparse", archive_contents_sparse },
+ { "non-sparse", archive_contents_nonsparse },
+ { NULL, NULL }
+};
+
+static unsigned char archive_1_0b[] = {
'.','/','P','a','x','H','e','a','d','e','r','s','.','7','5','4','7','/','s',
'p','a','r','s','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -174,11 +533,20 @@ static unsigned char archive_1_0[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'3',10,'9','9','9','9','3','6',10,'5','1','2',
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+
+/* 32 added bytes containing extra comments at beginning of sparse block */
+'#','!','g','n','u','-','s','p','a','r','s','e','-','f','o','r','m','a',
+'t',10,'#','f','o','r','m','a','t',':','1','.','0',10,
+
+'3',10,'9','9','9','9','3','6',10,'5','1','2',
10,'1','9','9','9','8','7','2',10,'5','1','2',10,'3','1','4','5','7','2',
'8',10,'0',10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+
+/* 32 removed bytes to preserve alignment. */
+/* 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, */
+0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -420,71 +788,101 @@ static unsigned char archive_1_0[] = {
#endif
+/*
+ * A tricky piece of code that verifies the contents of a sparse
+ * archive entry against a description as defined at the top of this
+ * source file.
+ */
#define min(a,b) ((a) < (b) ? (a) : (b))
+/*
+ * A convenience wrapper that adds the size of the buffer and the
+ * name of the buffer to any call.
+ */
+#define verify_archive(buffer, contents) \
+ _verify_archive(buffer, sizeof(buffer), #buffer, contents)
+
static void
-verify_archive(void *b, size_t l, struct contents *cts, const char *name)
+_verify_archive(void *buffer, size_t length, const char *name,
+ struct archive_contents *ac)
{
struct archive_entry *ae;
struct archive *a;
int err;
/* data, size, offset of next expected block. */
- struct contents e;
+ struct contents expect;
/* data, size, offset of block read from archive. */
- const void *ad;
- size_t as;
- off_t ao;
+ struct contents actual;
assert((a = archive_read_new()) != NULL);
assert(0 == archive_read_support_compression_all(a));
assert(0 == archive_read_support_format_tar(a));
- assert(0 == read_open_memory(a, b, l, 3));
- assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
- assertEqualString("sparse", archive_entry_pathname(ae));
-
- e = *cts++;
- while (0 == (err = archive_read_data_block(a, &ad, &as, &ao))) {
- while (as > 0) {
- /* Anything before the next expected block must be NULL. */
- char c = *(char *)ad;
- if(ao < e.o) {
- assert(c == 0);
- } else if (ao == e.o) {
- assert(c == *e.d);
- e.d++;
- e.o++;
- e.s--;
- /* End of expected? step to next expected. */
- if (e.s <= 0)
- e = *cts++;
- } else {
- failure("Expected data not found");
- assert(ao <= e.o);
- archive_read_finish(a);
- return;
+ assert(0 == read_open_memory(a, buffer, length, 3));
+
+ while (ac->filename != NULL) {
+ struct contents *cts = ac->contents;
+
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ failure("Name mismatch in archive %s", name);
+ assertEqualString(ac->filename, archive_entry_pathname(ae));
+
+ expect = *cts++;
+ while (0 == (err = archive_read_data_block(a,
+ (const void **)&actual.d,
+ &actual.s, &actual.o))) {
+ while (actual.s > 0) {
+ char c = *(char *)actual.d;
+ if(actual.o < expect.o) {
+ /*
+ * Any byte before the expected
+ * data must be NULL.
+ */
+ failure("%s: pad at offset %d "
+ "should be zero", name, actual.o);
+ assertEqualInt(c, 0);
+ } else if (actual.o == expect.o) {
+ /*
+ * Data at matching offsets must match.
+ */
+ assertEqualInt(c, *expect.d);
+ expect.d++;
+ expect.o++;
+ expect.s--;
+ /* End of expected? step to next expected. */
+ if (expect.s <= 0)
+ expect = *cts++;
+ } else {
+ /*
+ * We found data beyond that expected.
+ */
+ failure("%s: Unexpected trailing data",
+ name);
+ assert(actual.o <= expect.o);
+ archive_read_finish(a);
+ return;
+ }
+ actual.d++;
+ actual.o++;
+ actual.s--;
}
- ad++;
- ao++;
- as--;
}
- }
- assertEqualIntA(a, err, ARCHIVE_EOF);
- failure("Size returned at EOF must be zero");
- assertEqualInt(as, 0);
+ failure("%s: should be end of entry", name);
+ assertEqualIntA(a, err, ARCHIVE_EOF);
+ failure("%s: Size returned at EOF must be zero", name);
+ assertEqualInt(actual.s, 0);
#if ARCHIVE_VERSION_STAMP < 1009000
- /* libarchive < 1.9 doesn't get this right */
- skipping("offset of final sparse chunk");
+ /* libarchive < 1.9 doesn't get this right */
+ skipping("offset of final sparse chunk");
#else
- failure("Offset of final empty chunk must be same as file size");
- assertEqualInt(ao, e.o);
+ failure("%s: Offset of final empty chunk must be same as file size", name);
+ assertEqualInt(actual.o, expect.o);
#endif
+ /* Step to next file description. */
+ ++ac;
+ }
err = archive_read_next_header(a, &ae);
- failure("Failed to read the file following the sparse file in %s", name);
- assertEqualIntA(a, ARCHIVE_OK, err);
- if (err == ARCHIVE_OK) {
- assertEqualString("non-sparse", archive_entry_pathname(ae));
- }
+ assertEqualIntA(a, ARCHIVE_EOF, err);
assert(0 == archive_read_close(a));
#if ARCHIVE_API_VERSION > 1
@@ -496,11 +894,13 @@ verify_archive(void *b, size_t l, struct contents *cts, const char *name)
DEFINE_TEST(test_read_format_gtar_sparse)
{
- FILE *t = fopen("archive_1_0.tgz", "w");
- fwrite(archive_1_0, sizeof(archive_1_0), 1, t);
- fclose(t);
+ /*
+ FILE *t = fopen("archive_1_0.tgz", "w");
+ fwrite(archive_1_0, sizeof(archive_1_0), 1, t);
+ fclose(t);
+ */
- verify_archive(archive_old, sizeof(archive_old), archive_contents, "archive_old");
+ verify_archive(archive_old_gtar_1_13, files);
/*
* libarchive < 1.9 doesn't support the newer sparse formats
@@ -509,17 +909,18 @@ DEFINE_TEST(test_read_format_gtar_sparse)
#if ARCHIVE_VERSION_STAMP < 1009000
skipping("read support for GNUtar sparse format 0.0");
#else
- verify_archive(archive_0_0, sizeof(archive_0_0), archive_contents, "archive_0_0");
+ verify_archive(archive_0_0_gtar_1_17, files);
#endif
#if ARCHIVE_VERSION_STAMP < 1009000
skipping("read support for GNUtar sparse format 0.1");
#else
- verify_archive(archive_0_1, sizeof(archive_0_1), archive_contents, "archive_0_1");
+ verify_archive(archive_0_1_gtar_1_17, files);
#endif
#if ARCHIVE_VERSION_STAMP < 1009000
skipping("read support for GNUtar sparse format 1.0");
#else
- verify_archive(archive_1_0, sizeof(archive_1_0), archive_contents, "archive_1_0");
+ verify_archive(archive_1_0_gtar_1_17, files);
+ verify_archive(archive_1_0b, files_1_0b);
#endif
}
OpenPOWER on IntegriCloud