summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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