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:
Martin Matuska 2018-01-24 14:24:17 +00:00
commit a2a3407c7e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328332
31 changed files with 232 additions and 94 deletions

View file

@ -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);
}

View 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");
}

View file

@ -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;

View file

@ -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 =

View file

@ -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;

View file

@ -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 */

View file

@ -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

View file

@ -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)

View file

@ -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 ***/

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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");

View file

@ -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,

View file

@ -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));

View file

@ -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);

View file

@ -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));
}

View file

@ -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,

View file

@ -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);
}

View file

@ -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;

View file

@ -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) {

View file

@ -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"

View file

@ -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},

View file

@ -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);
}

View file

@ -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

View file

@ -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));

View file

@ -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");

View file

@ -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 */

View file

@ -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

View file

@ -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 \