MFV r328323,328324:
Sync libarchive with vendor. Relevant vendor changes: PR #893: delete dead ppmd7 alloc callbacks PR #904: Fix archive freeing bug in bsdcat PR #961: Fix ZIP format names PR #962: Don't modify attributes for existing directories when ARCHIVE_EXTRACT_NO_OVERWRITE is set PR #964: Fix -Werror=implicit-fallthrough= for GCC 7 PR #970: zip: Allow backslash as path separator MFC after: 1 week
This commit is contained in:
commit
a2a3407c7e
@ -70,6 +70,12 @@ version(void)
|
||||
void
|
||||
bsdcat_next(void)
|
||||
{
|
||||
if (a != NULL) {
|
||||
if (archive_read_close(a) != ARCHIVE_OK)
|
||||
bsdcat_print_error();
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
a = archive_read_new();
|
||||
archive_read_support_filter_all(a);
|
||||
archive_read_support_format_empty(a);
|
||||
@ -100,8 +106,10 @@ bsdcat_read_to_stdout(const char* filename)
|
||||
;
|
||||
else if (archive_read_data_into_fd(a, 1) != ARCHIVE_OK)
|
||||
bsdcat_print_error();
|
||||
if (archive_read_free(a) != ARCHIVE_OK)
|
||||
if (archive_read_close(a) != ARCHIVE_OK)
|
||||
bsdcat_print_error();
|
||||
archive_read_free(a);
|
||||
a = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
@ -135,15 +143,14 @@ main(int argc, char **argv)
|
||||
if (*bsdcat->argv == NULL) {
|
||||
bsdcat_current_path = "<stdin>";
|
||||
bsdcat_read_to_stdout(NULL);
|
||||
} else
|
||||
} else {
|
||||
while (*bsdcat->argv) {
|
||||
bsdcat_current_path = *bsdcat->argv++;
|
||||
bsdcat_read_to_stdout(bsdcat_current_path);
|
||||
bsdcat_next();
|
||||
}
|
||||
|
||||
if (a != NULL)
|
||||
archive_read_free(a);
|
||||
archive_read_free(a); /* Help valgrind & friends */
|
||||
}
|
||||
|
||||
exit(exit_status);
|
||||
}
|
||||
|
42
contrib/libarchive/cat/test/test_stdin.c
Normal file
42
contrib/libarchive/cat/test/test_stdin.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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"
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define DEV_NULL "/dev/null"
|
||||
#else
|
||||
#define DEV_NULL "NUL"
|
||||
#endif
|
||||
|
||||
DEFINE_TEST(test_stdin)
|
||||
{
|
||||
int f;
|
||||
|
||||
f = systemf("%s <%s >test.out 2>test.err", testprog, DEV_NULL);
|
||||
assertEqualInt(0, f);
|
||||
assertEmptyFile("test.out");
|
||||
assertEmptyFile("test.err");
|
||||
}
|
||||
|
@ -1159,6 +1159,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
switch (want_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
|
||||
want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
__LA_FALLTHROUGH;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
numfields = 5;
|
||||
@ -1626,6 +1627,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
switch (want_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
|
||||
want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
__LA_FALLTHROUGH;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
numfields = 5;
|
||||
|
@ -93,7 +93,9 @@ static const acl_perm_map_t acl_nfs4_flag_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
|
||||
#ifdef ACL_ENTRY_INHERITED
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
|
||||
#endif
|
||||
};
|
||||
|
||||
static const int acl_nfs4_flag_map_size =
|
||||
|
@ -1582,7 +1582,7 @@ time_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
*/
|
||||
|
||||
int
|
||||
archive_match_include_uid(struct archive *_a, int64_t uid)
|
||||
archive_match_include_uid(struct archive *_a, la_int64_t uid)
|
||||
{
|
||||
struct archive_match *a;
|
||||
|
||||
@ -1593,7 +1593,7 @@ archive_match_include_uid(struct archive *_a, int64_t uid)
|
||||
}
|
||||
|
||||
int
|
||||
archive_match_include_gid(struct archive *_a, int64_t gid)
|
||||
archive_match_include_gid(struct archive *_a, la_int64_t gid)
|
||||
{
|
||||
struct archive_match *a;
|
||||
|
||||
|
@ -191,4 +191,10 @@
|
||||
#define ARCHIVE_ERRNO_MISC (-1)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 7)
|
||||
#define __LA_FALLTHROUGH __attribute__((fallthrough))
|
||||
#else
|
||||
#define __LA_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
#endif /* !ARCHIVE_PLATFORM_H_INCLUDED */
|
||||
|
@ -115,14 +115,14 @@ static void Ppmd7_Construct(CPpmd7 *p)
|
||||
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
|
||||
}
|
||||
|
||||
static void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
|
||||
static void Ppmd7_Free(CPpmd7 *p)
|
||||
{
|
||||
alloc->Free(alloc, p->Base);
|
||||
free(p->Base);
|
||||
p->Size = 0;
|
||||
p->Base = 0;
|
||||
}
|
||||
|
||||
static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
|
||||
static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size)
|
||||
{
|
||||
if (p->Base == 0 || p->Size != size)
|
||||
{
|
||||
@ -131,14 +131,14 @@ static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
|
||||
if (size < UNIT_SIZE) {
|
||||
return False;
|
||||
}
|
||||
Ppmd7_Free(p, alloc);
|
||||
Ppmd7_Free(p);
|
||||
p->AlignOffset =
|
||||
#ifdef PPMD_32BIT
|
||||
(4 - size) & 3;
|
||||
#else
|
||||
4 - (size & 3);
|
||||
#endif
|
||||
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
|
||||
if ((p->Base = (Byte *)malloc(p->AlignOffset + size
|
||||
#ifndef PPMD_32BIT
|
||||
+ UNIT_SIZE
|
||||
#endif
|
||||
|
@ -95,8 +95,8 @@ typedef struct
|
||||
{
|
||||
/* Base Functions */
|
||||
void (*Ppmd7_Construct)(CPpmd7 *p);
|
||||
Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
|
||||
void (*Ppmd7_Free)(CPpmd7 *p, ISzAlloc *alloc);
|
||||
Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size);
|
||||
void (*Ppmd7_Free)(CPpmd7 *p);
|
||||
void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
|
||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
|
@ -69,13 +69,6 @@ typedef struct
|
||||
void (*Write)(void *p, Byte b);
|
||||
} IByteOut;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
/*** End defined in Types.h ***/
|
||||
/*** Begin defined in CpuArch.h ***/
|
||||
|
||||
|
@ -120,7 +120,8 @@ archive_read_new(void)
|
||||
* Record the do-not-extract-to file. This belongs in archive_read_extract.c.
|
||||
*/
|
||||
void
|
||||
archive_read_extract_set_skip_file(struct archive *_a, int64_t d, int64_t i)
|
||||
archive_read_extract_set_skip_file(struct archive *_a, la_int64_t d,
|
||||
la_int64_t i)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
@ -747,7 +748,7 @@ choose_format(struct archive_read *a)
|
||||
* Return the file offset (within the uncompressed data stream) where
|
||||
* the last header started.
|
||||
*/
|
||||
int64_t
|
||||
la_int64_t
|
||||
archive_read_header_position(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
@ -943,7 +944,7 @@ archive_read_data_skip(struct archive *_a)
|
||||
return (r);
|
||||
}
|
||||
|
||||
int64_t
|
||||
la_int64_t
|
||||
archive_seek_data(struct archive *_a, int64_t offset, int whence)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
@ -1626,7 +1627,8 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
|
||||
switch (whence) {
|
||||
case SEEK_CUR:
|
||||
/* Adjust the offset and use SEEK_SET instead */
|
||||
offset += filter->position;
|
||||
offset += filter->position;
|
||||
__LA_FALLTHROUGH;
|
||||
case SEEK_SET:
|
||||
cursor = 0;
|
||||
while (1)
|
||||
|
@ -387,7 +387,7 @@ archive_read_disk_vtable(void)
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_read_disk_gname(struct archive *_a, int64_t gid)
|
||||
archive_read_disk_gname(struct archive *_a, la_int64_t gid)
|
||||
{
|
||||
struct archive_read_disk *a = (struct archive_read_disk *)_a;
|
||||
if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
|
||||
@ -399,7 +399,7 @@ archive_read_disk_gname(struct archive *_a, int64_t gid)
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_read_disk_uname(struct archive *_a, int64_t uid)
|
||||
archive_read_disk_uname(struct archive *_a, la_int64_t uid)
|
||||
{
|
||||
struct archive_read_disk *a = (struct archive_read_disk *)_a;
|
||||
if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
|
||||
@ -413,7 +413,7 @@ archive_read_disk_uname(struct archive *_a, int64_t uid)
|
||||
int
|
||||
archive_read_disk_set_gname_lookup(struct archive *_a,
|
||||
void *private_data,
|
||||
const char * (*lookup_gname)(void *private, int64_t gid),
|
||||
const char * (*lookup_gname)(void *private, la_int64_t gid),
|
||||
void (*cleanup_gname)(void *private))
|
||||
{
|
||||
struct archive_read_disk *a = (struct archive_read_disk *)_a;
|
||||
@ -432,7 +432,7 @@ archive_read_disk_set_gname_lookup(struct archive *_a,
|
||||
int
|
||||
archive_read_disk_set_uname_lookup(struct archive *_a,
|
||||
void *private_data,
|
||||
const char * (*lookup_uname)(void *private, int64_t uid),
|
||||
const char * (*lookup_uname)(void *private, la_int64_t uid),
|
||||
void (*cleanup_uname)(void *private))
|
||||
{
|
||||
struct archive_read_disk *a = (struct archive_read_disk *)_a;
|
||||
|
@ -975,18 +975,6 @@ decode_codec_id(const unsigned char *codecId, size_t id_size)
|
||||
return (id);
|
||||
}
|
||||
|
||||
static void *
|
||||
ppmd_alloc(void *p, size_t size)
|
||||
{
|
||||
(void)p;
|
||||
return malloc(size);
|
||||
}
|
||||
static void
|
||||
ppmd_free(void *p, void *address)
|
||||
{
|
||||
(void)p;
|
||||
free(address);
|
||||
}
|
||||
static Byte
|
||||
ppmd_read(void *p)
|
||||
{
|
||||
@ -1006,8 +994,6 @@ ppmd_read(void *p)
|
||||
return (b);
|
||||
}
|
||||
|
||||
static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
|
||||
|
||||
static int
|
||||
init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
const struct _7z_coder *coder1, const struct _7z_coder *coder2)
|
||||
@ -1237,7 +1223,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
|
||||
if (zip->ppmd7_valid) {
|
||||
__archive_ppmd7_functions.Ppmd7_Free(
|
||||
&zip->ppmd7_context, &g_szalloc);
|
||||
&zip->ppmd7_context);
|
||||
zip->ppmd7_valid = 0;
|
||||
}
|
||||
|
||||
@ -1256,7 +1242,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
}
|
||||
__archive_ppmd7_functions.Ppmd7_Construct(&zip->ppmd7_context);
|
||||
r = __archive_ppmd7_functions.Ppmd7_Alloc(
|
||||
&zip->ppmd7_context, msize, &g_szalloc);
|
||||
&zip->ppmd7_context, msize);
|
||||
if (r == 0) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Coludn't allocate memory for PPMd");
|
||||
@ -1636,7 +1622,7 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
|
||||
#endif
|
||||
if (zip->ppmd7_valid) {
|
||||
__archive_ppmd7_functions.Ppmd7_Free(
|
||||
&zip->ppmd7_context, &g_szalloc);
|
||||
&zip->ppmd7_context);
|
||||
zip->ppmd7_valid = 0;
|
||||
}
|
||||
return (r);
|
||||
@ -2569,6 +2555,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
|
||||
case kDummy:
|
||||
if (ll == 0)
|
||||
break;
|
||||
__LA_FALLTHROUGH;
|
||||
default:
|
||||
if (header_bytes(a, ll) == NULL)
|
||||
return (-1);
|
||||
|
@ -1499,6 +1499,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
}
|
||||
if (strcmp(key, "cksum") == 0)
|
||||
break;
|
||||
__LA_FALLTHROUGH;
|
||||
case 'd':
|
||||
if (strcmp(key, "device") == 0) {
|
||||
/* stat(2) st_rdev field, e.g. the major/minor IDs
|
||||
@ -1512,12 +1513,14 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
archive_entry_set_rdev(entry, dev);
|
||||
return r;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'f':
|
||||
if (strcmp(key, "flags") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_FFLAGS;
|
||||
archive_entry_copy_fflags_text(entry, val);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'g':
|
||||
if (strcmp(key, "gid") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_GID;
|
||||
@ -1529,16 +1532,19 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
archive_entry_copy_gname(entry, val);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'i':
|
||||
if (strcmp(key, "inode") == 0) {
|
||||
archive_entry_set_ino(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'l':
|
||||
if (strcmp(key, "link") == 0) {
|
||||
archive_entry_copy_symlink(entry, val);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'm':
|
||||
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
|
||||
break;
|
||||
@ -1555,6 +1561,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
}
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'n':
|
||||
if (strcmp(key, "nlink") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_NLINK;
|
||||
@ -1562,6 +1569,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
(unsigned int)mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'r':
|
||||
if (strcmp(key, "resdevice") == 0) {
|
||||
/* stat(2) st_dev field, e.g. the device ID where the
|
||||
@ -1577,6 +1585,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
if (strcmp(key, "rmd160") == 0 ||
|
||||
strcmp(key, "rmd160digest") == 0)
|
||||
break;
|
||||
__LA_FALLTHROUGH;
|
||||
case 's':
|
||||
if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
|
||||
break;
|
||||
@ -1593,6 +1602,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
archive_entry_set_size(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 't':
|
||||
if (strcmp(key, "tags") == 0) {
|
||||
/*
|
||||
@ -1635,18 +1645,21 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
archive_entry_set_filetype(entry, AE_IFBLK);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'c':
|
||||
if (strcmp(val, "char") == 0) {
|
||||
archive_entry_set_filetype(entry,
|
||||
AE_IFCHR);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'd':
|
||||
if (strcmp(val, "dir") == 0) {
|
||||
archive_entry_set_filetype(entry,
|
||||
AE_IFDIR);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'f':
|
||||
if (strcmp(val, "fifo") == 0) {
|
||||
archive_entry_set_filetype(entry,
|
||||
@ -1658,12 +1671,14 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
AE_IFREG);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'l':
|
||||
if (strcmp(val, "link") == 0) {
|
||||
archive_entry_set_filetype(entry,
|
||||
AE_IFLNK);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
default:
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -1675,6 +1690,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
*parsed_kws |= MTREE_HAS_TYPE;
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'u':
|
||||
if (strcmp(key, "uid") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_UID;
|
||||
@ -1686,6 +1702,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
archive_entry_copy_uname(entry, val);
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Unrecognized key %s=%s", key, val);
|
||||
|
@ -604,20 +604,6 @@ lzss_emit_match(struct rar *rar, int offset, int length)
|
||||
rar->lzss.position += length;
|
||||
}
|
||||
|
||||
static void *
|
||||
ppmd_alloc(void *p, size_t size)
|
||||
{
|
||||
(void)p;
|
||||
return malloc(size);
|
||||
}
|
||||
static void
|
||||
ppmd_free(void *p, void *address)
|
||||
{
|
||||
(void)p;
|
||||
free(address);
|
||||
}
|
||||
static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
|
||||
|
||||
static Byte
|
||||
ppmd_read(void *p)
|
||||
{
|
||||
@ -1038,7 +1024,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||
case COMPRESS_METHOD_BEST:
|
||||
ret = read_data_compressed(a, buff, size, offset);
|
||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1253,7 +1239,7 @@ archive_read_format_rar_cleanup(struct archive_read *a)
|
||||
free(rar->dbo);
|
||||
free(rar->unp_buffer);
|
||||
free(rar->lzss.window);
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
free(rar);
|
||||
(a->format->data) = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
@ -1658,7 +1644,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
rar->unp_offset = 0;
|
||||
rar->unp_buffer_size = UNP_BUFFER_SIZE;
|
||||
memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
rar->ppmd_valid = rar->ppmd_eod = 0;
|
||||
|
||||
/* Don't set any archive entries for non-file header types */
|
||||
@ -2122,7 +2108,7 @@ parse_codes(struct archive_read *a)
|
||||
|
||||
/* Make sure ppmd7_contest is freed before Ppmd7_Construct
|
||||
* because reading a broken file cause this abnormal sequence. */
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
|
||||
rar->bytein.a = a;
|
||||
rar->bytein.Read = &ppmd_read;
|
||||
@ -2137,7 +2123,7 @@ parse_codes(struct archive_read *a)
|
||||
}
|
||||
|
||||
if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
|
||||
rar->dictionary_size, &g_szalloc))
|
||||
rar->dictionary_size))
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Out of memory");
|
||||
|
@ -251,15 +251,15 @@ archive_read_support_format_tar(struct archive *_a)
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
|
||||
|
||||
tar = (struct tar *)calloc(1, sizeof(*tar));
|
||||
#ifdef HAVE_COPYFILE_H
|
||||
/* Set this by default on Mac OS. */
|
||||
tar->process_mac_extensions = 1;
|
||||
#endif
|
||||
if (tar == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate tar data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#ifdef HAVE_COPYFILE_H
|
||||
/* Set this by default on Mac OS. */
|
||||
tar->process_mac_extensions = 1;
|
||||
#endif
|
||||
|
||||
r = __archive_read_register_format(a, tar, "tar",
|
||||
archive_read_format_tar_bid,
|
||||
|
@ -886,6 +886,24 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
zip_entry->mode |= 0664;
|
||||
}
|
||||
|
||||
/* Windows archivers sometimes use backslash as the directory separator.
|
||||
Normalize to slash. */
|
||||
if (zip_entry->system == 0 &&
|
||||
(wp = archive_entry_pathname_w(entry)) != NULL) {
|
||||
if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) {
|
||||
size_t i;
|
||||
struct archive_wstring s;
|
||||
archive_string_init(&s);
|
||||
archive_wstrcpy(&s, wp);
|
||||
for (i = 0; i < archive_strlen(&s); i++) {
|
||||
if (s.s[i] == '\\')
|
||||
s.s[i] = '/';
|
||||
}
|
||||
archive_entry_copy_pathname_w(entry, s.s);
|
||||
archive_wstring_free(&s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure that entries with a trailing '/' are marked as directories
|
||||
* even if the External File Attributes contains bogus values. If this
|
||||
* is not a directory and there is no type, assume regularfile. */
|
||||
@ -1061,6 +1079,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
zip->end_of_entry = 1;
|
||||
|
||||
/* Set up a more descriptive format name. */
|
||||
archive_string_empty(&zip->format_name);
|
||||
archive_string_sprintf(&zip->format_name, "ZIP %d.%d (%s)",
|
||||
version / 10, version % 10,
|
||||
compression_name(zip->entry->compression));
|
||||
|
@ -140,7 +140,7 @@ archive_compression_name(struct archive *a)
|
||||
/*
|
||||
* Return a count of the number of compressed bytes processed.
|
||||
*/
|
||||
int64_t
|
||||
la_int64_t
|
||||
archive_position_compressed(struct archive *a)
|
||||
{
|
||||
return archive_filter_bytes(a, -1);
|
||||
@ -149,7 +149,7 @@ archive_position_compressed(struct archive *a)
|
||||
/*
|
||||
* Return a count of the number of uncompressed bytes processed.
|
||||
*/
|
||||
int64_t
|
||||
la_int64_t
|
||||
archive_position_uncompressed(struct archive *a)
|
||||
{
|
||||
return archive_filter_bytes(a, 0);
|
||||
|
@ -48,7 +48,7 @@ archive_filter_name(struct archive *a, int n)
|
||||
return ((a->vtable->archive_filter_name)(a, n));
|
||||
}
|
||||
|
||||
int64_t
|
||||
la_int64_t
|
||||
archive_filter_bytes(struct archive *a, int n)
|
||||
{
|
||||
return ((a->vtable->archive_filter_bytes)(a, n));
|
||||
@ -131,7 +131,8 @@ archive_write_data(struct archive *a, const void *buff, size_t s)
|
||||
}
|
||||
|
||||
ssize_t
|
||||
archive_write_data_block(struct archive *a, const void *buff, size_t s, int64_t o)
|
||||
archive_write_data_block(struct archive *a, const void *buff, size_t s,
|
||||
la_int64_t o)
|
||||
{
|
||||
if (a->vtable->archive_write_data_block == NULL) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
@ -156,7 +157,7 @@ archive_read_next_header2(struct archive *a, struct archive_entry *entry)
|
||||
|
||||
int
|
||||
archive_read_data_block(struct archive *a,
|
||||
const void **buff, size_t *s, int64_t *o)
|
||||
const void **buff, size_t *s, la_int64_t *o)
|
||||
{
|
||||
return ((a->vtable->archive_read_data_block)(a, buff, s, o));
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ archive_write_get_bytes_in_last_block(struct archive *_a)
|
||||
* an archive to itself recursively.
|
||||
*/
|
||||
int
|
||||
archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
|
||||
archive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)_a;
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||
|
@ -835,7 +835,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
|
||||
archive_write_disk_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
|
||||
{
|
||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
||||
@ -1786,7 +1786,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
int
|
||||
archive_write_disk_set_group_lookup(struct archive *_a,
|
||||
void *private_data,
|
||||
int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
|
||||
la_int64_t (*lookup_gid)(void *private, const char *gname, la_int64_t gid),
|
||||
void (*cleanup_gid)(void *private))
|
||||
{
|
||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
||||
@ -1822,7 +1822,7 @@ archive_write_disk_set_user_lookup(struct archive *_a,
|
||||
}
|
||||
|
||||
int64_t
|
||||
archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
|
||||
archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id)
|
||||
{
|
||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
||||
@ -1833,7 +1833,7 @@ archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
|
||||
}
|
||||
|
||||
int64_t
|
||||
archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
|
||||
archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id)
|
||||
{
|
||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
||||
@ -1981,6 +1981,10 @@ restore_entry(struct archive_write_disk *a)
|
||||
if ((en == EISDIR || en == EEXIST)
|
||||
&& (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
|
||||
/* If we're not overwriting, we're done. */
|
||||
if (S_ISDIR(a->mode)) {
|
||||
/* Don't overwrite any settings on existing directories. */
|
||||
a->todo = 0;
|
||||
}
|
||||
archive_entry_unset_size(a->entry);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
@ -2095,19 +2095,6 @@ compression_init_encoder_lzma2(struct archive *a,
|
||||
/*
|
||||
* _7_PPMD compressor.
|
||||
*/
|
||||
static void *
|
||||
ppmd_alloc(void *p, size_t size)
|
||||
{
|
||||
(void)p;
|
||||
return malloc(size);
|
||||
}
|
||||
static void
|
||||
ppmd_free(void *p, void *address)
|
||||
{
|
||||
(void)p;
|
||||
free(address);
|
||||
}
|
||||
static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
|
||||
static void
|
||||
ppmd_write(void *p, Byte b)
|
||||
{
|
||||
@ -2167,7 +2154,7 @@ compression_init_encoder_ppmd(struct archive *a,
|
||||
archive_le32enc(props+1, msize);
|
||||
__archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
|
||||
r = __archive_ppmd7_functions.Ppmd7_Alloc(
|
||||
&strm->ppmd7_context, msize, &g_szalloc);
|
||||
&strm->ppmd7_context, msize);
|
||||
if (r == 0) {
|
||||
free(strm->buff);
|
||||
free(strm);
|
||||
@ -2243,7 +2230,7 @@ compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
strm = (struct ppmd_stream *)lastrm->real_stream;
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context, &g_szalloc);
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context);
|
||||
free(strm->buff);
|
||||
free(strm);
|
||||
lastrm->real_stream = NULL;
|
||||
|
@ -91,9 +91,11 @@ read_open_memory_internal(struct archive *a, const void *buff,
|
||||
switch (level) {
|
||||
case 3:
|
||||
archive_read_set_seek_callback(a, memory_read_seek);
|
||||
__LA_FALLTHROUGH;
|
||||
case 2:
|
||||
archive_read_set_open_callback(a, memory_read_open);
|
||||
archive_read_set_skip_callback(a, memory_read_skip);
|
||||
__LA_FALLTHROUGH;
|
||||
case 1:
|
||||
mine = malloc(sizeof(*mine));
|
||||
if (mine == NULL) {
|
||||
|
@ -33,4 +33,10 @@
|
||||
#define EXTRA_ERRNO(x) archive_errno((struct archive *)(x))
|
||||
#define EXTRA_VERSION archive_version_details()
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 7)
|
||||
#define __LA_FALLTHROUGH __attribute__((fallthrough))
|
||||
#else
|
||||
#define __LA_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
#include "test_common.h"
|
||||
|
@ -408,7 +408,9 @@ acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE}
|
||||
#else /* FreeBSD NFSv4 ACL inheritance flags */
|
||||
#ifdef ACL_ENTRY_INHERITED
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
|
||||
#endif
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
|
@ -422,3 +422,29 @@ DEFINE_TEST(test_compat_zip_7)
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* A file with backslash path separators instead of slashes.
|
||||
* PowerShell's Compress-Archive cmdlet produces such archives.
|
||||
*/
|
||||
DEFINE_TEST(test_compat_zip_8)
|
||||
{
|
||||
const char *refname = "test_compat_zip_8.zip";
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
void *p;
|
||||
size_t s;
|
||||
|
||||
extract_reference_file(refname);
|
||||
p = slurpfile(&s, refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, 7));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
/* This file is in the archive as arc\test */
|
||||
assertEqualString("arc/test", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
free(p);
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
begin 666 test_compat_zip_8.zip
|
||||
M4$L#!!0````(`%A\;TOY6""D$`````X````(````87)C7'1E<W3[_Z^$(96A
|
||||
MF*&$@9>!BP$`4$L!`A0`%`````@`6'QO2_E8(*00````#@````@`````````
|
||||
H`````````````&%R8UQT97-T4$L%!@`````!``$`-@```#8`````````
|
||||
`
|
||||
end
|
@ -41,6 +41,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
int64_t o;
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a));
|
||||
assertEqualString("dir/", archive_entry_pathname(ae));
|
||||
assertEqualInt(1179604249, archive_entry_mtime(ae));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
@ -53,6 +54,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
assertEqualInt((int)s, 0);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
assertEqualString("file1", archive_entry_pathname(ae));
|
||||
assertEqualInt(1179604289, archive_entry_mtime(ae));
|
||||
if (seek_checks)
|
||||
@ -72,6 +74,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
}
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
assertEqualString("file2", archive_entry_pathname(ae));
|
||||
assertEqualInt(1179605932, archive_entry_mtime(ae));
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
@ -93,6 +96,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
assert(archive_errno(a) != 0);
|
||||
}
|
||||
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
/* Verify the number of files read. */
|
||||
failure("the archive file has three files");
|
||||
assertEqualInt(3, archive_file_count(a));
|
||||
|
@ -131,6 +131,8 @@ DEFINE_TEST(test_write_disk_perms)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct stat st;
|
||||
uid_t original_uid;
|
||||
uid_t try_to_change_uid;
|
||||
|
||||
assertUmask(UMASK);
|
||||
|
||||
@ -201,6 +203,37 @@ DEFINE_TEST(test_write_disk_perms)
|
||||
failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode);
|
||||
assertEqualInt(st.st_mode & 0777, 0744);
|
||||
|
||||
/* For dir, the owner should get left when not overwritting. */
|
||||
assertMakeDir("dir_owner", 0744);
|
||||
|
||||
if (getuid() == 0) {
|
||||
original_uid = getuid() + 1;
|
||||
try_to_change_uid = getuid();
|
||||
assertEqualInt(0, chown("dir_owner", original_uid, getgid()));
|
||||
} else {
|
||||
original_uid = getuid();
|
||||
try_to_change_uid = getuid() + 1;
|
||||
}
|
||||
|
||||
/* Check original owner. */
|
||||
assertEqualInt(0, stat("dir_owner", &st));
|
||||
failure("dir_owner: st.st_uid=%d", st.st_uid);
|
||||
assertEqualInt(st.st_uid, original_uid);
|
||||
/* Shouldn't try to edit the owner when no overwrite option is set. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "dir_owner");
|
||||
archive_entry_set_mode(ae, S_IFDIR | 0744);
|
||||
archive_entry_set_uid(ae, try_to_change_uid);
|
||||
archive_write_disk_set_options(a,
|
||||
ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_NO_OVERWRITE);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
archive_entry_free(ae);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a));
|
||||
/* Make sure they're unchanged. */
|
||||
assertEqualInt(0, stat("dir_owner", &st));
|
||||
failure("dir_owner: st.st_uid=%d", st.st_uid);
|
||||
assertEqualInt(st.st_uid, original_uid);
|
||||
|
||||
/* Write a regular file with SUID bit, but don't use _EXTRACT_PERM. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "file_no_suid");
|
||||
|
@ -85,7 +85,9 @@ static const acl_flag_t acl_flags[] = {
|
||||
ACL_ENTRY_INHERIT_ONLY,
|
||||
ACL_ENTRY_SUCCESSFUL_ACCESS,
|
||||
ACL_ENTRY_FAILED_ACCESS,
|
||||
#ifdef ACL_ENTRY_INHERITED
|
||||
ACL_ENTRY_INHERITED
|
||||
#endif
|
||||
#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */
|
||||
};
|
||||
#endif /* ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_FREEBSD_NFS4 */
|
||||
|
@ -375,6 +375,7 @@ ${PACKAGE}FILES+= test_compat_zip_4.zip.uu
|
||||
${PACKAGE}FILES+= test_compat_zip_5.zip.uu
|
||||
${PACKAGE}FILES+= test_compat_zip_6.zip.uu
|
||||
${PACKAGE}FILES+= test_compat_zip_7.xps.uu
|
||||
${PACKAGE}FILES+= test_compat_zip_8.zip.uu
|
||||
${PACKAGE}FILES+= test_compat_zstd_1.tar.zst.uu
|
||||
${PACKAGE}FILES+= test_fuzz.cab.uu
|
||||
${PACKAGE}FILES+= test_fuzz.lzh.uu
|
||||
|
@ -40,6 +40,7 @@ TESTS_SRCS= \
|
||||
test_expand_xz.c \
|
||||
test_expand_zstd.c \
|
||||
test_help.c \
|
||||
test_stdin.c \
|
||||
test_version.c
|
||||
|
||||
SRCS.bsdcat_test= list.h \
|
||||
|
Loading…
Reference in New Issue
Block a user