MFV r345495:

Sync libarchive with vendor.

Relevant vendor changes:
  PR #1153: fixed 2 bugs in ZIP reader [1]
  PR #1143: ensure archive_read_disk_entry_from_file() uses ARCHIVE_READ_DISK
  Changes to file flags code, support more file flags on FreeBSD:
    UF_OFFLINE, UF_READONLY, UF_SPARSE, UF_REPARSE, UF_SYSTEM
    UF_ARCHIVE is not supported by intention (yet)

PR:		236300
MFC after:	2 weeks
This commit is contained in:
Martin Matuska 2019-03-25 11:49:57 +00:00
commit df422cb404
16 changed files with 365 additions and 225 deletions

View File

@ -89,7 +89,7 @@ int blake2sp_init( blake2sp_state *S, size_t outlen )
return -1;
for( i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;
if( blake2sp_init_leaf( S->S[i], outlen, 0, (uint32_t)i ) < 0 ) return -1;
S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
@ -112,7 +112,7 @@ int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t
return -1;
for( i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;
if( blake2sp_init_leaf( S->S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
@ -230,7 +230,7 @@ int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void
if( keylen > BLAKE2S_KEYBYTES ) return -1;
for( i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;
if( blake2sp_init_leaf( S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */

View File

@ -1632,6 +1632,51 @@ _archive_entry_acl_text_l(struct archive_entry *entry, int flags,
* SUCH DAMAGE.
*/
/*
* Supported file flags on FreeBSD and Mac OS:
* sappnd,sappend SF_APPEND
* arch,archived SF_ARCHIVED
* schg,schange,simmutable SF_IMMUTABLE
* sunlnk,sunlink SF_NOUNLINK (FreeBSD only)
* uappnd,uappend UF_APPEND
* compressed UF_COMPRESSED (Mac OS only)
* hidden,uhidden UF_HIDDEN
* uchg,uchange,uimmutable UF_IMMUTABLE
* nodump UF_NODUMP
* uunlnk,uunlink UF_NOUNLINK (FreeBSD only)
* offline,uoffline UF_OFFLINE (FreeBSD only)
* opaque UF_OPAQUE
* rdonly,urdonly,readonly UF_READONLY (FreeBSD only)
* reparse,ureparse UF_REPARSE (FreeBSD only)
* sparse,usparse UF_SPARSE (FreeBSD only)
* system,usystem UF_SYSTEM (FreeBSD only)
*
* See chflags(2) for more information
*
* Supported file attributes on Linux:
* a append only FS_APPEND_FL sappnd
* A no atime updates FS_NOATIME_FL atime
* c compress FS_COMPR_FL compress
* C no copy on write FS_NOCOW_FL cow
* d no dump FS_NODUMP_FL dump
* D synchronous directory updates FS_DIRSYNC_FL dirsync
* i immutable FS_IMMUTABLE_FL schg
* j data journalling FS_JOURNAL_DATA_FL journal
* P project hierarchy FS_PROJINHERIT_FL projinherit
* s secure deletion FS_SECRM_FL securedeletion
* S synchronous updates FS_SYNC_FL sync
* t no tail-merging FS_NOTAIL_FL tail
* T top of directory hierarchy FS_TOPDIR_FL topdir
* u undeletable FS_UNRM_FL undel
*
* See ioctl_iflags(2) for more information
*
* Equivalent file flags supported on FreeBSD / Mac OS and Linux:
* SF_APPEND FS_APPEND_FL sappnd
* SF_IMMUTABLE FS_IMMUTABLE_FL schg
* UF_NODUMP FS_NODUMP_FL nodump
*/
static const struct flag {
const char *name;
const wchar_t *wname;
@ -1640,190 +1685,149 @@ static const struct flag {
} flags[] = {
/* Preferred (shorter) names per flag first, all prefixed by "no" */
#ifdef SF_APPEND
{ "nosappnd", L"nosappnd", SF_APPEND, 0 },
{ "nosappend", L"nosappend", SF_APPEND, 0 },
{ "nosappnd", L"nosappnd", SF_APPEND, 0},
{ "nosappend", L"nosappend", SF_APPEND, 0},
#endif
#if defined(FS_APPEND_FL) /* 'a' */
{ "nosappnd", L"nosappnd", FS_APPEND_FL, 0 },
{ "nosappend", L"nosappend", FS_APPEND_FL, 0 },
{ "nosappnd", L"nosappnd", FS_APPEND_FL, 0},
{ "nosappend", L"nosappend", FS_APPEND_FL, 0},
#elif defined(EXT2_APPEND_FL) /* 'a' */
{ "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0 },
{ "nosappend", L"nosappend", EXT2_APPEND_FL, 0 },
{ "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0},
{ "nosappend", L"nosappend", EXT2_APPEND_FL, 0},
#endif
#ifdef SF_ARCHIVED
{ "noarch", L"noarch", SF_ARCHIVED, 0 },
{ "noarchived", L"noarchived", SF_ARCHIVED, 0 },
{ "noarch", L"noarch", SF_ARCHIVED, 0},
{ "noarchived", L"noarchived", SF_ARCHIVED, 0},
#endif
#ifdef SF_IMMUTABLE
{ "noschg", L"noschg", SF_IMMUTABLE, 0 },
{ "noschange", L"noschange", SF_IMMUTABLE, 0 },
{ "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0 },
{ "noschg", L"noschg", SF_IMMUTABLE, 0},
{ "noschange", L"noschange", SF_IMMUTABLE, 0},
{ "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0},
#endif
#if defined(FS_IMMUTABLE_FL) /* 'i' */
{ "noschg", L"noschg", FS_IMMUTABLE_FL, 0 },
{ "noschange", L"noschange", FS_IMMUTABLE_FL, 0 },
{ "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0 },
{ "noschg", L"noschg", FS_IMMUTABLE_FL, 0},
{ "noschange", L"noschange", FS_IMMUTABLE_FL, 0},
{ "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0},
#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */
{ "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0 },
{ "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0 },
{ "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0 },
{ "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0},
{ "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0},
{ "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0},
#endif
#ifdef SF_NOUNLINK
{ "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0 },
{ "nosunlink", L"nosunlink", SF_NOUNLINK, 0 },
#endif
#ifdef SF_SNAPSHOT
{ "nosnapshot", L"nosnapshot", SF_SNAPSHOT, 0 },
{ "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0},
{ "nosunlink", L"nosunlink", SF_NOUNLINK, 0},
#endif
#ifdef UF_APPEND
{ "nouappnd", L"nouappnd", UF_APPEND, 0 },
{ "nouappend", L"nouappend", UF_APPEND, 0 },
{ "nouappnd", L"nouappnd", UF_APPEND, 0},
{ "nouappend", L"nouappend", UF_APPEND, 0},
#endif
#ifdef UF_IMMUTABLE
{ "nouchg", L"nouchg", UF_IMMUTABLE, 0 },
{ "nouchange", L"nouchange", UF_IMMUTABLE, 0 },
{ "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0 },
{ "nouchg", L"nouchg", UF_IMMUTABLE, 0},
{ "nouchange", L"nouchange", UF_IMMUTABLE, 0},
{ "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0},
#endif
#ifdef UF_NODUMP
{ "nodump", L"nodump", 0, UF_NODUMP},
#endif
#if defined(FS_NODUMP_FL) /* 'd' */
{ "nodump", L"nodump", 0, FS_NODUMP_FL},
#elif defined(EXT2_NODUMP_FL) /* 'd' */
#elif defined(EXT2_NODUMP_FL)
{ "nodump", L"nodump", 0, EXT2_NODUMP_FL},
#endif
#ifdef UF_OPAQUE
{ "noopaque", L"noopaque", UF_OPAQUE, 0 },
{ "noopaque", L"noopaque", UF_OPAQUE, 0},
#endif
#ifdef UF_NOUNLINK
{ "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0 },
{ "nouunlink", L"nouunlink", UF_NOUNLINK, 0 },
{ "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0},
{ "nouunlink", L"nouunlink", UF_NOUNLINK, 0},
#endif
#ifdef UF_COMPRESSED
{ "nocompressed",L"nocompressed", UF_COMPRESSED, 0 },
/* Mac OS */
{ "nocompressed", L"nocompressed", UF_COMPRESSED, 0},
#endif
#ifdef UF_HIDDEN
{ "nohidden", L"nohidden", UF_HIDDEN, 0 },
{ "nohidden", L"nohidden", UF_HIDDEN, 0},
{ "nouhidden", L"nouhidden", UF_HIDDEN, 0},
#endif
#if defined(FS_UNRM_FL)
{ "nouunlink", L"nouunlink", FS_UNRM_FL, 0},
#ifdef UF_OFFLINE
{ "nooffline", L"nooffline", UF_OFFLINE, 0},
{ "nouoffline", L"nouoffline", UF_OFFLINE, 0},
#endif
#ifdef UF_READONLY
{ "nordonly", L"nordonly", UF_READONLY, 0},
{ "nourdonly", L"nourdonly", UF_READONLY, 0},
{ "noreadonly", L"noreadonly", UF_READONLY, 0},
#endif
#ifdef UF_SPARSE
{ "nosparse", L"nosparse", UF_SPARSE, 0},
{ "nousparse", L"nousparse", UF_SPARSE, 0},
#endif
#ifdef UF_REPARSE
{ "noreparse", L"noreparse", UF_REPARSE, 0},
{ "noureparse", L"noureparse", UF_REPARSE, 0},
#endif
#ifdef UF_SYSTEM
{ "nosystem", L"nosystem", UF_SYSTEM, 0},
{ "nousystem", L"nousystem", UF_SYSTEM, 0},
#endif
#if defined(FS_UNRM_FL) /* 'u' */
{ "noundel", L"noundel", FS_UNRM_FL, 0},
#elif defined(EXT2_UNRM_FL)
{ "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0},
{ "noundel", L"noundel", EXT2_UNRM_FL, 0},
#endif
#if defined(FS_BTREE_FL)
{ "nobtree", L"nobtree", FS_BTREE_FL, 0 },
#elif defined(EXT2_BTREE_FL)
{ "nobtree", L"nobtree", EXT2_BTREE_FL, 0 },
#if defined(FS_COMPR_FL) /* 'c' */
{ "nocompress", L"nocompress", FS_COMPR_FL, 0},
#elif defined(EXT2_COMPR_FL)
{ "nocompress", L"nocompress", EXT2_COMPR_FL, 0},
#endif
#if defined(FS_ECOMPR_FL)
{ "nocomperr", L"nocomperr", FS_ECOMPR_FL, 0 },
#elif defined(EXT2_ECOMPR_FL)
{ "nocomperr", L"nocomperr", EXT2_ECOMPR_FL, 0 },
#if defined(FS_NOATIME_FL) /* 'A' */
{ "noatime", L"noatime", 0, FS_NOATIME_FL},
#elif defined(EXT2_NOATIME_FL)
{ "noatime", L"noatime", 0, EXT2_NOATIME_FL},
#endif
#if defined(FS_COMPR_FL) /* 'c' */
{ "nocompress", L"nocompress", FS_COMPR_FL, 0 },
#elif defined(EXT2_COMPR_FL) /* 'c' */
{ "nocompress", L"nocompress", EXT2_COMPR_FL, 0 },
#endif
#if defined(FS_NOATIME_FL) /* 'A' */
{ "noatime", L"noatime", 0, FS_NOATIME_FL},
#elif defined(EXT2_NOATIME_FL) /* 'A' */
{ "noatime", L"noatime", 0, EXT2_NOATIME_FL},
#endif
#if defined(FS_DIRTY_FL)
{ "nocompdirty",L"nocompdirty", FS_DIRTY_FL, 0},
#elif defined(EXT2_DIRTY_FL)
{ "nocompdirty",L"nocompdirty", EXT2_DIRTY_FL, 0},
#endif
#if defined(FS_COMPRBLK_FL)
#if defined(FS_NOCOMPR_FL)
{ "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, FS_NOCOMPR_FL},
#else
{ "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, 0},
#endif
#elif defined(EXT2_COMPRBLK_FL)
#if defined(EXT2_NOCOMPR_FL)
{ "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL},
#else
{ "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, 0},
#endif
#endif
#if defined(FS_DIRSYNC_FL)
{ "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0},
#if defined(FS_DIRSYNC_FL) /* 'D' */
{ "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0},
#elif defined(EXT2_DIRSYNC_FL)
{ "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0},
{ "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0},
#endif
#if defined(FS_INDEX_FL)
{ "nohashidx", L"nohashidx", FS_INDEX_FL, 0},
#elif defined(EXT2_INDEX_FL)
{ "nohashidx", L"nohashidx", EXT2_INDEX_FL, 0},
#endif
#if defined(FS_IMAGIC_FL)
{ "noimagic", L"noimagic", FS_IMAGIC_FL, 0},
#elif defined(EXT2_IMAGIC_FL)
{ "noimagic", L"noimagic", EXT2_IMAGIC_FL, 0},
#endif
#if defined(FS_JOURNAL_DATA_FL)
{ "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0},
#if defined(FS_JOURNAL_DATA_FL) /* 'j' */
{ "nojournal-data",L"nojournal-data", FS_JOURNAL_DATA_FL, 0},
{ "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0},
#elif defined(EXT3_JOURNAL_DATA_FL)
{ "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0},
{ "nojournal-data",L"nojournal-data", EXT3_JOURNAL_DATA_FL, 0},
{ "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0},
#endif
#if defined(FS_SECRM_FL)
{ "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0},
#if defined(FS_SECRM_FL) /* 's' */
{ "nosecdel", L"nosecdel", FS_SECRM_FL, 0},
{ "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0},
#elif defined(EXT2_SECRM_FL)
{ "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0},
{ "nosecdel", L"nosecdel", EXT2_SECRM_FL, 0},
{ "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0},
#endif
#if defined(FS_SYNC_FL)
{ "nosync", L"nosync", FS_SYNC_FL, 0},
#if defined(FS_SYNC_FL) /* 'S' */
{ "nosync", L"nosync", FS_SYNC_FL, 0},
#elif defined(EXT2_SYNC_FL)
{ "nosync", L"nosync", EXT2_SYNC_FL, 0},
{ "nosync", L"nosync", EXT2_SYNC_FL, 0},
#endif
#if defined(FS_NOTAIL_FL)
{ "notail", L"notail", 0, FS_NOTAIL_FL},
#if defined(FS_NOTAIL_FL) /* 't' */
{ "notail", L"notail", 0, FS_NOTAIL_FL},
#elif defined(EXT2_NOTAIL_FL)
{ "notail", L"notail", 0, EXT2_NOTAIL_FL},
{ "notail", L"notail", 0, EXT2_NOTAIL_FL},
#endif
#if defined(FS_TOPDIR_FL)
{ "notopdir", L"notopdir", FS_TOPDIR_FL, 0},
#if defined(FS_TOPDIR_FL) /* 'T' */
{ "notopdir", L"notopdir", FS_TOPDIR_FL, 0},
#elif defined(EXT2_TOPDIR_FL)
{ "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0},
{ "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0},
#endif
#ifdef FS_ENCRYPT_FL
{ "noencrypt", L"noencrypt", FS_ENCRYPT_FL, 0},
#ifdef FS_NOCOW_FL /* 'C' */
{ "nocow", L"nocow", 0, FS_NOCOW_FL},
#endif
#ifdef FS_HUGE_FILE_FL
{ "nohugefile", L"nohugefile", FS_HUGE_FILE_FL, 0},
#ifdef FS_PROJINHERIT_FL /* 'P' */
{ "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0},
#endif
#ifdef FS_EXTENT_FL
{ "noextent", L"noextent", FS_EXTENT_FL, 0},
#endif
#ifdef FS_EA_INODE_FL
{ "noeainode", L"noeainode", FS_EA_INODE_FL, 0},
#endif
#ifdef FS_EOFBLOCKS_FL
{ "noeofblocks",L"noeofblocks", FS_EOFBLOCKS_FL, 0},
#endif
#ifdef FS_NOCOW_FL
{ "nocow", L"nocow", FS_NOCOW_FL, 0},
#endif
#ifdef FS_INLINE_DATA_FL
{ "noinlinedata",L"noinlinedata", FS_INLINE_DATA_FL, 0},
#endif
#ifdef FS_PROJINHERIT_FL
{ "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0},
#endif
#if defined(FS_RESERVED_FL)
{ "noreserved", L"noreserved", FS_RESERVED_FL, 0},
#elif defined(EXT2_RESERVED_FL)
{ "noreserved", L"noreserved", EXT2_RESERVED_FL, 0},
#endif
{ NULL, NULL, 0, 0 }
{ NULL, NULL, 0, 0}
};
/*

View File

@ -163,6 +163,9 @@ archive_read_disk_entry_from_file(struct archive *_a,
int initial_fd = fd;
int r, r1;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
"archive_read_disk_entry_from_file");
archive_clear_error(_a);
path = archive_entry_sourcepath(entry);
if (path == NULL)

View File

@ -517,15 +517,16 @@ static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt,
const uint32_t file_size = 0x1000000;
ssize_t i;
const int mask = (int)rar->cstate.window_mask;
circular_memcpy(rar->cstate.filtered_buf,
rar->cstate.window_buf,
rar->cstate.window_mask,
mask,
rar->cstate.solid_offset + flt->block_start,
rar->cstate.solid_offset + flt->block_start + flt->block_length);
for(i = 0; i < flt->block_length - 4;) {
uint8_t b = rar->cstate.window_buf[(rar->cstate.solid_offset +
flt->block_start + i++) & rar->cstate.window_mask];
flt->block_start + i++) & mask];
/* 0xE8 = x86's call <relative_addr_uint32> (function call)
* 0xE9 = x86's jmp <relative_addr_uint32> (unconditional jump) */
@ -534,17 +535,17 @@ static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt,
uint32_t addr;
uint32_t offset = (i + flt->block_start) % file_size;
addr = read_filter_data(rar, (rar->cstate.solid_offset +
addr = read_filter_data(rar, (uint32_t)(rar->cstate.solid_offset +
flt->block_start + i) & rar->cstate.window_mask);
if(addr & 0x80000000) {
if(((addr + offset) & 0x80000000) == 0) {
write_filter_data(rar, i, addr + file_size);
write_filter_data(rar, (uint32_t)i, addr + file_size);
}
} else {
if((addr - file_size) & 0x80000000) {
uint32_t naddr = addr - offset;
write_filter_data(rar, i, naddr);
write_filter_data(rar, (uint32_t)i, naddr);
}
}
@ -558,11 +559,11 @@ static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt,
static int run_arm_filter(struct rar5* rar, struct filter_info* flt) {
ssize_t i = 0;
uint32_t offset;
const int mask = rar->cstate.window_mask;
const int mask = (int)rar->cstate.window_mask;
circular_memcpy(rar->cstate.filtered_buf,
rar->cstate.window_buf,
rar->cstate.window_mask,
mask,
rar->cstate.solid_offset + flt->block_start,
rar->cstate.solid_offset + flt->block_start + flt->block_length);
@ -577,7 +578,7 @@ static int run_arm_filter(struct rar5* rar, struct filter_info* flt) {
offset -= (uint32_t) ((i + flt->block_start) / 4);
offset = (offset & 0x00ffffff) | 0xeb000000;
write_filter_data(rar, i, offset);
write_filter_data(rar, (uint32_t)i, offset);
}
}
@ -643,7 +644,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
static void push_data(struct archive_read* a, struct rar5* rar,
const uint8_t* buf, int64_t idx_begin, int64_t idx_end)
{
const int wmask = rar->cstate.window_mask;
const int wmask = (int)rar->cstate.window_mask;
const ssize_t solid_write_ptr = (rar->cstate.solid_offset +
rar->cstate.last_write_ptr) & wmask;
@ -1716,8 +1717,8 @@ static int process_base_block(struct archive_read* a,
rar->generic.split_after = (header_flags & HFL_SPLIT_AFTER) > 0;
rar->generic.split_before = (header_flags & HFL_SPLIT_BEFORE) > 0;
rar->generic.size = hdr_size;
rar->generic.last_header_id = header_id;
rar->generic.size = (int)hdr_size;
rar->generic.last_header_id = (int)header_id;
rar->main.endarc = 0;
/* Those are possible header ids in RARv5. */
@ -1933,7 +1934,7 @@ static int create_decode_tables(uint8_t* bit_length,
}
}
quick_data_size = 1 << table->quick_bits;
quick_data_size = (int64_t)1 << table->quick_bits;
cur_len = 1;
for(code = 0; code < quick_data_size; code++) {
int bit_field = code << (16 - table->quick_bits);
@ -2364,7 +2365,7 @@ static int decode_code_length(struct rar5* rar, const uint8_t* p,
static int copy_string(struct archive_read* a, int len, int dist) {
struct rar5* rar = get_context(a);
const int cmask = rar->cstate.window_mask;
const int cmask = (int)rar->cstate.window_mask;
const int64_t write_ptr = rar->cstate.write_ptr + rar->cstate.solid_offset;
int i;
@ -2390,7 +2391,7 @@ static int do_uncompress_block(struct archive_read* a, const uint8_t* p) {
uint16_t num;
int ret;
const int cmask = rar->cstate.window_mask;
const int cmask = (int)rar->cstate.window_mask;
const struct compressed_block_header* hdr = &rar->last_block_hdr;
const uint8_t bit_size = 1 + bf_bit_size(hdr);

View File

@ -194,6 +194,7 @@ struct zip {
ssize_t zipx_ppmd_read_compressed;
CPpmd8 ppmd8;
char ppmd8_valid;
char ppmd8_stream_failed;
struct archive_string_conv *sconv;
struct archive_string_conv *sconv_default;
@ -254,9 +255,15 @@ ppmd_read(void* p) {
/* Get the handle to current decompression context. */
struct archive_read *a = ((IByteIn*)p)->a;
struct zip *zip = (struct zip*) a->format->data;
ssize_t bytes_avail = 0;
/* Fetch next byte. */
const uint8_t* data = __archive_read_ahead(a, 1, NULL);
const uint8_t* data = __archive_read_ahead(a, 1, &bytes_avail);
if(bytes_avail < 1) {
zip->ppmd8_stream_failed = 1;
return 0;
}
__archive_read_consume(a, 1);
/* Increment the counter. */
@ -1750,6 +1757,7 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
/* Create a new decompression context. */
__archive_ppmd8_functions.Ppmd8_Construct(&zip->ppmd8);
zip->ppmd8_stream_failed = 0;
/* Setup function pointers required by Ppmd8 decompressor. The
* 'ppmd_read' function will feed new bytes to the decompressor,
@ -1869,6 +1877,14 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
break;
}
/* This field is set by ppmd_read() when there was no more data
* to be read. */
if(zip->ppmd8_stream_failed) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated PPMd8 file body");
return (ARCHIVE_FATAL);
}
zip->uncompressed_buffer[consumed_bytes] = (uint8_t) sym;
++consumed_bytes;
} while(consumed_bytes < zip->uncompressed_buffer_size);
@ -1902,7 +1918,7 @@ zipx_bzip2_init(struct archive_read *a, struct zip *zip)
{
int r;
/* Deallocate already existing BZ2 decompression context if it
/* Deallocate already existing BZ2 decompression context if it
* exists. */
if(zip->bzstream_valid) {
BZ2_bzDecompressEnd(&zip->bzstream);
@ -1968,6 +1984,15 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
}
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
if(in_bytes < 1) {
/* libbz2 doesn't complain when caller feeds avail_in == 0. It will
* actually return success in this case, which is undesirable. This is
* why we need to make this check manually. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated bzip2 file body");
return (ARCHIVE_FATAL);
}
/* Setup buffer boundaries. */
zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;

View File

@ -1512,8 +1512,10 @@ get_current_codepage(void)
p = strrchr(locale, '.');
if (p == NULL)
return (GetACP());
if (strcmp(p+1, "utf8") == 0)
return CP_UTF8;
cp = my_atoi(p+1);
if (cp <= 0)
if ((int)cp <= 0)
return (GetACP());
return (cp);
}
@ -4050,6 +4052,7 @@ archive_mstring_copy_utf8(struct archive_mstring *aes, const char *utf8)
{
if (utf8 == NULL) {
aes->aes_set = 0;
return (0);
}
aes->aes_set = AES_SET_UTF8;
archive_string_empty(&(aes->aes_mbs));
@ -4064,6 +4067,7 @@ archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs,
{
if (wcs == NULL) {
aes->aes_set = 0;
return (0);
}
aes->aes_set = AES_SET_WCS; /* Only WCS form set. */
archive_string_empty(&(aes->aes_mbs));

View File

@ -2588,8 +2588,11 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
*/
restore_pwd = open(".", O_RDONLY | O_BINARY | O_CLOEXEC);
__archive_ensure_cloexec_flag(restore_pwd);
if (restore_pwd < 0)
if (restore_pwd < 0) {
fsobj_error(a_eno, a_estr, errno,
"Could not open ", path);
return (ARCHIVE_FATAL);
}
head = path;
tail = path;
last = 0;
@ -3128,12 +3131,14 @@ create_dir(struct archive_write_disk *a, char *path)
static int
set_ownership(struct archive_write_disk *a)
{
#ifndef __CYGWIN__
/* unfortunately, on win32 there is no 'root' user with uid 0,
so we just have to try the chown and see if it works */
/* If we know we can't change it, don't bother trying. */
if (a->user_uid != 0 && a->user_uid != a->uid) {
#if !defined(__CYGWIN__) && !defined(__linux__)
/*
* On Linux, a process may have the CAP_CHOWN capability.
* On Windows there is no 'root' user with uid 0.
* Elsewhere we can skip calling chown if we are not root and the desired
* user id does not match the current user.
*/
if (a->user_uid != 0 && a->user_uid != a->uid) {
archive_set_error(&a->archive, errno,
"Can't set UID=%jd", (intmax_t)a->uid);
return (ARCHIVE_WARN);
@ -3500,9 +3505,7 @@ set_fflags(struct archive_write_disk *a)
struct fixup_entry *le;
unsigned long set, clear;
int r;
int critical_flags;
mode_t mode = archive_entry_mode(a->entry);
/*
* Make 'critical_flags' hold all file flags that can't be
* immediately restored. For example, on BSD systems,
@ -3518,33 +3521,33 @@ set_fflags(struct archive_write_disk *a)
* other programs that might try to muck with files as they're
* being restored.
*/
/* Hopefully, the compiler will optimize this mess into a constant. */
critical_flags = 0;
const int critical_flags = 0
#ifdef SF_IMMUTABLE
critical_flags |= SF_IMMUTABLE;
| SF_IMMUTABLE
#endif
#ifdef UF_IMMUTABLE
critical_flags |= UF_IMMUTABLE;
| UF_IMMUTABLE
#endif
#ifdef SF_APPEND
critical_flags |= SF_APPEND;
| SF_APPEND
#endif
#ifdef UF_APPEND
critical_flags |= UF_APPEND;
| UF_APPEND
#endif
#if defined(FS_APPEND_FL)
critical_flags |= FS_APPEND_FL;
| FS_APPEND_FL
#elif defined(EXT2_APPEND_FL)
critical_flags |= EXT2_APPEND_FL;
| EXT2_APPEND_FL
#endif
#if defined(FS_IMMUTABLE_FL)
critical_flags |= FS_IMMUTABLE_FL;
| FS_IMMUTABLE_FL
#elif defined(EXT2_IMMUTABLE_FL)
critical_flags |= EXT2_IMMUTABLE_FL;
| EXT2_IMMUTABLE_FL
#endif
#ifdef FS_JOURNAL_DATA_FL
critical_flags |= FS_JOURNAL_DATA_FL;
| FS_JOURNAL_DATA_FL
#endif
;
if (a->todo & TODO_FFLAGS) {
archive_entry_fflags(a->entry, &set, &clear);
@ -3575,29 +3578,27 @@ set_fflags(struct archive_write_disk *a)
static int
clear_nochange_fflags(struct archive_write_disk *a)
{
int nochange_flags;
mode_t mode = archive_entry_mode(a->entry);
/* Hopefully, the compiler will optimize this mess into a constant. */
nochange_flags = 0;
const int nochange_flags = 0
#ifdef SF_IMMUTABLE
nochange_flags |= SF_IMMUTABLE;
| SF_IMMUTABLE
#endif
#ifdef UF_IMMUTABLE
nochange_flags |= UF_IMMUTABLE;
| UF_IMMUTABLE
#endif
#ifdef SF_APPEND
nochange_flags |= SF_APPEND;
| SF_APPEND
#endif
#ifdef UF_APPEND
nochange_flags |= UF_APPEND;
| UF_APPEND
#endif
#ifdef EXT2_APPEND_FL
nochange_flags |= EXT2_APPEND_FL;
| EXT2_APPEND_FL
#endif
#ifdef EXT2_IMMUTABLE_FL
nochange_flags |= EXT2_IMMUTABLE_FL;
| EXT2_IMMUTABLE_FL
#endif
;
return (set_fflags_platform(a, a->fd, a->name, mode, 0,
nochange_flags));
@ -3613,8 +3614,22 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
mode_t mode, unsigned long set, unsigned long clear)
{
int r;
const int sf_mask = 0
#ifdef SF_APPEND
| SF_APPEND
#endif
#ifdef SF_ARCHIVED
| SF_ARCHIVED
#endif
#ifdef SF_IMMUTABLE
| SF_IMMUTABLE
#endif
#ifdef SF_NOUNLINK
| SF_NOUNLINK
#endif
;
(void)mode; /* UNUSED */
if (set == 0 && clear == 0)
return (ARCHIVE_OK);
@ -3629,6 +3644,12 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
a->st.st_flags &= ~clear;
a->st.st_flags |= set;
/* Only super-user may change SF_* flags */
if (a->user_uid != 0)
a->st.st_flags &= ~sf_mask;
#ifdef HAVE_FCHFLAGS
/* If platform has fchflags() and we were given an fd, use it. */
if (fd >= 0 && fchflags(fd, a->st.st_flags) == 0)
@ -3670,7 +3691,28 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
int ret;
int myfd = fd;
int newflags, oldflags;
int sf_mask = 0;
/*
* Linux has no define for the flags that are only settable by
* the root user. This code may seem a little complex, but
* there seem to be some Linux systems that lack these
* defines. (?) The code below degrades reasonably gracefully
* if sf_mask is incomplete.
*/
const int sf_mask = 0
#if defined(FS_IMMUTABLE_FL)
| FS_IMMUTABLE_FL
#elif defined(EXT2_IMMUTABLE_FL)
| EXT2_IMMUTABLE_FL
#endif
#if defined(FS_APPEND_FL)
| FS_APPEND_FL
#elif defined(EXT2_APPEND_FL)
| EXT2_APPEND_FL
#endif
#if defined(FS_JOURNAL_DATA_FL)
| FS_JOURNAL_DATA_FL
#endif
;
if (set == 0 && clear == 0)
return (ARCHIVE_OK);
@ -3686,26 +3728,6 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
if (myfd < 0)
return (ARCHIVE_OK);
/*
* Linux has no define for the flags that are only settable by
* the root user. This code may seem a little complex, but
* there seem to be some Linux systems that lack these
* defines. (?) The code below degrades reasonably gracefully
* if sf_mask is incomplete.
*/
#if defined(FS_IMMUTABLE_FL)
sf_mask |= FS_IMMUTABLE_FL;
#elif defined(EXT2_IMMUTABLE_FL)
sf_mask |= EXT2_IMMUTABLE_FL;
#endif
#if defined(FS_APPEND_FL)
sf_mask |= FS_APPEND_FL;
#elif defined(EXT2_APPEND_FL)
sf_mask |= EXT2_APPEND_FL;
#endif
#if defined(FS_JOURNAL_DATA_FL)
sf_mask |= FS_JOURNAL_DATA_FL;
#endif
/*
* XXX As above, this would be way simpler if we didn't have
* to read the current flags from disk. XXX

View File

@ -439,7 +439,8 @@ _7z_write_header(struct archive_write *a, struct archive_entry *entry)
r = file_new(a, entry, &file);
if (r < ARCHIVE_WARN) {
file_free(file);
if (file != NULL)
file_free(file);
return (r);
}
if (file->size == 0 && file->dir) {

View File

@ -336,7 +336,7 @@ DEFINE_TEST(test_entry)
/* Converting fflags bitmap to string is currently system-dependent. */
/* TODO: Make this system-independent. */
assertEqualString(archive_entry_fflags_text(e),
"uappnd,nouchg,nodump,noopaque,uunlnk");
"uappnd,nouchg,nodump,noopaque,uunlnk,nosystem");
/* Test archive_entry_copy_fflags_text_w() */
archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,uunlnk");
archive_entry_fflags(e, &set, &clear);

View File

@ -96,7 +96,7 @@ int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) {
int ret = 1;
uint32_t computed_crc;
fsize = archive_entry_size(ae);
fsize = (la_ssize_t) archive_entry_size(ae);
buf = malloc(fsize);
if(buf == NULL)
return 1;
@ -110,13 +110,13 @@ int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) {
computed_crc = crc32(0, buf, fsize);
assertEqualInt(computed_crc, crc);
ret = 0;
fn_exit:
free(buf);
return ret;
}
DEFINE_TEST(test_read_format_rar5_stored)
DEFINE_TEST(test_read_format_rar5_stored)
{
const char helloworld_txt[] = "hello libarchive test suite!\n";
la_ssize_t file_size = sizeof(helloworld_txt) - 1;
@ -143,7 +143,7 @@ DEFINE_TEST(test_read_format_rar5_stored)
DEFINE_TEST(test_read_format_rar5_compressed)
{
const int DATA_SIZE = 1200;
uint8_t buff[DATA_SIZE];
uint8_t buff[1200];
PROLOGUE("test_read_format_rar5_compressed.rar");
@ -161,7 +161,7 @@ DEFINE_TEST(test_read_format_rar5_compressed)
DEFINE_TEST(test_read_format_rar5_multiple_files)
{
const int DATA_SIZE = 4096;
uint8_t buff[DATA_SIZE];
uint8_t buff[4096];
PROLOGUE("test_read_format_rar5_multiple_files.rar");
@ -173,7 +173,7 @@ DEFINE_TEST(test_read_format_rar5_multiple_files)
assertEqualInt(DATA_SIZE, archive_entry_size(ae));
assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
assertA(verify_data(buff, 1, DATA_SIZE));
assertA(0 == archive_read_next_header(a, &ae));
assertEqualString("test2.bin", archive_entry_pathname(ae));
assertEqualInt(DATA_SIZE, archive_entry_size(ae));
@ -207,7 +207,7 @@ DEFINE_TEST(test_read_format_rar5_multiple_files)
DEFINE_TEST(test_read_format_rar5_multiple_files_solid)
{
const int DATA_SIZE = 4096;
uint8_t buff[DATA_SIZE];
uint8_t buff[4096];
PROLOGUE("test_read_format_rar5_multiple_files_solid.rar");
@ -216,7 +216,7 @@ DEFINE_TEST(test_read_format_rar5_multiple_files_solid)
assertEqualInt(DATA_SIZE, archive_entry_size(ae));
assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE));
assertA(verify_data(buff, 1, DATA_SIZE));
assertA(0 == archive_read_next_header(a, &ae));
assertEqualString("test2.bin", archive_entry_pathname(ae));
assertEqualInt(DATA_SIZE, archive_entry_size(ae));
@ -309,7 +309,7 @@ DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_second)
DEFINE_TEST(test_read_format_rar5_blake2)
{
const la_ssize_t proper_size = 814;
uint8_t buf[proper_size];
uint8_t buf[814];
PROLOGUE("test_read_format_rar5_blake2.rar");
assertA(0 == archive_read_next_header(a, &ae));
@ -334,7 +334,7 @@ DEFINE_TEST(test_read_format_rar5_arm_filter)
* test. */
const la_ssize_t proper_size = 90808;
uint8_t buf[proper_size];
uint8_t buf[90808];
PROLOGUE("test_read_format_rar5_arm.rar");
assertA(0 == archive_read_next_header(a, &ae));
@ -598,7 +598,7 @@ DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_last)
EPILOGUE();
}
DEFINE_TEST(test_read_format_rar5_solid_skip_all)
DEFINE_TEST(test_read_format_rar5_solid_skip_all)
{
const char* reffile = "test_read_format_rar5_solid.rar";
@ -623,7 +623,7 @@ DEFINE_TEST(test_read_format_rar5_solid_skip_all)
EPILOGUE();
}
DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first)
DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first)
{
const char* reffile = "test_read_format_rar5_solid.rar";
@ -649,7 +649,7 @@ DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first)
EPILOGUE();
}
DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second)
DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second)
{
const char* reffile = "test_read_format_rar5_solid.rar";

View File

@ -799,7 +799,7 @@ static void verify(unsigned char *d, size_t s,
static void verifyB(unsigned char *d, size_t s) {
struct archive* a;
struct archive_entry *entry = NULL;
la_int64_t buf_size;
size_t buf_size;
unsigned char *buf;
assert((a = archive_read_new()) != NULL);
@ -826,20 +826,20 @@ static void verifyB(unsigned char *d, size_t s) {
// f1, content "onetwothree\n", size 12 bytes
assertA(0 == archive_read_next_header(a, &entry));
buf_size = archive_entry_size(entry);
buf_size = (size_t) archive_entry_size(entry);
assertA(buf_size == 12);
buf = (unsigned char*) malloc(buf_size);
assertA(NULL != buf);
assertA(buf_size == archive_read_data(a, buf, buf_size));
assertA(buf_size == (size_t) archive_read_data(a, buf, buf_size));
free(buf);
// f2, content "fourfivesix\n", size 12 bytes
assertA(0 == archive_read_next_header(a, &entry));
buf_size = archive_entry_size(entry);
buf_size = (size_t) archive_entry_size(entry);
assertA(buf_size == 12);
buf = (unsigned char*) malloc(buf_size);
assertA(NULL != buf);
assertA(buf_size == archive_read_data(a, buf, buf_size));
assertA(buf_size == (size_t) archive_read_data(a, buf, buf_size));
free(buf);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));

View File

@ -37,7 +37,7 @@ int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc)
int ret = 1;
uint32_t computed_crc;
fsize = archive_entry_size(ae);
fsize = (la_ssize_t) archive_entry_size(ae);
buf = malloc(fsize);
if(buf == NULL)
return 1;
@ -759,3 +759,67 @@ DEFINE_TEST(test_read_format_zip_xz_multi_blockread)
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_zip_ppmd8_crash_1)
{
const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx";
struct archive *a;
struct archive_entry *ae;
char buf[64];
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 100));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
/* This file shouldn't be properly decompressed, because it's invalid.
* However, unpacker should return an error during unpacking. Without the
* proper fix, the unpacker was entering an unlimited loop. */
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 1));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_zip_bz2_hang_on_invalid)
{
const char *refname = "test_read_format_zip_bz2_hang.zip";
struct archive *a;
struct archive_entry *ae;
char buf[8];
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
/* The file `refname` is invalid in this case, so this call should fail.
* But it shouldn't crash. */
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_zip_ppmd8_crash_2)
{
const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx";
struct archive *a;
struct archive_entry *ae;
char buf[64];
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
/* The file `refname` is invalid in this case, so this call should fail.
* But it shouldn't crash. */
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,5 @@
begin 644 test_read_format_zip_bz2_hang.zip
M4$L#!)LP,#`,,#`P,#`P,#`P,#`P,#`P,#`$`!P`,#`P,#`P"0`P,#`P,#`P
1,#!U>`L`8(0P,#`P,#`P,#``
`
end

View File

@ -0,0 +1,4 @@
begin 644 test_read_format_zip_ppmd8_crash_1.zipx
K4$L'"(=02P,$\+N.O&*A>*\+."U``$H`````````@``````#````6(0`````
`
end

View File

@ -0,0 +1,4 @@
begin 644 test_read_format_zip_ppmd8_crash_2.zipx
L4$L'"(=02P,$\+N.O&*A>*\+.2U`@$H`````````@``````#````````````
`
end

View File

@ -538,6 +538,7 @@ ${PACKAGE}FILES+= test_read_format_ustar_filename_eucjp.tar.Z.uu
${PACKAGE}FILES+= test_read_format_ustar_filename_koi8r.tar.Z.uu
${PACKAGE}FILES+= test_read_format_warc.warc.uu
${PACKAGE}FILES+= test_read_format_zip.zip.uu
${PACKAGE}FILES+= test_read_format_zip_bz2_hang.zip.uu
${PACKAGE}FILES+= test_read_format_zip_bzip2.zipx.uu
${PACKAGE}FILES+= test_read_format_zip_bzip2_multi.zipx.uu
${PACKAGE}FILES+= test_read_format_zip_comment_stored_1.zip.uu
@ -565,6 +566,8 @@ ${PACKAGE}FILES+= test_read_format_zip_padded1.zip.uu
${PACKAGE}FILES+= test_read_format_zip_padded2.zip.uu
${PACKAGE}FILES+= test_read_format_zip_padded3.zip.uu
${PACKAGE}FILES+= test_read_format_zip_ppmd8.zipx.uu
${PACKAGE}FILES+= test_read_format_zip_ppmd8_crash_1.zipx.uu
${PACKAGE}FILES+= test_read_format_zip_ppmd8_crash_2.zipx.uu
${PACKAGE}FILES+= test_read_format_zip_ppmd8_multi.zipx.uu
${PACKAGE}FILES+= test_read_format_zip_sfx.uu
${PACKAGE}FILES+= test_read_format_zip_symlink.zip.uu