MFV r317781:
Sync libarchive with vendor Vendor changes (FreeBSD-related): PR 897: add test for ZIP archives with invalid EOCD headers PR 901: fix invalid renaming of sparse files OSS-Fuzz issue 497: remove fallback tree in LZX decoder OSS-Fuzz issue 527: rewrite expressions in lz4 filter OSS-Fuzz issue 577: fix integer overflow in cpio reader OSS-Fuzz issue 862: fix numerc parsing in mtree reader OSS-Fuzz issue 1097: fix undefined shift in rar reader cpio: various optimizations and memory leak fixes MFC after: 1 week
This commit is contained in:
commit
a8fc61d51a
@ -628,6 +628,7 @@ mode_out(struct cpio *cpio)
|
||||
blocks == 1 ? "block" : "blocks");
|
||||
}
|
||||
archive_write_free(cpio->archive);
|
||||
archive_entry_linkresolver_free(cpio->linkresolver);
|
||||
}
|
||||
|
||||
static const char *
|
||||
@ -1194,12 +1195,15 @@ mode_pass(struct cpio *cpio, const char *destdir)
|
||||
struct lafe_line_reader *lr;
|
||||
const char *p;
|
||||
int r;
|
||||
size_t destdir_len;
|
||||
|
||||
/* Ensure target dir has a trailing '/' to simplify path surgery. */
|
||||
cpio->destdir = malloc(strlen(destdir) + 8);
|
||||
strcpy(cpio->destdir, destdir);
|
||||
if (destdir[strlen(destdir) - 1] != '/')
|
||||
strcat(cpio->destdir, "/");
|
||||
destdir_len = strlen(destdir);
|
||||
cpio->destdir = malloc(destdir_len + 8);
|
||||
memcpy(cpio->destdir, destdir, destdir_len);
|
||||
if (destdir_len == 0 || destdir[destdir_len - 1] != '/')
|
||||
cpio->destdir[destdir_len++] = '/';
|
||||
cpio->destdir[destdir_len++] = '\0';
|
||||
|
||||
cpio->archive = archive_write_disk_new();
|
||||
if (cpio->archive == NULL)
|
||||
@ -1240,6 +1244,7 @@ mode_pass(struct cpio *cpio, const char *destdir)
|
||||
}
|
||||
|
||||
archive_write_free(cpio->archive);
|
||||
free(cpio->pass_destpath);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -43,17 +43,18 @@ DEFINE_TEST(test_option_Z_upper)
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without compress support");
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
failure("-Z option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
goto done;
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
/* Check that the archive file has a compress signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x1f\x9d", 2);
|
||||
done:
|
||||
free(p);
|
||||
}
|
||||
|
@ -96,7 +96,8 @@ DEFINE_TEST(test_option_a)
|
||||
test_create();
|
||||
|
||||
/* Sanity check; verify that atimes really do get modified. */
|
||||
assert((p = slurpfile(NULL, "f0")) != NULL);
|
||||
p = slurpfile(NULL, "f0");
|
||||
assert(p != NULL);
|
||||
free(p);
|
||||
assertEqualInt(0, stat("f0", &st));
|
||||
if (st.st_atime == files[0].atime_sec) {
|
||||
|
@ -42,6 +42,7 @@ DEFINE_TEST(test_option_b64encode)
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin-base64 644", 16);
|
||||
free(p);
|
||||
|
||||
/* Archive it with uuencode only. */
|
||||
assertEqualInt(0,
|
||||
@ -51,4 +52,5 @@ DEFINE_TEST(test_option_b64encode)
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin-base64 644", 16);
|
||||
free(p);
|
||||
}
|
||||
|
@ -44,9 +44,10 @@ DEFINE_TEST(test_option_grzip)
|
||||
systemf("echo f | %s -o --grzip >archive.out 2>archive.err",
|
||||
testprog));
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
free(p);
|
||||
/* Check that the archive file has an grzip signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "GRZipII\x00\x02\x04:)", 12);
|
||||
free(p);
|
||||
}
|
||||
|
@ -44,9 +44,10 @@ DEFINE_TEST(test_option_lrzip)
|
||||
systemf("echo f | %s -o --lrzip >archive.out 2>archive.err",
|
||||
testprog));
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
free(p);
|
||||
/* Check that the archive file has an lzma signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "LRZI\x00", 5);
|
||||
free(p);
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ DEFINE_TEST(test_option_lz4)
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without lz4 support");
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
/* POSIX permits different handling of the spawnp
|
||||
@ -52,6 +53,7 @@ DEFINE_TEST(test_option_lz4)
|
||||
if (strstr(p, "Can't launch") != NULL && !canLz4()) {
|
||||
skipping("This version of bsdcpio uses an external lz4 program "
|
||||
"but no such program is available on this system.");
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
/* Some systems successfully spawn the new process,
|
||||
@ -61,6 +63,7 @@ DEFINE_TEST(test_option_lz4)
|
||||
if (strstr(p, "Can't write") != NULL && !canLz4()) {
|
||||
skipping("This version of bsdcpio uses an external lz4 program "
|
||||
"but no such program is available on this system.");
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
/* On some systems the error won't be detected until closing
|
||||
@ -68,14 +71,18 @@ DEFINE_TEST(test_option_lz4)
|
||||
if (strstr(p, "Error closing") != NULL && !canLz4()) {
|
||||
skipping("This version of bsdcpio uses an external lz4 program "
|
||||
"but no such program is available on this system.");
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
failure("--lz4 option is broken: %s", p);
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
/* Check that the archive file has an lz4 signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x04\x22\x4d\x18", 4);
|
||||
free(p);
|
||||
}
|
||||
|
@ -43,14 +43,18 @@ DEFINE_TEST(test_option_lzma)
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without lzma support");
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
failure("--lzma option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
/* Check that the archive file has an lzma signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x5d\00\00", 3);
|
||||
free(p);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ DEFINE_TEST(test_option_lzop)
|
||||
r = systemf("echo f | %s -o --lzop >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
free(p);
|
||||
if (r != 0) {
|
||||
if (!canLzop()) {
|
||||
skipping("lzop is not supported on this platform");
|
||||
@ -53,4 +53,5 @@ DEFINE_TEST(test_option_lzop)
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9);
|
||||
free(p);
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ DEFINE_TEST(test_option_uuencode)
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin 644", 9);
|
||||
free(p);
|
||||
|
||||
/* Archive it with uuencode only. */
|
||||
assertEqualInt(0,
|
||||
@ -51,4 +52,5 @@ DEFINE_TEST(test_option_uuencode)
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin 644", 9);
|
||||
free(p);
|
||||
}
|
||||
|
@ -44,14 +44,18 @@ DEFINE_TEST(test_option_xz)
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without xz support");
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
failure("--xz option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
/* Check that the archive file has an xz signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\xFD\x37\x7A\x58\x5A\x00", 6);
|
||||
free(p);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ DEFINE_TEST(test_option_y)
|
||||
r = systemf("echo f | %s -oy >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
free(p);
|
||||
if (r != 0) {
|
||||
if (!canBzip2()) {
|
||||
skipping("bzip2 is not supported on this platform");
|
||||
@ -46,14 +46,12 @@ DEFINE_TEST(test_option_y)
|
||||
}
|
||||
failure("-y option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
assertTextFileContents("1 block\n", "archive.err");
|
||||
/* Check that the archive file has a bzip2 signature. */
|
||||
free(p);
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "BZh9", 4);
|
||||
done:
|
||||
free(p);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ DEFINE_TEST(test_option_z)
|
||||
r = systemf("echo f | %s -oz >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
free(p);
|
||||
if (r != 0) {
|
||||
if (!canGzip()) {
|
||||
skipping("gzip is not supported on this platform");
|
||||
@ -52,4 +52,5 @@ DEFINE_TEST(test_option_z)
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 4);
|
||||
assertEqualMem(p, "\x1f\x8b\x08\x00", 4);
|
||||
free(p);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ archive_entry_sparse_clear(struct archive_entry *entry)
|
||||
|
||||
void
|
||||
archive_entry_sparse_add_entry(struct archive_entry *entry,
|
||||
int64_t offset, int64_t length)
|
||||
la_int64_t offset, la_int64_t length)
|
||||
{
|
||||
struct ae_sparse *sp;
|
||||
|
||||
@ -135,7 +135,7 @@ archive_entry_sparse_reset(struct archive_entry * entry)
|
||||
|
||||
int
|
||||
archive_entry_sparse_next(struct archive_entry * entry,
|
||||
int64_t *offset, int64_t *length)
|
||||
la_int64_t *offset, la_int64_t *length)
|
||||
{
|
||||
if (entry->sparse_p) {
|
||||
*offset = entry->sparse_p->offset;
|
||||
|
@ -691,7 +691,7 @@ Convert(time_t Month, time_t Day, time_t Year,
|
||||
time_t Hours, time_t Minutes, time_t Seconds,
|
||||
time_t Timezone, enum DSTMODE DSTmode)
|
||||
{
|
||||
int DaysInMonth[12] = {
|
||||
signed char DaysInMonth[12] = {
|
||||
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
time_t Julian;
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memset */
|
||||
static inline HMAC_CTX *HMAC_CTX_new(void)
|
||||
|
@ -881,7 +881,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||
len = a->read_data_remaining;
|
||||
if (len > s)
|
||||
len = s;
|
||||
memcpy(dest, a->read_data_block, len);
|
||||
if (len)
|
||||
memcpy(dest, a->read_data_block, len);
|
||||
s -= len;
|
||||
a->read_data_block += len;
|
||||
a->read_data_remaining -= len;
|
||||
|
@ -928,11 +928,10 @@ setup_sparse(struct archive_read_disk *a,
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
/* Does filesystem support the reporting of hole ? */
|
||||
if (*fd < 0) {
|
||||
if (*fd < 0)
|
||||
path = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (path == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
else
|
||||
path = NULL;
|
||||
|
||||
if (*fd >= 0) {
|
||||
#ifdef _PC_MIN_HOLE_SIZE
|
||||
@ -943,6 +942,8 @@ setup_sparse(struct archive_read_disk *a,
|
||||
if (initial_off != 0)
|
||||
lseek(*fd, 0, SEEK_SET);
|
||||
} else {
|
||||
if (path == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
#ifdef _PC_MIN_HOLE_SIZE
|
||||
if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
@ -494,7 +494,7 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
|
||||
if (read_buf == NULL)
|
||||
goto truncated_error;
|
||||
compressed_size = archive_le32dec(read_buf);
|
||||
if ((compressed_size & ~(1 << 31)) > state->flags.block_maximum_size)
|
||||
if ((compressed_size & 0x7fffffff) > state->flags.block_maximum_size)
|
||||
goto malformed_error;
|
||||
/* A compressed size == 0 means the end of stream blocks. */
|
||||
if (compressed_size == 0) {
|
||||
@ -504,8 +504,8 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
|
||||
|
||||
checksum_size = state->flags.block_checksum;
|
||||
/* Check if the block is uncompressed. */
|
||||
if (compressed_size & (1 << 31)) {
|
||||
compressed_size &= ~(1 << 31);
|
||||
if (compressed_size & 0x80000000U) {
|
||||
compressed_size &= 0x7fffffff;
|
||||
uncompressed_size = compressed_size;
|
||||
} else
|
||||
uncompressed_size = 0;/* Unknown yet. */
|
||||
|
@ -116,19 +116,11 @@ struct lzx_dec {
|
||||
* coding tree, which is a binary tree. But a use of a large
|
||||
* index table causes L1 cache read miss many times.
|
||||
*/
|
||||
#define HTBL_BITS 10
|
||||
int max_bits;
|
||||
int shift_bits;
|
||||
int tbl_bits;
|
||||
int tree_used;
|
||||
int tree_avail;
|
||||
/* Direct access table. */
|
||||
uint16_t *tbl;
|
||||
/* Binary tree table for extra bits over the direct access. */
|
||||
struct htree_t {
|
||||
uint16_t left;
|
||||
uint16_t right;
|
||||
} *tree;
|
||||
} at, lt, mt, pt;
|
||||
|
||||
int loop;
|
||||
@ -352,7 +344,6 @@ static int lzx_huffman_init(struct huffman *, size_t, int);
|
||||
static void lzx_huffman_free(struct huffman *);
|
||||
static int lzx_make_huffman_table(struct huffman *);
|
||||
static inline int lzx_decode_huffman(struct huffman *, unsigned);
|
||||
static int lzx_decode_huffman_tree(struct huffman *, unsigned, int);
|
||||
|
||||
|
||||
int
|
||||
@ -3127,7 +3118,6 @@ lzx_read_bitlen(struct lzx_stream *strm, struct huffman *d, int end)
|
||||
static int
|
||||
lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
|
||||
{
|
||||
int bits;
|
||||
|
||||
if (hf->bitlen == NULL || hf->len_size != (int)len_size) {
|
||||
free(hf->bitlen);
|
||||
@ -3138,21 +3128,11 @@ lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
|
||||
} else
|
||||
memset(hf->bitlen, 0, len_size * sizeof(hf->bitlen[0]));
|
||||
if (hf->tbl == NULL) {
|
||||
if (tbl_bits < HTBL_BITS)
|
||||
bits = tbl_bits;
|
||||
else
|
||||
bits = HTBL_BITS;
|
||||
hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0]));
|
||||
hf->tbl = malloc(((size_t)1 << tbl_bits) * sizeof(hf->tbl[0]));
|
||||
if (hf->tbl == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
hf->tbl_bits = tbl_bits;
|
||||
}
|
||||
if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
|
||||
hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
|
||||
hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
|
||||
if (hf->tree == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -3161,7 +3141,6 @@ lzx_huffman_free(struct huffman *hf)
|
||||
{
|
||||
free(hf->bitlen);
|
||||
free(hf->tbl);
|
||||
free(hf->tree);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3174,7 +3153,7 @@ lzx_make_huffman_table(struct huffman *hf)
|
||||
const unsigned char *bitlen;
|
||||
int bitptn[17], weight[17];
|
||||
int i, maxbits = 0, ptn, tbl_size, w;
|
||||
int diffbits, len_avail;
|
||||
int len_avail;
|
||||
|
||||
/*
|
||||
* Initialize bit patterns.
|
||||
@ -3205,28 +3184,11 @@ lzx_make_huffman_table(struct huffman *hf)
|
||||
weight[i] >>= ebits;
|
||||
}
|
||||
}
|
||||
if (maxbits > HTBL_BITS) {
|
||||
int htbl_max;
|
||||
uint16_t *p;
|
||||
|
||||
diffbits = maxbits - HTBL_BITS;
|
||||
for (i = 1; i <= HTBL_BITS; i++) {
|
||||
bitptn[i] >>= diffbits;
|
||||
weight[i] >>= diffbits;
|
||||
}
|
||||
htbl_max = bitptn[HTBL_BITS] +
|
||||
weight[HTBL_BITS] * hf->freq[HTBL_BITS];
|
||||
p = &(hf->tbl[htbl_max]);
|
||||
while (p < &hf->tbl[1U<<HTBL_BITS])
|
||||
*p++ = 0;
|
||||
} else
|
||||
diffbits = 0;
|
||||
hf->shift_bits = diffbits;
|
||||
|
||||
/*
|
||||
* Make the table.
|
||||
*/
|
||||
tbl_size = 1 << HTBL_BITS;
|
||||
tbl_size = 1 << hf->tbl_bits;
|
||||
tbl = hf->tbl;
|
||||
bitlen = hf->bitlen;
|
||||
len_avail = hf->len_size;
|
||||
@ -3234,120 +3196,32 @@ lzx_make_huffman_table(struct huffman *hf)
|
||||
for (i = 0; i < len_avail; i++) {
|
||||
uint16_t *p;
|
||||
int len, cnt;
|
||||
uint16_t bit;
|
||||
int extlen;
|
||||
struct htree_t *ht;
|
||||
|
||||
if (bitlen[i] == 0)
|
||||
continue;
|
||||
/* Get a bit pattern */
|
||||
len = bitlen[i];
|
||||
if (len > tbl_size)
|
||||
return (0);
|
||||
ptn = bitptn[len];
|
||||
cnt = weight[len];
|
||||
if (len <= HTBL_BITS) {
|
||||
/* Calculate next bit pattern */
|
||||
if ((bitptn[len] = ptn + cnt) > tbl_size)
|
||||
return (0);/* Invalid */
|
||||
/* Update the table */
|
||||
p = &(tbl[ptn]);
|
||||
while (--cnt >= 0)
|
||||
p[cnt] = (uint16_t)i;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* A bit length is too big to be housed to a direct table,
|
||||
* so we use a tree model for its extra bits.
|
||||
*/
|
||||
bitptn[len] = ptn + cnt;
|
||||
bit = 1U << (diffbits -1);
|
||||
extlen = len - HTBL_BITS;
|
||||
|
||||
p = &(tbl[ptn >> diffbits]);
|
||||
if (*p == 0) {
|
||||
*p = len_avail + hf->tree_used;
|
||||
ht = &(hf->tree[hf->tree_used++]);
|
||||
if (hf->tree_used > hf->tree_avail)
|
||||
return (0);/* Invalid */
|
||||
ht->left = 0;
|
||||
ht->right = 0;
|
||||
} else {
|
||||
if (*p < len_avail ||
|
||||
*p >= (len_avail + hf->tree_used))
|
||||
return (0);/* Invalid */
|
||||
ht = &(hf->tree[*p - len_avail]);
|
||||
}
|
||||
while (--extlen > 0) {
|
||||
if (ptn & bit) {
|
||||
if (ht->left < len_avail) {
|
||||
ht->left = len_avail + hf->tree_used;
|
||||
ht = &(hf->tree[hf->tree_used++]);
|
||||
if (hf->tree_used > hf->tree_avail)
|
||||
return (0);/* Invalid */
|
||||
ht->left = 0;
|
||||
ht->right = 0;
|
||||
} else {
|
||||
ht = &(hf->tree[ht->left - len_avail]);
|
||||
}
|
||||
} else {
|
||||
if (ht->right < len_avail) {
|
||||
ht->right = len_avail + hf->tree_used;
|
||||
ht = &(hf->tree[hf->tree_used++]);
|
||||
if (hf->tree_used > hf->tree_avail)
|
||||
return (0);/* Invalid */
|
||||
ht->left = 0;
|
||||
ht->right = 0;
|
||||
} else {
|
||||
ht = &(hf->tree[ht->right - len_avail]);
|
||||
}
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
if (ptn & bit) {
|
||||
if (ht->left != 0)
|
||||
return (0);/* Invalid */
|
||||
ht->left = (uint16_t)i;
|
||||
} else {
|
||||
if (ht->right != 0)
|
||||
return (0);/* Invalid */
|
||||
ht->right = (uint16_t)i;
|
||||
}
|
||||
/* Calculate next bit pattern */
|
||||
if ((bitptn[len] = ptn + cnt) > tbl_size)
|
||||
return (0);/* Invalid */
|
||||
/* Update the table */
|
||||
p = &(tbl[ptn]);
|
||||
while (--cnt >= 0)
|
||||
p[cnt] = (uint16_t)i;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
lzx_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
|
||||
{
|
||||
struct htree_t *ht;
|
||||
int extlen;
|
||||
|
||||
ht = hf->tree;
|
||||
extlen = hf->shift_bits;
|
||||
while (c >= hf->len_size) {
|
||||
c -= hf->len_size;
|
||||
if (extlen-- <= 0 || c >= hf->tree_used)
|
||||
return (0);
|
||||
if (rbits & (1U << extlen))
|
||||
c = ht[c].left;
|
||||
else
|
||||
c = ht[c].right;
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
static inline int
|
||||
lzx_decode_huffman(struct huffman *hf, unsigned rbits)
|
||||
{
|
||||
int c;
|
||||
/*
|
||||
* At first search an index table for a bit pattern.
|
||||
* If it fails, search a huffman tree for.
|
||||
*/
|
||||
c = hf->tbl[rbits >> hf->shift_bits];
|
||||
c = hf->tbl[rbits];
|
||||
if (c < hf->len_size)
|
||||
return (c);
|
||||
/* This bit pattern needs to be found out at a huffman tree. */
|
||||
return (lzx_decode_huffman_tree(hf, rbits, c));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ __FBSDID("$FreeBSD$");
|
||||
struct links_entry {
|
||||
struct links_entry *next;
|
||||
struct links_entry *previous;
|
||||
int links;
|
||||
unsigned int links;
|
||||
dev_t dev;
|
||||
int64_t ino;
|
||||
char *name;
|
||||
|
@ -3021,8 +3021,9 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
|
||||
ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
memcpy(new_pending_files, heap->files,
|
||||
heap->allocated * sizeof(new_pending_files[0]));
|
||||
if (heap->allocated)
|
||||
memcpy(new_pending_files, heap->files,
|
||||
heap->allocated * sizeof(new_pending_files[0]));
|
||||
if (heap->files != NULL)
|
||||
free(heap->files);
|
||||
heap->files = new_pending_files;
|
||||
|
@ -130,9 +130,7 @@ static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t)
|
||||
static int skip(struct archive_read *a);
|
||||
static int read_header(struct archive_read *,
|
||||
struct archive_entry *);
|
||||
static int64_t mtree_atol10(char **);
|
||||
static int64_t mtree_atol8(char **);
|
||||
static int64_t mtree_atol(char **);
|
||||
static int64_t mtree_atol(char **, int base);
|
||||
|
||||
/*
|
||||
* There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
|
||||
@ -1418,7 +1416,7 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
|
||||
"Too many arguments");
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
numbers[argc++] = (unsigned long)mtree_atol(&p);
|
||||
numbers[argc++] = (unsigned long)mtree_atol(&p, 0);
|
||||
}
|
||||
if (argc < 2) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -1433,7 +1431,7 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
|
||||
}
|
||||
} else {
|
||||
/* file system raw value. */
|
||||
result = (dev_t)mtree_atol(&val);
|
||||
result = (dev_t)mtree_atol(&val, 0);
|
||||
}
|
||||
*pdev = result;
|
||||
return ARCHIVE_OK;
|
||||
@ -1513,7 +1511,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
case 'g':
|
||||
if (strcmp(key, "gid") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_GID;
|
||||
archive_entry_set_gid(entry, mtree_atol10(&val));
|
||||
archive_entry_set_gid(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
if (strcmp(key, "gname") == 0) {
|
||||
@ -1523,7 +1521,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
}
|
||||
case 'i':
|
||||
if (strcmp(key, "inode") == 0) {
|
||||
archive_entry_set_ino(entry, mtree_atol10(&val));
|
||||
archive_entry_set_ino(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
case 'l':
|
||||
@ -1535,14 +1533,14 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
|
||||
break;
|
||||
if (strcmp(key, "mode") == 0) {
|
||||
if (val[0] >= '0' && val[0] <= '9') {
|
||||
if (val[0] >= '0' && val[0] <= '7') {
|
||||
*parsed_kws |= MTREE_HAS_PERM;
|
||||
archive_entry_set_perm(entry,
|
||||
(mode_t)mtree_atol8(&val));
|
||||
(mode_t)mtree_atol(&val, 8));
|
||||
} else {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Symbolic mode \"%s\" unsupported", val);
|
||||
"Symbolic or non-octal mode \"%s\" unsupported", val);
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
break;
|
||||
@ -1551,7 +1549,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
if (strcmp(key, "nlink") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_NLINK;
|
||||
archive_entry_set_nlink(entry,
|
||||
(unsigned int)mtree_atol10(&val));
|
||||
(unsigned int)mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
case 'r':
|
||||
@ -1582,7 +1580,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
strcmp(key, "sha512digest") == 0)
|
||||
break;
|
||||
if (strcmp(key, "size") == 0) {
|
||||
archive_entry_set_size(entry, mtree_atol10(&val));
|
||||
archive_entry_set_size(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
@ -1601,13 +1599,13 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
long ns = 0;
|
||||
|
||||
*parsed_kws |= MTREE_HAS_MTIME;
|
||||
m = mtree_atol10(&val);
|
||||
m = mtree_atol(&val, 10);
|
||||
/* Replicate an old mtree bug:
|
||||
* 123456789.1 represents 123456789
|
||||
* seconds and 1 nanosecond. */
|
||||
if (*val == '.') {
|
||||
++val;
|
||||
ns = (long)mtree_atol10(&val);
|
||||
ns = (long)mtree_atol(&val, 10);
|
||||
if (ns < 0)
|
||||
ns = 0;
|
||||
else if (ns > 999999999)
|
||||
@ -1670,7 +1668,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
case 'u':
|
||||
if (strcmp(key, "uid") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_UID;
|
||||
archive_entry_set_uid(entry, mtree_atol10(&val));
|
||||
archive_entry_set_uid(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
if (strcmp(key, "uname") == 0) {
|
||||
@ -1825,77 +1823,9 @@ parse_escapes(char *src, struct mtree_entry *mentry)
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that this implementation does not (and should not!) obey
|
||||
* locale settings; you cannot simply substitute strtol here, since
|
||||
* it does obey locale.
|
||||
*/
|
||||
static int64_t
|
||||
mtree_atol8(char **p)
|
||||
{
|
||||
int64_t l, limit, last_digit_limit;
|
||||
int digit, base;
|
||||
|
||||
base = 8;
|
||||
limit = INT64_MAX / base;
|
||||
last_digit_limit = INT64_MAX % base;
|
||||
|
||||
l = 0;
|
||||
digit = **p - '0';
|
||||
while (digit >= 0 && digit < base) {
|
||||
if (l>limit || (l == limit && digit > last_digit_limit)) {
|
||||
l = INT64_MAX; /* Truncate on overflow. */
|
||||
break;
|
||||
}
|
||||
l = (l * base) + digit;
|
||||
digit = *++(*p) - '0';
|
||||
}
|
||||
return (l);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that this implementation does not (and should not!) obey
|
||||
* locale settings; you cannot simply substitute strtol here, since
|
||||
* it does obey locale.
|
||||
*
|
||||
* Convert the number pointed to by 'p' into a 64-bit signed integer.
|
||||
* On return, 'p' points to the first non-digit following the number.
|
||||
* On overflow, the function returns INT64_MIN or INT64_MAX.
|
||||
*/
|
||||
static int64_t
|
||||
mtree_atol10(char **p)
|
||||
{
|
||||
const int base = 10;
|
||||
const int64_t limit = INT64_MAX / base;
|
||||
const int64_t last_digit_limit = INT64_MAX % base;
|
||||
int64_t l;
|
||||
int sign;
|
||||
|
||||
if (**p == '-') {
|
||||
sign = -1;
|
||||
++(*p);
|
||||
} else {
|
||||
sign = 1;
|
||||
}
|
||||
|
||||
l = 0;
|
||||
while (**p >= '0' && **p < '0' + base) {
|
||||
int digit = **p - '0';
|
||||
if (l > limit || (l == limit && digit > last_digit_limit)) {
|
||||
while (**p >= '0' && **p < '0' + base) {
|
||||
++(*p);
|
||||
}
|
||||
return (sign < 0) ? INT64_MIN : INT64_MAX;
|
||||
}
|
||||
l = (l * base) + digit;
|
||||
++(*p);
|
||||
}
|
||||
return (sign < 0) ? -l : l;
|
||||
}
|
||||
|
||||
/* Parse a hex digit. */
|
||||
static int
|
||||
parsehex(char c)
|
||||
parsedigit(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
@ -1913,45 +1843,50 @@ parsehex(char c)
|
||||
* it does obey locale.
|
||||
*/
|
||||
static int64_t
|
||||
mtree_atol16(char **p)
|
||||
mtree_atol(char **p, int base)
|
||||
{
|
||||
int64_t l, limit, last_digit_limit;
|
||||
int base, digit, sign;
|
||||
int64_t l, limit;
|
||||
int digit, last_digit_limit;
|
||||
|
||||
base = 16;
|
||||
if (base == 0) {
|
||||
if (**p != '0')
|
||||
base = 10;
|
||||
else if ((*p)[1] == 'x' || (*p)[1] == 'X') {
|
||||
*p += 2;
|
||||
base = 16;
|
||||
} else {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (**p == '-') {
|
||||
sign = -1;
|
||||
limit = ((uint64_t)(INT64_MAX) + 1) / base;
|
||||
last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
|
||||
limit = INT64_MIN / base;
|
||||
last_digit_limit = INT64_MIN % base;
|
||||
++(*p);
|
||||
|
||||
l = 0;
|
||||
digit = parsedigit(**p);
|
||||
while (digit >= 0 && digit < base) {
|
||||
if (l < limit || (l == limit && digit > last_digit_limit))
|
||||
return INT64_MIN;
|
||||
l = (l * base) - digit;
|
||||
digit = parsedigit(*++(*p));
|
||||
}
|
||||
return l;
|
||||
} else {
|
||||
sign = 1;
|
||||
limit = INT64_MAX / base;
|
||||
last_digit_limit = INT64_MAX % base;
|
||||
}
|
||||
|
||||
l = 0;
|
||||
digit = parsehex(**p);
|
||||
while (digit >= 0 && digit < base) {
|
||||
if (l > limit || (l == limit && digit > last_digit_limit))
|
||||
return (sign < 0) ? INT64_MIN : INT64_MAX;
|
||||
l = (l * base) + digit;
|
||||
digit = parsehex(*++(*p));
|
||||
l = 0;
|
||||
digit = parsedigit(**p);
|
||||
while (digit >= 0 && digit < base) {
|
||||
if (l > limit || (l == limit && digit > last_digit_limit))
|
||||
return INT64_MAX;
|
||||
l = (l * base) + digit;
|
||||
digit = parsedigit(*++(*p));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
return (sign < 0) ? -l : l;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
mtree_atol(char **p)
|
||||
{
|
||||
if (**p != '0')
|
||||
return mtree_atol10(p);
|
||||
if ((*p)[1] == 'x' || (*p)[1] == 'X') {
|
||||
*p += 2;
|
||||
return mtree_atol16(p);
|
||||
}
|
||||
return mtree_atol8(p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1750,7 +1750,7 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
|
||||
return (-1);
|
||||
for (j = 0; j < count; j++)
|
||||
{
|
||||
rem = ((*p) << 16) | (rem >> 8);
|
||||
rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
|
||||
p++;
|
||||
}
|
||||
tm = localtime(&t);
|
||||
|
@ -202,7 +202,8 @@ archive_string_append(struct archive_string *as, const char *p, size_t s)
|
||||
{
|
||||
if (archive_string_ensure(as, as->length + s + 1) == NULL)
|
||||
return (NULL);
|
||||
memmove(as->s + as->length, p, s);
|
||||
if (s)
|
||||
memmove(as->s + as->length, p, s);
|
||||
as->length += s;
|
||||
as->s[as->length] = 0;
|
||||
return (as);
|
||||
|
@ -1196,8 +1196,12 @@ archive_write_pax_header(struct archive_write *a,
|
||||
"GNU.sparse.major", 1);
|
||||
add_pax_attr_int(&(pax->pax_header),
|
||||
"GNU.sparse.minor", 0);
|
||||
/*
|
||||
* Make sure to store the original path, since
|
||||
* truncation to ustar limit happened already.
|
||||
*/
|
||||
add_pax_attr(&(pax->pax_header),
|
||||
"GNU.sparse.name", entry_name.s);
|
||||
"GNU.sparse.name", path);
|
||||
add_pax_attr_int(&(pax->pax_header),
|
||||
"GNU.sparse.realsize",
|
||||
archive_entry_size(entry_main));
|
||||
@ -1650,13 +1654,14 @@ build_pax_attribute_name(char *dest, const char *src)
|
||||
* GNU PAX Format 1.0 requires the special name, which pattern is:
|
||||
* <dir>/GNUSparseFile.<pid>/<original file name>
|
||||
*
|
||||
* Since reproducable archives are more important, use 0 as pid.
|
||||
*
|
||||
* This function is used for only Sparse file, a file type of which
|
||||
* is regular file.
|
||||
*/
|
||||
static char *
|
||||
build_gnu_sparse_name(char *dest, const char *src)
|
||||
{
|
||||
char buff[64];
|
||||
const char *p;
|
||||
|
||||
/* Handle the null filename case. */
|
||||
@ -1682,15 +1687,9 @@ build_gnu_sparse_name(char *dest, const char *src)
|
||||
break;
|
||||
}
|
||||
|
||||
#if HAVE_GETPID && 0 /* Disable this as pax attribute name. */
|
||||
sprintf(buff, "GNUSparseFile.%d", getpid());
|
||||
#else
|
||||
/* If the platform can't fetch the pid, don't include it. */
|
||||
strcpy(buff, "GNUSparseFile");
|
||||
#endif
|
||||
/* General case: build a ustar-compatible name adding
|
||||
* "/GNUSparseFile/". */
|
||||
build_ustar_entry_name(dest, src, p - src, buff);
|
||||
build_ustar_entry_name(dest, src, p - src, "GNUSparseFile.0");
|
||||
|
||||
return (dest);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
.Dt LIBARCHIVE_CHANGES 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm libarchive_changes
|
||||
.Nd changes in libarchive interface
|
||||
.\"
|
||||
.Sh CHANGES IN LIBARCHIVE 3
|
||||
|
@ -183,7 +183,7 @@ test_read_format_mtree1(void)
|
||||
min_time = archive_entry_mtime(ae);
|
||||
assert(min_time <= 0);
|
||||
/* Simply asserting min_time - 1 > 0 breaks with some compiler optimizations. */
|
||||
t = min_time - 1;
|
||||
t = (time_t)((uintmax_t)min_time - 1);
|
||||
assert(t > 0);
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Phillip Berndt
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Issue 869: zip files without a valid EOCD header aren't loaded even if they
|
||||
* have a valid ZIP64 version of said header.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_with_invalid_traditional_eocd)
|
||||
{
|
||||
const char *refname = "test_read_format_zip_with_invalid_traditional_eocd.zip";
|
||||
char *p;
|
||||
size_t s;
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
extract_reference_file(refname);
|
||||
p = slurpfile(&s, refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip_seekable(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("test1.txt", archive_entry_pathname(ae));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("test2.txt", archive_entry_pathname(ae));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
free(p);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
begin 644 test_read_format_zip_without_eocd.zip
|
||||
M4$L#!"T`"````-IT@DH`````__________\)`"``=&5S=#$N='AT`0`<````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`%!+`P0M``@```#:=()*`````/__________"0`@`'1E<W0R+G1X=`$`'```
|
||||
M````````````````````6P``````````````````````````````````````
|
||||
M``!02P$"+0,M``@```#:=()*`````/__________"0`@````__\`````I('_
|
||||
M____=&5S=#$N='AT`0`<``````````````````````````````````````!0
|
||||
M2P$"+0,M``@```#:=()*`````/__________"0`@````__\`````I('_____
|
||||
M=&5S=#(N='AT`0`<``````````````````````!;``````````````!02P8&
|
||||
M+``````````M`RT````````````"``````````(`````````K@````````"V
|
||||
M`````````%!+!@<`````9`$````````!````4$L%!O__________________
|
||||
$__\`````
|
||||
`
|
||||
end
|
@ -80,13 +80,19 @@ DEFINE_TEST(test_write_format_pax)
|
||||
/*
|
||||
* "file3" is sparse file and has hole size of which is
|
||||
* 1024000 bytes, and has 8 bytes data after the hole.
|
||||
*
|
||||
* Pad the filename to make it larger than the ustar limit.
|
||||
* It should still read back correctly.
|
||||
*/
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_set_atime(ae, 2, 20);
|
||||
archive_entry_set_birthtime(ae, 3, 30);
|
||||
archive_entry_set_ctime(ae, 4, 40);
|
||||
archive_entry_set_mtime(ae, 5, 50);
|
||||
archive_entry_copy_pathname(ae, "file3");
|
||||
archive_entry_copy_pathname(ae, "file3"
|
||||
"_123456789_123456789_123456789_123456789_123456789"
|
||||
"_123456789_123456789_123456789_123456789_123456789"
|
||||
"_123456789_123456789_123456789_123456789_123456789");
|
||||
archive_entry_set_mode(ae, S_IFREG | 0755);
|
||||
archive_entry_set_size(ae, 1024008);
|
||||
archive_entry_sparse_add_entry(ae, 1024000, 8);
|
||||
@ -171,7 +177,11 @@ DEFINE_TEST(test_write_format_pax)
|
||||
assertEqualInt(40, archive_entry_ctime_nsec(ae));
|
||||
assertEqualInt(5, archive_entry_mtime(ae));
|
||||
assertEqualInt(50, archive_entry_mtime_nsec(ae));
|
||||
assertEqualString("file3", archive_entry_pathname(ae));
|
||||
assertEqualString("file3"
|
||||
"_123456789_123456789_123456789_123456789_123456789"
|
||||
"_123456789_123456789_123456789_123456789_123456789"
|
||||
"_123456789_123456789_123456789_123456789_123456789",
|
||||
archive_entry_pathname(ae));
|
||||
assert((S_IFREG | 0755) == archive_entry_mode(ae));
|
||||
assertEqualInt(1024008, archive_entry_size(ae));
|
||||
assertEqualInt(1, archive_entry_sparse_reset(ae));
|
||||
|
@ -108,8 +108,19 @@ static void verify_write_uncompressed(struct archive *a)
|
||||
}
|
||||
|
||||
/* Quick and dirty: Read 2-byte and 4-byte integers from Zip file. */
|
||||
static int i2(const char *p) { return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); }
|
||||
static int i4(const char *p) { return (i2(p) | (i2(p + 2) << 16)); }
|
||||
static unsigned int
|
||||
i2(const void *p_)
|
||||
{
|
||||
const unsigned char *p = p_;
|
||||
return (p[0] | (p[1] << 8));
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
i4(const void *p_)
|
||||
{
|
||||
const unsigned char *p = p_;
|
||||
return (i2(p) | (i2(p + 2) << 16));
|
||||
}
|
||||
|
||||
static void verify_uncompressed_contents(const char *buff, size_t used)
|
||||
{
|
||||
|
@ -67,21 +67,19 @@ static int64_t memory_read_skip(struct archive *, void *, int64_t request);
|
||||
static ssize_t memory_read(struct archive *, void *, const void **buff);
|
||||
static ssize_t memory_write(struct archive *, void *, const void *, size_t);
|
||||
|
||||
static int16_t le16(const void *_p) {
|
||||
static uint16_t le16(const void *_p) {
|
||||
const uint8_t *p = _p;
|
||||
return (0xff & (int16_t)p[0]) | ((0xff & (int16_t)p[1]) << 8);
|
||||
return p[0] | (p[1] << 8);
|
||||
}
|
||||
|
||||
static int32_t le32(const void *_p) {
|
||||
static uint32_t le32(const void *_p) {
|
||||
const uint8_t *p = _p;
|
||||
int32_t v = 0xffff & (int32_t)le16(_p);
|
||||
return v + ((0xffff & (int32_t)le16(p + 2)) << 16);
|
||||
return le16(p) | ((uint32_t)le16(p + 2) << 16);
|
||||
}
|
||||
|
||||
static int64_t le64(const void *_p) {
|
||||
static uint64_t le64(const void *_p) {
|
||||
const uint8_t *p = _p;
|
||||
int64_t v = 0xffffffff & (int64_t)le32(_p);
|
||||
return v + ((0xffffffff & (int64_t)le32(p + 4)) << 32);
|
||||
return le32(p) | ((uint64_t)le32(p + 4) << 32);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
@ -141,13 +141,19 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#define A32(x) (((const U32_S *)(x))->v)
|
||||
|
||||
|
||||
/****************************************
|
||||
** Compiler-specific Functions and Macros
|
||||
*****************************************/
|
||||
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
#define GCC_VERSION ((__GNUC__-0) * 100 + (__GNUC_MINOR__ - 0))
|
||||
|
||||
#if GCC_VERSION >= 409
|
||||
__attribute__((__no_sanitize_undefined__))
|
||||
#endif
|
||||
static inline U32 A32(const void * x)
|
||||
{
|
||||
return (((const U32_S *)(x))->v);
|
||||
}
|
||||
|
||||
/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
|
||||
#if defined(_MSC_VER)
|
||||
|
@ -1102,6 +1102,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
|
||||
failure_start(pathname, line, "Can't allocate memory");
|
||||
failure_finish(NULL);
|
||||
free(expected);
|
||||
free(buff);
|
||||
return (0);
|
||||
}
|
||||
for (i = 0; lines[i] != NULL; ++i) {
|
||||
@ -1124,6 +1125,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
|
||||
failure_start(pathname, line, "Can't allocate memory");
|
||||
failure_finish(NULL);
|
||||
free(expected);
|
||||
free(buff);
|
||||
return (0);
|
||||
}
|
||||
for (j = 0, p = buff; p < buff + buff_size;
|
||||
|
@ -195,6 +195,7 @@ TESTS_SRCS= \
|
||||
test_read_format_zip_traditional_encryption_data.c \
|
||||
test_read_format_zip_winzip_aes.c \
|
||||
test_read_format_zip_winzip_aes_large.c \
|
||||
test_read_format_zip_with_invalid_traditional_eocd.c \
|
||||
test_read_format_zip_zip64.c \
|
||||
test_read_large.c \
|
||||
test_read_pax_schily_xattr.c \
|
||||
@ -541,6 +542,7 @@ ${PACKAGE}FILES+= test_read_format_zip_sfx.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_symlink.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_traditional_encryption_data.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_ux.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_with_invalid_traditional_eocd.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_winzip_aes128.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_winzip_aes256.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_winzip_aes256_large.zip.uu
|
||||
|
Loading…
Reference in New Issue
Block a user