31 changes: 25 additions & 6 deletions libarchive/archive_read_support_format_mtree.c
Expand Up @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
#include "archive_read_private.h"
#include "archive_string.h"
#include "archive_pack_dev.h"
#include "archive_entry_private.h"

#ifndef O_BINARY
#define O_BINARY 0
Expand All @@ -75,6 +76,23 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
#define MTREE_HAS_OPTIONAL 0x0800
#define MTREE_HAS_NOCHANGE 0x1000 /* FreeBSD specific */

struct links_entry {
struct links_entry *next;
struct links_entry *previous;
struct archive_entry *canonical;
struct archive_entry *entry;
size_t hash;
unsigned int links; /* # links not yet seen */
};

struct archive_entry_linkresolver {
struct links_entry **buckets;
struct links_entry *spare;
unsigned long number_entries;
size_t number_buckets;
int strategy;
};

struct mtree_option {
struct mtree_option *next;
char *value;
Expand Down Expand Up @@ -216,7 +234,7 @@ free_options(struct mtree_option *head)
int
archive_read_support_format_mtree(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
struct mtree *mtree;
int r;

Expand All @@ -233,7 +251,7 @@ archive_read_support_format_mtree(struct archive *_a)
mtree->fd = -1;

r = __archive_read_register_format(a, mtree, "mtree",
mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, 0, cleanup, 0, 0);

if (r != ARCHIVE_OK)
free(mtree);
Expand Down Expand Up @@ -553,7 +571,7 @@ bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
* Skip the path-name which is quoted.
*/
for (;pp < pp_end; ++pp) {
if (!safe_char[*(const unsigned char *)pp]) {
if (!safe_char[*(const unsigned char *)(void *)pp]) {
if (*pp != ' ' && *pp != '\t' && *pp != '\r'
&& *pp != '\n')
f = 0;
Expand All @@ -580,7 +598,7 @@ bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)

slash = 0;
while (p <= --pb && *pb != ' ' && *pb != '\t') {
if (!safe_char[*(const unsigned char *)pb])
if (!safe_char[*(const unsigned char *)(void *)pb])
return (-1);
name_len++;
/* The pathname should have a slash in this
Expand Down Expand Up @@ -1094,7 +1112,8 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
{
const char *path;
struct stat st_storage, *st;
struct stat st_storage;
struct stat *st;
struct mtree_entry *mp;
struct archive_entry *sparse_entry;
int r = ARCHIVE_OK, r1, parsed_kws;
Expand Down Expand Up @@ -1382,7 +1401,7 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
* Decode and pack it accordingly.
*/
*dev++ = '\0';
if ((pack = pack_find(val)) == NULL) {
if ((pack = pack_find(val)) == 0) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
"Unknown format `%s'", val);
return ARCHIVE_WARN;
Expand Down
45 changes: 26 additions & 19 deletions libarchive/archive_read_support_format_rar.c
Expand Up @@ -45,6 +45,7 @@
#include "archive_ppmd7_private.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_entry_private.h"

/* RAR signature, also known as the mark header */
#define RAR_SIGNATURE "\x52\x61\x72\x21\x1A\x07\x00"
Expand Down Expand Up @@ -207,6 +208,20 @@ struct data_block_offsets
int64_t end_offset;
};

/*
* Bit stream reader.
*/
struct rar_br {
#define CACHE_TYPE uint64_t
#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
/* Cache buffer. */
CACHE_TYPE cache_buffer;
/* Indicates how many bits avail in cache_buffer. */
int cache_avail;
ssize_t avail_in;
const unsigned char *next_in;
};

struct rar
{
/* Entries from main RAR header */
Expand Down Expand Up @@ -296,16 +311,7 @@ struct rar
/*
* Bit stream reader.
*/
struct rar_br {
#define CACHE_TYPE uint64_t
#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
/* Cache buffer. */
CACHE_TYPE cache_buffer;
/* Indicates how many bits avail in cache_buffer. */
int cache_avail;
ssize_t avail_in;
const unsigned char *next_in;
} br;
struct rar_br br;

/*
* Custom field to denote that this archive contains encrypted entries
Expand Down Expand Up @@ -608,7 +614,7 @@ static void *
ppmd_alloc(void *p, size_t size)
{
(void)p;
return malloc(size);
return (CPpmd7 *)malloc(size);
}
static void
ppmd_free(void *p, void *address)
Expand Down Expand Up @@ -640,7 +646,7 @@ ppmd_read(void *p)
int
archive_read_support_format_rar(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
struct rar *rar;
int r;

Expand Down Expand Up @@ -688,7 +694,7 @@ archive_read_support_format_rar_capabilities(struct archive_read * a)
}

static int
archive_read_format_rar_has_encrypted_entries(struct archive_read *_a)
archive_read_format_rar_has_encrypted_entries(struct archive_read * _a)
{
if (_a && _a->format) {
struct rar * rar = (struct rar *)_a->format->data;
Expand Down Expand Up @@ -919,7 +925,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}

crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
crc32_val = crc32(0, (const unsigned char *)(void *)p + 2, (unsigned)skip - 2);
if ((crc32_val & 0xffff) != archive_le16dec(p)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Header CRC error");
Expand Down Expand Up @@ -974,7 +980,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}
p = h;
crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned)did_read);
crc32_val = crc32(crc32_val, (const unsigned char *)(void *)p, (unsigned)did_read);
__archive_read_consume(a, did_read);
skip -= did_read;
}
Expand Down Expand Up @@ -1306,7 +1312,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
"Invalid header size");
return (ARCHIVE_FATAL);
}
crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2);
crc32_val = crc32(0, (const unsigned char *)(void *)p + 2, 7 - 2);
__archive_read_consume(a, 7);

if (!(rar->file_flags & FHD_SOLID))
Expand Down Expand Up @@ -2063,7 +2069,8 @@ static int
parse_codes(struct archive_read *a)
{
int i, j, val, n, r;
unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags;
unsigned char bitlengths[MAX_SYMBOLS];
unsigned char zerocount, ppmd_flags;
unsigned int maxorder;
struct huffman_code precode;
struct rar *rar = (struct rar *)(a->format->data);
Expand Down Expand Up @@ -2558,7 +2565,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
static int
new_node(struct huffman_code *code)
{
void *new_tree;
struct huffman_tree_node * new_tree;
if (code->numallocatedentries == code->numentries) {
int new_num_entries = 256;
if (code->numentries > 0) {
Expand All @@ -2567,7 +2574,7 @@ new_node(struct huffman_code *code)
new_tree = realloc(code->tree, new_num_entries * sizeof(*code->tree));
if (new_tree == NULL)
return (-1);
code->tree = (struct huffman_tree_node *)new_tree;
code->tree = new_tree;
code->numallocatedentries = new_num_entries;
}
code->tree[code->numentries].branches[0] = -1;
Expand Down
11 changes: 6 additions & 5 deletions libarchive/archive_read_support_format_raw.c
Expand Up @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_raw.c 201107
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_entry_private.h"

struct raw_info {
int64_t offset; /* Current position in the file. */
Expand All @@ -56,7 +57,7 @@ int
archive_read_support_format_raw(struct archive *_a)
{
struct raw_info *info;
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
int r;

archive_check_magic(_a, ARCHIVE_READ_MAGIC,
Expand All @@ -73,14 +74,14 @@ archive_read_support_format_raw(struct archive *_a)
info,
"raw",
archive_read_format_raw_bid,
NULL,
0,
archive_read_format_raw_read_header,
archive_read_format_raw_read_data,
archive_read_format_raw_read_data_skip,
NULL,
0,
archive_read_format_raw_cleanup,
NULL,
NULL);
0,
0);
if (r != ARCHIVE_OK)
free(info);
return (r);
Expand Down
164 changes: 54 additions & 110 deletions libarchive/archive_read_support_format_tar.c
Expand Up @@ -44,68 +44,11 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_entry_private.h"
#include <archive_read_support_format_tar_private.h>

#define tar_min(a,b) ((a) < (b) ? (a) : (b))

/*
* Layout of POSIX 'ustar' tar header.
*/
struct archive_entry_header_ustar {
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char checksum[8];
char typeflag[1];
char linkname[100]; /* "old format" header ends here */
char magic[6]; /* For POSIX: "ustar\0" */
char version[2]; /* For POSIX: "00" */
char uname[32];
char gname[32];
char rdevmajor[8];
char rdevminor[8];
char prefix[155];
};

/*
* Structure of GNU tar header
*/
struct gnu_sparse {
char offset[12];
char numbytes[12];
};

struct archive_entry_header_gnutar {
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char checksum[8];
char typeflag[1];
char linkname[100];
char magic[8]; /* "ustar \0" (note blank/blank/null at end) */
char uname[32];
char gname[32];
char rdevmajor[8];
char rdevminor[8];
char atime[12];
char ctime[12];
char offset[12];
char longnames[4];
char unused[1];
struct gnu_sparse sparse[4];
char isextended[1];
char realsize[12];
/*
* Old GNU format doesn't use POSIX 'prefix' field; they use
* the 'L' (longname) entry instead.
*/
};

/*
* Data specific to this format.
*/
Expand Down Expand Up @@ -236,7 +179,7 @@ archive_read_support_format_gnutar(struct archive *a)
int
archive_read_support_format_tar(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
struct tar *tar;
int r;

Expand All @@ -260,10 +203,10 @@ archive_read_support_format_tar(struct archive *_a)
archive_read_format_tar_read_header,
archive_read_format_tar_read_data,
archive_read_format_tar_skip,
NULL,
0,
archive_read_format_tar_cleanup,
NULL,
NULL);
0,
0);

if (r != ARCHIVE_OK)
free(tar);
Expand Down Expand Up @@ -326,7 +269,7 @@ archive_read_format_tar_bid(struct archive_read *a, int best_bid)
return (0);
bid += 48; /* Checksum is usually 6 octal digits. */

header = (const struct archive_entry_header_ustar *)h;
header = to_archive_entry_header_ustar_ptr(h);

/* Recognize POSIX formats. */
if ((memcmp(header->magic, "ustar\0", 6) == 0)
Expand Down Expand Up @@ -710,7 +653,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
}

/* Determine the format variant. */
header = (const struct archive_entry_header_ustar *)h;
header = to_archive_entry_header_ustar_ptr(h);

switch(header->typeflag[0]) {
case 'A': /* Solaris tar ACL */
Expand Down Expand Up @@ -746,7 +689,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
err = header_pax_extensions(a, tar, entry, h, unconsumed);
break;
default:
gnuheader = (const struct archive_entry_header_gnutar *)h;
gnuheader = to_archive_entry_header_gnutar_ptr(h);
if (memcmp(gnuheader->magic, "ustar \0", 8) == 0) {
a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
a->archive.archive_format_name = "GNU tar format";
Expand All @@ -769,7 +712,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
tar_flush_unconsumed(a, unconsumed);

h = NULL;
header = NULL;
header = (struct archive_entry_header_ustar *)NULL;

--tar->header_recursion_depth;
/* Yuck. Apple's design here ends up storing long pathname
Expand Down Expand Up @@ -825,8 +768,8 @@ checksum(struct archive_read *a, const void *h)
size_t i;

(void)a; /* UNUSED */
bytes = (const unsigned char *)h;
header = (const struct archive_entry_header_ustar *)h;
bytes = to_unsigned_char_ptr(h);
header = to_archive_entry_header_ustar_ptr(h);

/* Checksum field must hold an octal number */
for (i = 0; i < sizeof(header->checksum); ++i) {
Expand All @@ -839,7 +782,7 @@ checksum(struct archive_read *a, const void *h)
* Test the checksum. Note that POSIX specifies _unsigned_
* bytes for this calculation.
*/
sum = (int)tar_atol(header->checksum, sizeof(header->checksum));
sum = (int)tar_atol((char *)header->checksum, sizeof(header->checksum));
check = 0;
for (i = 0; i < 148; i++)
check += (unsigned char)bytes[i];
Expand Down Expand Up @@ -899,8 +842,8 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
* read_body_to_string adds a NUL terminator, but we need a little
* more to make sure that we don't overrun acl_text later.
*/
header = (const struct archive_entry_header_ustar *)h;
size = (size_t)tar_atol(header->size, sizeof(header->size));
header = to_archive_entry_header_ustar_ptr(h);
size = (size_t)tar_atol((char *)header->size, sizeof(header->size));
err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
Expand Down Expand Up @@ -1065,8 +1008,8 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
const void *src;

(void)tar; /* UNUSED */
header = (const struct archive_entry_header_ustar *)h;
size = tar_atol(header->size, sizeof(header->size));
header = to_archive_entry_header_ustar_ptr(h);
size = tar_atol((char *)header->size, sizeof(header->size));
if ((size > 1048576) || (size < 0)) {
archive_set_error(&a->archive, EINVAL,
"Special header too large");
Expand Down Expand Up @@ -1113,19 +1056,19 @@ header_common(struct archive_read *a, struct tar *tar,
char tartype;
int err = ARCHIVE_OK;

header = (const struct archive_entry_header_ustar *)h;
header = to_archive_entry_header_ustar_ptr(h);
if (header->linkname[0])
archive_strncpy(&(tar->entry_linkpath),
header->linkname, sizeof(header->linkname));
(char *)header->linkname, sizeof(header->linkname));
else
archive_string_empty(&(tar->entry_linkpath));

/* Parse out the numeric fields (all are octal) */
archive_entry_set_mode(entry,
(mode_t)tar_atol(header->mode, sizeof(header->mode)));
archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
(mode_t)tar_atol((char *)header->mode, sizeof(header->mode)));
archive_entry_set_uid(entry, tar_atol((char *)header->uid, sizeof(header->uid)));
archive_entry_set_gid(entry, tar_atol((char *)header->gid, sizeof(header->gid)));
tar->entry_bytes_remaining = tar_atol((char *)header->size, sizeof(header->size));
if (tar->entry_bytes_remaining < 0) {
tar->entry_bytes_remaining = 0;
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
Expand All @@ -1141,7 +1084,7 @@ header_common(struct archive_read *a, struct tar *tar,
}
tar->realsize = tar->entry_bytes_remaining;
archive_entry_set_size(entry, tar->entry_bytes_remaining);
archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
archive_entry_set_mtime(entry, tar_atol((char *)header->mtime, sizeof(header->mtime)), 0);

/* Handle the tar type flag appropriately. */
tartype = header->typeflag[0];
Expand Down Expand Up @@ -1302,9 +1245,9 @@ header_old_tar(struct archive_read *a, struct tar *tar,
int err = ARCHIVE_OK, err2;

/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_ustar *)h;
header = to_archive_entry_header_ustar_ptr(h);
if (archive_entry_copy_pathname_l(entry,
header->name, sizeof(header->name), tar->sconv) != 0) {
(char *)header->name, sizeof(header->name), tar->sconv) != 0) {
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
if (err == ARCHIVE_FATAL)
return (err);
Expand Down Expand Up @@ -1450,17 +1393,17 @@ header_ustar(struct archive_read *a, struct tar *tar,
struct archive_string *as;
int err = ARCHIVE_OK, r;

header = (const struct archive_entry_header_ustar *)h;
header = to_archive_entry_header_ustar_ptr(h);

/* Copy name into an internal buffer to ensure null-termination. */
as = &(tar->entry_pathname);
if (header->prefix[0]) {
archive_strncpy(as, header->prefix, sizeof(header->prefix));
archive_strncpy(as, (char *)header->prefix, sizeof(header->prefix));
if (as->s[archive_strlen(as) - 1] != '/')
archive_strappend_char(as, '/');
archive_strncat(as, header->name, sizeof(header->name));
archive_strncat(as, (char *)header->name, sizeof(header->name));
} else {
archive_strncpy(as, header->name, sizeof(header->name));
archive_strncpy(as, (char *)header->name, sizeof(header->name));
}
if (archive_entry_copy_pathname_l(entry, as->s, archive_strlen(as),
tar->sconv) != 0) {
Expand All @@ -1478,14 +1421,14 @@ header_ustar(struct archive_read *a, struct tar *tar,

/* Handle POSIX ustar fields. */
if (archive_entry_copy_uname_l(entry,
header->uname, sizeof(header->uname), tar->sconv) != 0) {
(char *)header->uname, sizeof(header->uname), tar->sconv) != 0) {
err = set_conversion_failed_error(a, tar->sconv, "Uname");
if (err == ARCHIVE_FATAL)
return (err);
}

if (archive_entry_copy_gname_l(entry,
header->gname, sizeof(header->gname), tar->sconv) != 0) {
(char *)header->gname, sizeof(header->gname), tar->sconv) != 0) {
err = set_conversion_failed_error(a, tar->sconv, "Gname");
if (err == ARCHIVE_FATAL)
return (err);
Expand All @@ -1494,9 +1437,9 @@ header_ustar(struct archive_read *a, struct tar *tar,
/* Parse out device numbers only for char and block specials. */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
archive_entry_set_rdevmajor(entry, (dev_t)
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
tar_atol((char *)header->rdevmajor, sizeof(header->rdevmajor)));
archive_entry_set_rdevminor(entry, (dev_t)
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
tar_atol((char *)header->rdevminor, sizeof(header->rdevminor)));
}

tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
Expand Down Expand Up @@ -2070,9 +2013,9 @@ header_gnutar(struct archive_read *a, struct tar *tar,
return (err);

/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_gnutar *)h;
header = to_archive_entry_header_gnutar_ptr(h);
if (archive_entry_copy_pathname_l(entry,
header->name, sizeof(header->name), tar->sconv) != 0) {
(char *)header->name, sizeof(header->name), tar->sconv) != 0) {
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
if (err == ARCHIVE_FATAL)
return (err);
Expand All @@ -2083,14 +2026,14 @@ header_gnutar(struct archive_read *a, struct tar *tar,
* to ustar and gnu tar? Is it okay to move it down into
* header_common, perhaps? */
if (archive_entry_copy_uname_l(entry,
header->uname, sizeof(header->uname), tar->sconv) != 0) {
(char *)header->uname, sizeof(header->uname), tar->sconv) != 0) {
err = set_conversion_failed_error(a, tar->sconv, "Uname");
if (err == ARCHIVE_FATAL)
return (err);
}

if (archive_entry_copy_gname_l(entry,
header->gname, sizeof(header->gname), tar->sconv) != 0) {
(char *)header->gname, sizeof(header->gname), tar->sconv) != 0) {
err = set_conversion_failed_error(a, tar->sconv, "Gname");
if (err == ARCHIVE_FATAL)
return (err);
Expand All @@ -2099,25 +2042,25 @@ header_gnutar(struct archive_read *a, struct tar *tar,
/* Parse out device numbers only for char and block specials */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
archive_entry_set_rdevmajor(entry, (dev_t)
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
tar_atol((char *)header->rdevmajor, sizeof(header->rdevmajor)));
archive_entry_set_rdevminor(entry, (dev_t)
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
tar_atol((char *)header->rdevminor, sizeof(header->rdevminor)));
} else
archive_entry_set_rdev(entry, 0);

tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);

/* Grab GNU-specific fields. */
t = tar_atol(header->atime, sizeof(header->atime));
t = tar_atol((char *)header->atime, sizeof(header->atime));
if (t > 0)
archive_entry_set_atime(entry, t, 0);
t = tar_atol(header->ctime, sizeof(header->ctime));
t = tar_atol((char *)header->ctime, sizeof(header->ctime));
if (t > 0)
archive_entry_set_ctime(entry, t, 0);

if (header->realsize[0] != 0) {
tar->realsize
= tar_atol(header->realsize, sizeof(header->realsize));
= tar_atol((char *)header->realsize, sizeof(header->realsize));
archive_entry_set_size(entry, tar->realsize);
}

Expand Down Expand Up @@ -2185,20 +2128,21 @@ gnu_clear_sparse_list(struct tar *tar)
* lot of criticism.
*/

struct extended {
struct gnu_sparse sparse[21];
char isextended[1];
char padding[7];
};

static int
gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
const struct archive_entry_header_gnutar *header, size_t *unconsumed)
{
ssize_t bytes_read;
const void *data;
struct extended {
struct gnu_sparse sparse[21];
char isextended[1];
char padding[7];
};
const struct extended *ext;

if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK)
if (gnu_sparse_old_parse(a, tar, (struct gnu_sparse *)header->sparse, 4) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
if (header->isextended[0] == 0)
return (ARCHIVE_OK);
Expand Down Expand Up @@ -2230,8 +2174,8 @@ gnu_sparse_old_parse(struct archive_read *a, struct tar *tar,
{
while (length > 0 && sparse->offset[0] != 0) {
if (gnu_add_sparse_entry(a, tar,
tar_atol(sparse->offset, sizeof(sparse->offset)),
tar_atol(sparse->numbytes, sizeof(sparse->numbytes)))
tar_atol((char *)sparse->offset, sizeof(sparse->offset)),
tar_atol((char *)sparse->numbytes, sizeof(sparse->numbytes)))
!= ARCHIVE_OK)
return (ARCHIVE_FATAL);
sparse++;
Expand Down Expand Up @@ -2555,7 +2499,7 @@ static int64_t
tar_atol256(const char *_p, size_t char_cnt)
{
uint64_t l;
const unsigned char *p = (const unsigned char *)_p;
const unsigned char *p = (const unsigned char *)(void *)_p;
unsigned char c, neg;

/* Extend 7-bit 2s-comp to 8-bit 2s-comp, decide sign. */
Expand Down Expand Up @@ -2686,7 +2630,7 @@ base64_decode(const char *s, size_t len, size_t *out_len)
'4','5','6','7','8','9','+','/' };
static unsigned char decode_table[128];
char *out, *d;
const unsigned char *src = (const unsigned char *)s;
const unsigned char *src = (const unsigned char *)(void *)s;

/* If the decode table is not yet initialized, prepare it. */
if (decode_table[digits[1]] != 1) {
Expand Down
31 changes: 18 additions & 13 deletions libarchive/archive_read_support_format_warc.c
Expand Up @@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_entry_private.h"

typedef enum {
WT_NONE,
Expand All @@ -94,12 +95,12 @@ typedef enum {
LAST_WT
} warc_type_t;

typedef struct {
typedef struct warc_string_t_ {
size_t len;
const char *str;
} warc_string_t;

typedef struct {
typedef struct warc_strbuf_t_ {
size_t len;
char *str;
} warc_strbuf_t;
Expand Down Expand Up @@ -127,7 +128,7 @@ static int _warc_skip(struct archive_read *a);
static int _warc_rdhdr(struct archive_read *a, struct archive_entry *e);

/* private routines */
static unsigned int _warc_rdver(const char buf[10], size_t bsz);
static unsigned int _warc_rdver(const char *buf, size_t bsz);
static unsigned int _warc_rdtyp(const char *buf, size_t bsz);
static warc_string_t _warc_rduri(const char *buf, size_t bsz);
static ssize_t _warc_rdlen(const char *buf, size_t bsz);
Expand All @@ -139,7 +140,7 @@ static const char *_warc_find_eoh(const char *buf, size_t bsz);
int
archive_read_support_format_warc(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
struct warc_s *w;
int r;

Expand All @@ -155,8 +156,8 @@ archive_read_support_format_warc(struct archive *_a)

r = __archive_read_register_format(
a, w, "warc",
_warc_bid, NULL, _warc_rdhdr, _warc_read,
_warc_skip, NULL, _warc_cleanup, NULL, NULL);
_warc_bid, 0, _warc_rdhdr, _warc_read,
_warc_skip, 0, _warc_cleanup, 0, 0);

if (r != ARCHIVE_OK) {
free(w);
Expand Down Expand Up @@ -290,7 +291,7 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
w->pver = ver;
}
/* start off with the type */
ftyp = _warc_rdtyp(buf, eoh - buf);
ftyp = (warc_type_t)_warc_rdtyp(buf, eoh - buf);
/* and let future calls know about the content */
w->cntlen = cntlen;
w->cntoff = 0U;
Expand Down Expand Up @@ -369,7 +370,6 @@ _warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
ssize_t nrd;

if (w->cntoff >= w->cntlen) {
eof:
/* it's our lucky day, no work, we can leave early */
*buf = NULL;
*bsz = 0U;
Expand All @@ -384,7 +384,12 @@ _warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
/* big catastrophe */
return (int)nrd;
} else if (nrd == 0) {
goto eof;
/* it's our lucky day, no work, we can leave early */
*buf = NULL;
*bsz = 0U;
*off = w->cntoff + 4U/*for \r\n\r\n separator*/;
w->unconsumed = 0U;
return (ARCHIVE_EOF);
} else if ((size_t)nrd > w->cntlen - w->cntoff) {
/* clamp to content-length */
nrd = w->cntlen - w->cntoff;
Expand Down Expand Up @@ -414,7 +419,7 @@ _warc_skip(struct archive_read *a)
static void*
deconst(const void *c)
{
return (char *)0x1 + (((const char *)c) - (const char *)0x1);
return (char *)(void *)0x1 + (((const char *)c) - (const char *)(void *)0x1);
}

static char*
Expand Down Expand Up @@ -578,7 +583,7 @@ xstrpisotime(const char *s, char **endptr)
}

static unsigned int
_warc_rdver(const char buf[10], size_t bsz)
_warc_rdver(const char * buf, size_t bsz)
{
static const char magic[] = "WARC/";
unsigned int ver;
Expand Down Expand Up @@ -611,7 +616,7 @@ _warc_rdver(const char buf[10], size_t bsz)
/* set up major version */
ver = (buf[0U] - '0') * 10000U;
/* minor version, anyone? */
ver += (strtol(buf + 2U, &on, 10)) * 100U;
ver += (strtol(buf + 2U, 0, 10)) * 100U;
/* don't parse anything else */
if (on > buf + 2U) {
break;
Expand Down Expand Up @@ -732,7 +737,7 @@ _warc_rdlen(const char *buf, size_t bsz)

/* strtol kindly overreads whitespace for us, so use that */
val += sizeof(_key) - 1U;
len = strtol(val, &on, 10);
len = strtol(val, 0, 10);
if (on == NULL || !isspace((unsigned char)*on)) {
/* hm, can we trust that number? Best not. */
return -1;
Expand Down
15 changes: 8 additions & 7 deletions libarchive/archive_read_support_format_xar.c
Expand Up @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_entry_private.h"

#if (!defined(HAVE_LIBXML_XMLREADER_H) && \
!defined(HAVE_BSDXML_H) && !defined(HAVE_EXPAT_H)) ||\
Expand All @@ -73,7 +74,7 @@ __FBSDID("$FreeBSD$");
int
archive_read_support_format_xar(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_NEW, "archive_read_support_format_xar");

Expand All @@ -88,7 +89,7 @@ archive_read_support_format_xar(struct archive *_a)
/* #define DEBUG_PRINT_TOC 1 */
#if DEBUG_PRINT_TOC
#define PRINT_TOC(d, outbytes) do { \
unsigned char *x = (unsigned char *)(uintptr_t)d; \
unsigned char *x = (unsigned char *)d; \
unsigned char c = x[outbytes-1]; \
x[outbytes - 1] = 0; \
fprintf(stderr, "%s", x); \
Expand Down Expand Up @@ -446,7 +447,7 @@ int
archive_read_support_format_xar(struct archive *_a)
{
struct xar *xar;
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
int r;

archive_check_magic(_a, ARCHIVE_READ_MAGIC,
Expand Down Expand Up @@ -1593,7 +1594,7 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,

xar = (struct xar *)(a->format->data);
avail_in = *used;
outbuff = (void *)(uintptr_t)*buff;
outbuff = (void *)*buff;
if (outbuff == NULL) {
if (xar->outbuff == NULL) {
xar->outbuff = malloc(OUTBUFF_SIZE);
Expand All @@ -1610,7 +1611,7 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
avail_out = *outbytes;
switch (xar->rd_encoding) {
case GZIP:
xar->stream.next_in = (Bytef *)(uintptr_t)b;
xar->stream.next_in = (Bytef *)b;
xar->stream.avail_in = avail_in;
xar->stream.next_out = (unsigned char *)outbuff;
xar->stream.avail_out = avail_out;
Expand All @@ -1629,7 +1630,7 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
break;
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
case BZIP2:
xar->bzstream.next_in = (char *)(uintptr_t)b;
xar->bzstream.next_in = (char *)b;
xar->bzstream.avail_in = avail_in;
xar->bzstream.next_out = (char *)outbuff;
xar->bzstream.avail_out = avail_out;
Expand Down Expand Up @@ -1687,7 +1688,7 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
break;
#elif defined(HAVE_LZMADEC_H) && defined(HAVE_LIBLZMADEC)
case LZMA:
xar->lzstream.next_in = (unsigned char *)(uintptr_t)b;
xar->lzstream.next_in = (unsigned char *)b;
xar->lzstream.avail_in = avail_in;
xar->lzstream.next_out = (unsigned char *)outbuff;
xar->lzstream.avail_out = avail_out;
Expand Down
74 changes: 39 additions & 35 deletions libarchive/archive_read_support_format_zip.c
Expand Up @@ -63,11 +63,26 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
#include "archive_private.h"
#include "archive_rb.h"
#include "archive_read_private.h"
#include "archive_entry_private.h"

#ifndef HAVE_ZLIB_H
#include "archive_crc32.h"
#endif

/* WinZip AES encryption extra field should be available
* when compression is 99. */
struct aes_extra_ {
/* Vendor version: AE-1 - 0x0001, AE-2 - 0x0002 */
unsigned vendor;
#define AES_VENDOR_AE_1 0x0001
#define AES_VENDOR_AE_2 0x0002
/* AES encryption strength:
* 1 - 128 bits, 2 - 192 bits, 2 - 256 bits. */
unsigned strength;
/* Actual compression method. */
unsigned char compression;
};

struct zip_entry {
struct archive_rb_node node;
struct zip_entry *next;
Expand All @@ -90,17 +105,7 @@ struct zip_entry {

/* WinZip AES encryption extra field should be available
* when compression is 99. */
struct {
/* Vendor version: AE-1 - 0x0001, AE-2 - 0x0002 */
unsigned vendor;
#define AES_VENDOR_AE_1 0x0001
#define AES_VENDOR_AE_2 0x0002
/* AES encryption strength:
* 1 - 128 bits, 2 - 192 bits, 2 - 256 bits. */
unsigned strength;
/* Actual compression method. */
unsigned char compression;
} aes_extra;
struct aes_extra_ aes_extra;
};

struct trad_enc_ctx {
Expand Down Expand Up @@ -347,7 +352,7 @@ fake_crc32(unsigned long crc, const void *buff, size_t len)
return 0;
}

static struct {
static struct compression_methods_ {
int id;
const char * name;
} compression_methods[] = {
Expand Down Expand Up @@ -1219,18 +1224,18 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
dec_size = zip->decrypted_buffer_size;
if (zip->tctx_valid) {
trad_enc_decrypt_update(&zip->tctx,
(const uint8_t *)buff, dec_size,
(const uint8_t *)(void *)buff, dec_size,
zip->decrypted_buffer, dec_size);
} else {
size_t dsize = dec_size;
archive_hmac_sha1_update(&zip->hctx,
(const uint8_t *)buff, dec_size);
(const uint8_t *)(void *)buff, dec_size);
archive_decrypto_aes_ctr_update(&zip->cctx,
(const uint8_t *)buff, dec_size,
(const uint8_t *)(void *)buff, dec_size,
zip->decrypted_buffer, &dsize);
}
bytes_avail = dec_size;
buff = (const char *)zip->decrypted_buffer;
buff = (const char *)(void *)zip->decrypted_buffer;
}
*size = bytes_avail;
zip->entry_bytes_remaining -= bytes_avail;
Expand Down Expand Up @@ -1365,7 +1370,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
* next_in pointer, only reads it). The result: this ugly
* cast to remove 'const'.
*/
zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff;
zip->stream.next_in = (Bytef *)(const void *)compressed_buff;
zip->stream.avail_in = (uInt)bytes_avail;
zip->stream.total_in = 0;
zip->stream.next_out = zip->uncompressed_buffer;
Expand Down Expand Up @@ -1965,7 +1970,7 @@ archive_read_format_zip_cleanup(struct archive_read *a)
}

static int
archive_read_format_zip_has_encrypted_entries(struct archive_read *_a)
archive_read_format_zip_has_encrypted_entries(struct archive_read * _a)
{
if (_a && _a->format) {
struct zip * zip = (struct zip *)_a->format->data;
Expand Down Expand Up @@ -2275,7 +2280,7 @@ archive_read_format_zip_read_data_skip_streamable(struct archive_read *a)
int
archive_read_support_format_zip_streamable(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
struct zip *zip;
int r;

Expand Down Expand Up @@ -2307,7 +2312,7 @@ archive_read_support_format_zip_streamable(struct archive *_a)
archive_read_format_zip_streamable_read_header,
archive_read_format_zip_read_data,
archive_read_format_zip_read_data_skip_streamable,
NULL,
0,
archive_read_format_zip_cleanup,
archive_read_support_format_zip_capabilities_streamable,
archive_read_format_zip_has_encrypted_entries);
Expand Down Expand Up @@ -2476,8 +2481,8 @@ archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
static int
cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n2)
{
const struct zip_entry *e1 = (const struct zip_entry *)n1;
const struct zip_entry *e2 = (const struct zip_entry *)n2;
const struct zip_entry *e1 = _containerof(n1, const struct zip_entry, node);
const struct zip_entry *e2 = _containerof(n2, const struct zip_entry, node);

if (e1->local_header_offset > e2->local_header_offset)
return -1;
Expand All @@ -2503,16 +2508,16 @@ static int
rsrc_cmp_node(const struct archive_rb_node *n1,
const struct archive_rb_node *n2)
{
const struct zip_entry *e1 = (const struct zip_entry *)n1;
const struct zip_entry *e2 = (const struct zip_entry *)n2;
const struct zip_entry *e1 = _containerof(n1, const struct zip_entry, node);
const struct zip_entry *e2 = _containerof(n2, const struct zip_entry, node);

return (strcmp(e2->rsrcname.s, e1->rsrcname.s));
}

static int
rsrc_cmp_key(const struct archive_rb_node *n, const void *key)
{
const struct zip_entry *e = (const struct zip_entry *)n;
const struct zip_entry *e = _containerof(n, const struct zip_entry, node);
return (strcmp((const char *)key, e->rsrcname.s));
}

Expand Down Expand Up @@ -2551,8 +2556,7 @@ expose_parent_dirs(struct zip *zip, const char *name, size_t name_length)
*s = '\0';
/* Transfer the parent directory from zip->tree_rsrc RB
* tree to zip->tree RB tree to expose. */
dir = (struct zip_entry *)
__archive_rb_tree_find_node(&zip->tree_rsrc, str.s);
dir = _containerof(__archive_rb_tree_find_node(&zip->tree_rsrc, str.s), struct zip_entry, node);
if (dir == NULL)
break;
__archive_rb_tree_remove_node(&zip->tree_rsrc, &dir->node);
Expand Down Expand Up @@ -2890,7 +2894,7 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
if (ret != ARCHIVE_OK)
goto exit_mac_metadata;
zip->stream.next_in =
(Bytef *)(uintptr_t)(const void *)p;
(Bytef *)(const void *)p;
zip->stream.avail_in = (uInt)bytes_avail;
zip->stream.total_in = 0;
zip->stream.next_out = mp;
Expand Down Expand Up @@ -2970,19 +2974,19 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
/* Get first entry whose local header offset is lower than
* other entries in the archive file. */
zip->entry =
(struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree);
_containerof(ARCHIVE_RB_TREE_MIN(&zip->tree), struct zip_entry, node);
} else if (zip->entry != NULL) {
/* Get next entry in local header offset order. */
zip->entry = (struct zip_entry *)__archive_rb_tree_iterate(
&zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT);
zip->entry = _containerof(__archive_rb_tree_iterate(
&zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT), struct zip_entry, node);
}

if (zip->entry == NULL)
return ARCHIVE_EOF;

if (zip->entry->rsrcname.s)
rsrc = (struct zip_entry *)__archive_rb_tree_find_node(
&zip->tree_rsrc, zip->entry->rsrcname.s);
rsrc = _containerof(__archive_rb_tree_find_node(
&zip->tree_rsrc, zip->entry->rsrcname.s), struct zip_entry, node);
else
rsrc = NULL;

Expand Down Expand Up @@ -3033,7 +3037,7 @@ archive_read_format_zip_read_data_skip_seekable(struct archive_read *a)
int
archive_read_support_format_zip_seekable(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read *a = _containerof(_a, struct archive_read, archive);
struct zip *zip;
int r;

Expand Down Expand Up @@ -3067,7 +3071,7 @@ archive_read_support_format_zip_seekable(struct archive *_a)
archive_read_format_zip_seekable_read_header,
archive_read_format_zip_read_data,
archive_read_format_zip_read_data_skip_seekable,
NULL,
0,
archive_read_format_zip_cleanup,
archive_read_support_format_zip_capabilities_seekable,
archive_read_format_zip_has_encrypted_entries);
Expand Down
137 changes: 70 additions & 67 deletions libarchive/archive_string.c
Expand Up @@ -65,62 +65,16 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
#include "archive_endian.h"
#include "archive_private.h"
#include "archive_string.h"
#include "archive_string_composition.h"
#include <archive_string_composition.h>

#if !defined(HAVE_WMEMCPY) && !defined(wmemcpy)
#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
#define wmemcpy(a,b,i) (wchar_t *)(void *)memcpy((a), (b), (i) * sizeof(wchar_t))
#endif

#if !defined(HAVE_WMEMMOVE) && !defined(wmemmove)
#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t))
#define wmemmove(a,b,i) (wchar_t *)(void *)memmove((a), (b), (i) * sizeof(wchar_t))
#endif

struct archive_string_conv {
struct archive_string_conv *next;
char *from_charset;
char *to_charset;
unsigned from_cp;
unsigned to_cp;
/* Set 1 if from_charset and to_charset are the same. */
int same;
int flag;
#define SCONV_TO_CHARSET 1 /* MBS is being converted to specified
* charset. */
#define SCONV_FROM_CHARSET (1<<1) /* MBS is being converted from
* specified charset. */
#define SCONV_BEST_EFFORT (1<<2) /* Copy at least ASCII code. */
#define SCONV_WIN_CP (1<<3) /* Use Windows API for converting
* MBS. */
#define SCONV_UTF8_LIBARCHIVE_2 (1<<4) /* Incorrect UTF-8 made by libarchive
* 2.x in the wrong assumption. */
#define SCONV_NORMALIZATION_C (1<<6) /* Need normalization to be Form C.
* Before UTF-8 characters are actually
* processed. */
#define SCONV_NORMALIZATION_D (1<<7) /* Need normalization to be Form D.
* Before UTF-8 characters are actually
* processed.
* Currently this only for MAC OS X. */
#define SCONV_TO_UTF8 (1<<8) /* "to charset" side is UTF-8. */
#define SCONV_FROM_UTF8 (1<<9) /* "from charset" side is UTF-8. */
#define SCONV_TO_UTF16BE (1<<10) /* "to charset" side is UTF-16BE. */
#define SCONV_FROM_UTF16BE (1<<11) /* "from charset" side is UTF-16BE. */
#define SCONV_TO_UTF16LE (1<<12) /* "to charset" side is UTF-16LE. */
#define SCONV_FROM_UTF16LE (1<<13) /* "from charset" side is UTF-16LE. */
#define SCONV_TO_UTF16 (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE)
#define SCONV_FROM_UTF16 (SCONV_FROM_UTF16BE | SCONV_FROM_UTF16LE)

#if HAVE_ICONV
iconv_t cd;
iconv_t cd_w;/* Use at archive_mstring on
* Windows. */
#endif
/* A temporary buffer for normalization. */
struct archive_string utftmp;
int (*converter[2])(struct archive_string *, const void *, size_t,
struct archive_string_conv *);
int nconverter;
};

#define CP_C_LOCALE 0 /* "C" locale only for this file. */
#define CP_UTF16LE 1200
#define CP_UTF16BE 1201
Expand Down Expand Up @@ -252,14 +206,6 @@ archive_wstring_free(struct archive_wstring *as)
as->s = NULL;
}

struct archive_wstring *
archive_wstring_ensure(struct archive_wstring *as, size_t s)
{
return (struct archive_wstring *)
archive_string_ensure((struct archive_string *)as,
s * sizeof(wchar_t));
}

/* Returns NULL on any allocation failure. */
struct archive_string *
archive_string_ensure(struct archive_string *as, size_t s)
Expand Down Expand Up @@ -316,6 +262,61 @@ archive_string_ensure(struct archive_string *as, size_t s)
return (as);
}

struct archive_wstring *
archive_wstring_ensure(struct archive_wstring *as, size_t s)
{
wchar_t *p;
size_t new_length;

/* If buffer is already big enough, don't reallocate. */
if (as->s && (s <= as->buffer_length))
return (as);

/*
* Growing the buffer at least exponentially ensures that
* append operations are always linear in the number of
* characters appended. Using a smaller growth rate for
* larger buffers reduces memory waste somewhat at the cost of
* a larger constant factor.
*/
if (as->buffer_length < 32)
/* Start with a minimum 32-character buffer. */
new_length = 32;
else if (as->buffer_length < 8192)
/* Buffers under 8k are doubled for speed. */
new_length = as->buffer_length + as->buffer_length;
else {
/* Buffers 8k and over grow by at least 25% each time. */
new_length = as->buffer_length + as->buffer_length / 4;
/* Be safe: If size wraps, fail. */
if (new_length < as->buffer_length) {
/* On failure, wipe the string and return NULL. */
archive_wstring_free(as);
errno = ENOMEM;/* Make sure errno has ENOMEM. */
return (NULL);
}
}
/*
* The computation above is a lower limit to how much we'll
* grow the buffer. In any case, we have to grow it enough to
* hold the request.
*/
if (new_length < s)
new_length = s;
/* Now we can reallocate the buffer. */
p = (wchar_t *)realloc(as->s, new_length * sizeof(wchar_t));
if (p == NULL) {
/* On failure, wipe the string and return NULL. */
archive_wstring_free(as);
errno = ENOMEM;/* Make sure errno has ENOMEM. */
return (NULL);
}

as->s = p;
as->buffer_length = new_length;
return (as);
}

/*
* TODO: See if there's a way to avoid scanning
* the source string twice. Then test to see
Expand Down Expand Up @@ -592,7 +593,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,

memset(&shift_state, 0, sizeof(shift_state));
#endif
if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
if (archive_wstring_ensure(dest, dest->length + wcs_length + 1) == NULL)
return (-1);
wcs = dest->s + dest->length;
/*
Expand All @@ -605,8 +606,8 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
dest->length = wcs - dest->s;
dest->s[dest->length] = L'\0';
wcs_length = mbs_length;
if (NULL == archive_wstring_ensure(dest,
dest->length + wcs_length + 1))
if (archive_wstring_ensure(dest,
dest->length + wcs_length + 1) == NULL)
return (-1);
wcs = dest->s + dest->length;
}
Expand Down Expand Up @@ -2019,7 +2020,7 @@ iconv_strncat_in_locale(struct archive_string *as, const void *_p,
return (-1);

cd = sc->cd;
itp = (char *)(uintptr_t)_p;
itp = (char *)_p;
remaining = length;
outp = as->s + as->length;
avail = as->buffer_length - as->length - to_size;
Expand Down Expand Up @@ -2168,7 +2169,7 @@ invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc)
memset(&shift_state, 0, sizeof(shift_state));
#else
/* Clear the shift state before starting. */
mbtowc(NULL, NULL, 0);
mbtowc(0, 0, 0);
#endif
while (n) {
wchar_t wc;
Expand Down Expand Up @@ -3211,6 +3212,11 @@ get_nfd(uint32_t *cp1, uint32_t *cp2, uint32_t uc)
/*
* Normalize UTF-8 characters to Form D and copy the result.
*/
struct fdc_ {
uint32_t uc;
int ccc;
};

static int
archive_string_normalize_D(struct archive_string *as, const void *_p,
size_t len, struct archive_string_conv *sc)
Expand Down Expand Up @@ -3279,10 +3285,7 @@ archive_string_normalize_D(struct archive_string *as, const void *_p,
const char *ucptr;
uint32_t cp1, cp2;
int SIndex;
struct {
uint32_t uc;
int ccc;
} fdc[FDC_MAX];
struct fdc_ fdc[FDC_MAX];
int fdi, fdj;
int ccc;

Expand Down Expand Up @@ -3407,7 +3410,7 @@ strncat_from_utf8_libarchive2(struct archive_string *as,
memset(&shift_state, 0, sizeof(shift_state));
#else
/* Clear the shift state before starting. */
wctomb(NULL, L'\0');
wctomb(0, L'\0');
#endif
(void)sc; /* UNUSED */
/*
Expand Down
83 changes: 46 additions & 37 deletions libarchive/archive_string.h
Expand Up @@ -48,27 +48,56 @@

#include "archive.h"

/*
* Basic resizable/reusable string support similar to Java's "StringBuffer."
*
* Unlike sbuf(9), the buffers here are fully reusable and track the
* length throughout.
*/
struct archive_string_conv;

struct archive_string {
char *s; /* Pointer to the storage */
size_t length; /* Length of 's' in characters */
size_t buffer_length; /* Length of malloc-ed storage in bytes. */
};
typedef int (*converter_)(struct archive_string *, const void *, size_t,
struct archive_string_conv *);

struct archive_wstring {
wchar_t *s; /* Pointer to the storage */
size_t length; /* Length of 's' in characters */
size_t buffer_length; /* Length of malloc-ed storage in bytes. */
struct archive_string_conv {
struct archive_string_conv *next;
char *from_charset;
char *to_charset;
unsigned from_cp;
unsigned to_cp;
/* Set 1 if from_charset and to_charset are the same. */
int same;
int flag;
#define SCONV_TO_CHARSET 1 /* MBS is being converted to specified
* charset. */
#define SCONV_FROM_CHARSET (1<<1) /* MBS is being converted from
* specified charset. */
#define SCONV_BEST_EFFORT (1<<2) /* Copy at least ASCII code. */
#define SCONV_WIN_CP (1<<3) /* Use Windows API for converting
* MBS. */
#define SCONV_UTF8_LIBARCHIVE_2 (1<<4) /* Incorrect UTF-8 made by libarchive
* 2.x in the wrong assumption. */
#define SCONV_NORMALIZATION_C (1<<6) /* Need normalization to be Form C.
* Before UTF-8 characters are actually
* processed. */
#define SCONV_NORMALIZATION_D (1<<7) /* Need normalization to be Form D.
* Before UTF-8 characters are actually
* processed.
* Currently this only for MAC OS X. */
#define SCONV_TO_UTF8 (1<<8) /* "to charset" side is UTF-8. */
#define SCONV_FROM_UTF8 (1<<9) /* "from charset" side is UTF-8. */
#define SCONV_TO_UTF16BE (1<<10) /* "to charset" side is UTF-16BE. */
#define SCONV_FROM_UTF16BE (1<<11) /* "from charset" side is UTF-16BE. */
#define SCONV_TO_UTF16LE (1<<12) /* "to charset" side is UTF-16LE. */
#define SCONV_FROM_UTF16LE (1<<13) /* "from charset" side is UTF-16LE. */
#define SCONV_TO_UTF16 (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE)
#define SCONV_FROM_UTF16 (SCONV_FROM_UTF16BE | SCONV_FROM_UTF16LE)

#if HAVE_ICONV
iconv_t cd;
iconv_t cd_w;/* Use at archive_mstring on
* Windows. */
#endif
/* A temporary buffer for normalization. */
struct archive_string utftmp;
converter_ converter[2];
int nconverter;
};

struct archive_string_conv;

/* Initialize an archive_string object on the stack or elsewhere. */
#define archive_string_init(a) \
do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0)
Expand Down Expand Up @@ -197,26 +226,6 @@ int archive_wstring_append_from_mbs(struct archive_wstring *dest,
const char *, size_t);


/* A "multistring" can hold Unicode, UTF8, or MBS versions of
* the string. If you set and read the same version, no translation
* is done. If you set and read different versions, the library
* will attempt to transparently convert.
*/
struct archive_mstring {
struct archive_string aes_mbs;
struct archive_string aes_utf8;
struct archive_wstring aes_wcs;
struct archive_string aes_mbs_in_locale;
/* Bitmap of which of the above are valid. Because we're lazy
* about malloc-ing and reusing the underlying storage, we
* can't rely on NULL pointers to indicate whether a string
* has been set. */
int aes_set;
#define AES_SET_MBS 1
#define AES_SET_UTF8 2
#define AES_SET_WCS 4
};

void archive_mstring_clean(struct archive_mstring *);
void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src);
int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
Expand Down
6 changes: 3 additions & 3 deletions libarchive/archive_string_sprintf.c
Expand Up @@ -145,23 +145,23 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
case 's':
switch(long_flag) {
case 'l':
pw = va_arg(ap, wchar_t *);
pw = (wchar_t *)(void *)va_arg(ap, uintptr_t);
if (pw == NULL)
pw = L"(null)";
if (archive_string_append_from_wcs(as, pw,
wcslen(pw)) != 0 && errno == ENOMEM)
__archive_errx(1, "Out of memory");
break;
default:
p2 = va_arg(ap, char *);
p2 = (char *)(void *)va_arg(ap, uintptr_t);
if (p2 == NULL)
p2 = "(null)";
archive_strcat(as, p2);
break;
}
break;
case 'S':
pw = va_arg(ap, wchar_t *);
pw = (wchar_t *)(void *)va_arg(ap, uintptr_t);
if (pw == NULL)
pw = L"(null)";
if (archive_string_append_from_wcs(as, pw,
Expand Down
5 changes: 3 additions & 2 deletions libarchive/archive_util.c
Expand Up @@ -548,7 +548,7 @@ __archive_mktemp(const char *tmpdir)
p = tp;
archive_random(p, ep - p);
while (p < ep) {
int d = *((unsigned char *)p) % sizeof(num);
int d = *((unsigned char *)(void *)p) % sizeof(num);
*p++ = num[d];
}
fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
Expand Down Expand Up @@ -599,7 +599,8 @@ static int
archive_utility_string_sort_helper(char **strings, unsigned int n)
{
unsigned int i, lesser_count, greater_count;
char **lesser, **greater, **tmp, *pivot;
char **lesser, **greater, **tmp;
char *pivot;
int retval1, retval2;

/* A list of 0 or 1 elements is already sorted */
Expand Down
2 changes: 1 addition & 1 deletion libarchive/archive_virtual.c
Expand Up @@ -133,7 +133,7 @@ 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)
{
if (a->vtable->archive_write_data_block == NULL) {
if (a->vtable->archive_write_data_block == 0) {
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"archive_write_data_block not supported");
a->state = ARCHIVE_STATE_FATAL;
Expand Down
68 changes: 37 additions & 31 deletions libarchive/archive_write.c
Expand Up @@ -142,7 +142,7 @@ archive_write_new(void)
int
archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
a->bytes_per_block = bytes_per_block;
Expand All @@ -155,7 +155,7 @@ archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
int
archive_write_get_bytes_per_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
return (a->bytes_per_block);
Expand All @@ -168,7 +168,7 @@ archive_write_get_bytes_per_block(struct archive *_a)
int
archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
a->bytes_in_last_block = bytes;
Expand All @@ -181,7 +181,7 @@ archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
int
archive_write_get_bytes_in_last_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
return (a->bytes_in_last_block);
Expand All @@ -194,7 +194,7 @@ archive_write_get_bytes_in_last_block(struct archive *_a)
int
archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
a->skip_file_set = 1;
Expand All @@ -209,7 +209,7 @@ archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
struct archive_write_filter *
__archive_write_allocate_filter(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f;

f = calloc(1, sizeof(*f));
Expand All @@ -232,7 +232,7 @@ __archive_write_filter(struct archive_write_filter *f,
int r;
if (length == 0)
return(ARCHIVE_OK);
if (f->write == NULL)
if (f->write == 0)
/* If unset, a fatal error has already ocuured, so this filter
* didn't open. We cannot write anything. */
return(ARCHIVE_FATAL);
Expand All @@ -247,7 +247,7 @@ __archive_write_filter(struct archive_write_filter *f,
int
__archive_write_open_filter(struct archive_write_filter *f)
{
if (f->open == NULL)
if (f->open == 0)
return (ARCHIVE_OK);
return (f->open)(f);
}
Expand All @@ -258,7 +258,7 @@ __archive_write_open_filter(struct archive_write_filter *f)
int
__archive_write_close_filter(struct archive_write_filter *f)
{
if (f->close != NULL)
if (f->close != 0)
return (f->close)(f);
if (f->next_filter != NULL)
return (__archive_write_close_filter(f->next_filter));
Expand Down Expand Up @@ -290,7 +290,7 @@ __archive_write_nulls(struct archive_write *a, size_t length)
static int
archive_write_client_open(struct archive_write_filter *f)
{
struct archive_write *a = (struct archive_write *)f->archive;
struct archive_write *a = _containerof(f->archive, struct archive_write, archive);
struct archive_none *state;
void *buffer;
size_t buffer_size;
Expand All @@ -316,7 +316,7 @@ archive_write_client_open(struct archive_write_filter *f)
state->avail = state->buffer_size;
f->data = state;

if (a->client_opener == NULL)
if (a->client_opener == 0)
return (ARCHIVE_OK);
return (a->client_opener(f->archive, a->client_data));
}
Expand All @@ -325,7 +325,7 @@ static int
archive_write_client_write(struct archive_write_filter *f,
const void *_buff, size_t length)
{
struct archive_write *a = (struct archive_write *)f->archive;
struct archive_write *a = _containerof(f->archive, struct archive_write, archive);
struct archive_none *state = (struct archive_none *)f->data;
const char *buff = (const char *)_buff;
ssize_t remaining, to_copy;
Expand Down Expand Up @@ -406,7 +406,7 @@ archive_write_client_write(struct archive_write_filter *f,
static int
archive_write_client_close(struct archive_write_filter *f)
{
struct archive_write *a = (struct archive_write *)f->archive;
struct archive_write *a = _containerof(f->archive, struct archive_write, archive);
struct archive_none *state = (struct archive_none *)f->data;
ssize_t block_length;
ssize_t target_block_length;
Expand Down Expand Up @@ -442,7 +442,7 @@ archive_write_client_close(struct archive_write_filter *f)
free(state->buffer);
free(state);
/* Clear the close handler myself not to be called again. */
f->close = NULL;
f->close = 0;
a->client_data = NULL;
/* Clear passphrase. */
if (a->passphrase != NULL) {
Expand All @@ -461,7 +461,7 @@ archive_write_open(struct archive *_a, void *client_data,
archive_open_callback *opener, archive_write_callback *writer,
archive_close_callback *closer)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *client_filter;
int ret, r1;

Expand Down Expand Up @@ -497,7 +497,7 @@ archive_write_open(struct archive *_a, void *client_data,
static int
_archive_write_close(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
int r = ARCHIVE_OK, r1 = ARCHIVE_OK;

archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
Expand All @@ -511,12 +511,12 @@ _archive_write_close(struct archive *_a)

/* Finish the last entry if a finish callback is specified */
if (a->archive.state == ARCHIVE_STATE_DATA
&& a->format_finish_entry != NULL)
&& a->format_finish_entry != 0)
r = ((a->format_finish_entry)(a));

/* Finish off the archive. */
/* TODO: have format closers invoke compression close. */
if (a->format_close != NULL) {
if (a->format_close != 0) {
r1 = (a->format_close)(a);
if (r1 < r)
r = r1;
Expand All @@ -535,7 +535,7 @@ _archive_write_close(struct archive *_a)
static int
_archive_write_filter_count(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *p = a->filter_first;
int count = 0;
while(p) {
Expand All @@ -548,13 +548,13 @@ _archive_write_filter_count(struct archive *_a)
void
__archive_write_filters_free(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
int r = ARCHIVE_OK, r1;

while (a->filter_first != NULL) {
struct archive_write_filter *next
= a->filter_first->next_filter;
if (a->filter_first->free != NULL) {
if (a->filter_first->free != 0) {
r1 = (*a->filter_first->free)(a->filter_first);
if (r > r1)
r = r1;
Expand All @@ -575,7 +575,7 @@ __archive_write_filters_free(struct archive *_a)
static int
_archive_write_free(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
int r = ARCHIVE_OK, r1;

if (_a == NULL)
Expand All @@ -587,7 +587,7 @@ _archive_write_free(struct archive *_a)
r = archive_write_close(&a->archive);

/* Release format resources. */
if (a->format_free != NULL) {
if (a->format_free != 0) {
r1 = (a->format_free)(a);
if (r1 < r)
r = r1;
Expand All @@ -596,7 +596,7 @@ _archive_write_free(struct archive *_a)
__archive_write_filters_free(_a);

/* Release various dynamic buffers. */
free((void *)(uintptr_t)(const void *)a->nulls);
free(a->nulls);
archive_string_free(&a->archive.error_string);
if (a->passphrase != NULL) {
/* A passphrase should be cleaned. */
Expand All @@ -615,20 +615,23 @@ _archive_write_free(struct archive *_a)
static int
_archive_write_header(struct archive *_a, struct archive_entry *entry)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
int ret, r2;
printf("%s: %i\n", __PRETTY_FUNCTION__, __LINE__);

archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
archive_clear_error(&a->archive);

if (a->format_write_header == NULL) {
printf("%s: %i\n", __PRETTY_FUNCTION__, __LINE__);
if (a->format_write_header == 0) {
archive_set_error(&(a->archive), -1,
"Format must be set before you can write to an archive.");
a->archive.state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}

printf("%s: %i\n", __PRETTY_FUNCTION__, __LINE__);
/* In particular, "retry" and "fatal" get returned immediately. */
ret = archive_write_finish_entry(&a->archive);
if (ret == ARCHIVE_FATAL) {
Expand All @@ -638,6 +641,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN)
return (ret);

printf("%s: %i\n", __PRETTY_FUNCTION__, __LINE__);
if (a->skip_file_set &&
archive_entry_dev_is_set(entry) &&
archive_entry_ino_is_set(entry) &&
Expand All @@ -648,6 +652,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
return (ARCHIVE_FAILED);
}

printf("%s: %i\n", __PRETTY_FUNCTION__, __LINE__);
/* Format and write header. */
r2 = ((a->format_write_header)(a, entry));
if (r2 == ARCHIVE_FAILED) {
Expand All @@ -660,21 +665,22 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
if (r2 < ret)
ret = r2;

printf("%s: %i\n", __PRETTY_FUNCTION__, __LINE__);
a->archive.state = ARCHIVE_STATE_DATA;
return (ret);
}

static int
_archive_write_finish_entry(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
int ret = ARCHIVE_OK;

archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
if (a->archive.state & ARCHIVE_STATE_DATA
&& a->format_finish_entry != NULL)
&& a->format_finish_entry != 0)
ret = (a->format_finish_entry)(a);
a->archive.state = ARCHIVE_STATE_HEADER;
return (ret);
Expand All @@ -686,7 +692,7 @@ _archive_write_finish_entry(struct archive *_a)
static ssize_t
_archive_write_data(struct archive *_a, const void *buff, size_t s)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
const size_t max_write = INT_MAX;

archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
Expand All @@ -701,7 +707,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s)
static struct archive_write_filter *
filter_lookup(struct archive *_a, int n)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f = a->filter_first;
if (n == -1)
return a->filter_last;
Expand All @@ -725,7 +731,7 @@ static const char *
_archive_filter_name(struct archive *_a, int n)
{
struct archive_write_filter *f = filter_lookup(_a, n);
return f != NULL ? f->name : NULL;
return f != NULL ? f->name : (const char *)NULL;
}

static int64_t
Expand Down
4 changes: 2 additions & 2 deletions libarchive/archive_write_add_filter.c
Expand Up @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");

/* A table that maps filter codes to functions. */
static
struct { int code; int (*setter)(struct archive *); } codes[] =
struct codes_ { int code; int (*setter)(struct archive *); } codes[] =
{
{ ARCHIVE_FILTER_NONE, archive_write_add_filter_none },
{ ARCHIVE_FILTER_GZIP, archive_write_add_filter_gzip },
Expand All @@ -53,7 +53,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
{ ARCHIVE_FILTER_LZOP, archive_write_add_filter_lzip },
{ ARCHIVE_FILTER_UU, archive_write_add_filter_uuencode },
{ ARCHIVE_FILTER_XZ, archive_write_add_filter_xz },
{ -1, NULL }
{ -1, 0 }
};

int
Expand Down
2 changes: 1 addition & 1 deletion libarchive/archive_write_add_filter_b64encode.c
Expand Up @@ -80,7 +80,7 @@ static const char base64[] = {
int
archive_write_add_filter_b64encode(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_b64encode *state;

Expand Down
4 changes: 2 additions & 2 deletions libarchive/archive_write_add_filter_by_name.c
Expand Up @@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");

/* A table that maps names to functions. */
static
struct { const char *name; int (*setter)(struct archive *); } names[] =
struct names_ { const char *name; int (*setter)(struct archive *); } names[] =
{
{ "b64encode", archive_write_add_filter_b64encode },
{ "bzip2", archive_write_add_filter_bzip2 },
Expand All @@ -57,7 +57,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
{ "lzop", archive_write_add_filter_lzop },
{ "uuencode", archive_write_add_filter_uuencode },
{ "xz", archive_write_add_filter_xz },
{ NULL, NULL }
{ NULL, 0 }
};

int
Expand Down
4 changes: 2 additions & 2 deletions libarchive/archive_write_add_filter_bzip2.c
Expand Up @@ -81,7 +81,7 @@ static int archive_compressor_bzip2_write(struct archive_write_filter *,
int
archive_write_add_filter_bzip2(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;

Expand Down Expand Up @@ -154,7 +154,7 @@ archive_compressor_bzip2_options(struct archive_write_filter *f,
* of ugly hackery to convert a const * pointer to a non-const pointer.
*/
#define SET_NEXT_IN(st,src) \
(st)->stream.next_in = (char *)(uintptr_t)(const void *)(src)
(st)->stream.next_in = (char *)(const void *)(src)
static int drive_compressor(struct archive_write_filter *,
struct private_data *, int finishing);

Expand Down
2 changes: 1 addition & 1 deletion libarchive/archive_write_add_filter_compress.c
Expand Up @@ -129,7 +129,7 @@ archive_write_set_compression_compress(struct archive *a)
int
archive_write_add_filter_compress(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f = __archive_write_allocate_filter(_a);

archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
Expand Down
4 changes: 2 additions & 2 deletions libarchive/archive_write_add_filter_gzip.c
Expand Up @@ -76,7 +76,7 @@ struct private_data {
* of ugly hackery to convert a const * pointer to a non-const pointer.
*/
#define SET_NEXT_IN(st,src) \
(st)->stream.next_in = (Bytef *)(uintptr_t)(const void *)(src)
(st)->stream.next_in = (Bytef *)(const void *)(src)

static int archive_compressor_gzip_options(struct archive_write_filter *,
const char *, const char *);
Expand All @@ -97,7 +97,7 @@ static int drive_compressor(struct archive_write_filter *,
int
archive_write_add_filter_gzip(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
Expand Down
4 changes: 3 additions & 1 deletion libarchive/archive_write_add_filter_lrzip.c
Expand Up @@ -41,10 +41,12 @@ __FBSDID("$FreeBSD$");
#include "archive_string.h"
#include "archive_write_private.h"

enum compression_ { lzma = 0, bzip2, gzip, lzo, none, zpaq };

struct write_lrzip {
struct archive_write_program_data *pdata;
int compression_level;
enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression;
enum compression_ compression;
};

static int archive_write_lrzip_open(struct archive_write_filter *);
Expand Down
2 changes: 1 addition & 1 deletion libarchive/archive_write_add_filter_lz4.c
Expand Up @@ -95,7 +95,7 @@ static int archive_filter_lz4_write(struct archive_write_filter *,
int
archive_write_add_filter_lz4(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;

Expand Down
13 changes: 0 additions & 13 deletions libarchive/archive_write_add_filter_program.c
Expand Up @@ -58,19 +58,6 @@ archive_write_set_compression_program(struct archive *a, const char *cmd)
}
#endif

struct archive_write_program_data {
#if defined(_WIN32) && !defined(__CYGWIN__)
HANDLE child;
#else
pid_t child;
#endif
int child_stdin, child_stdout;

char *child_buf;
size_t child_buf_len, child_buf_avail;
char *program_name;
};

struct private_data {
struct archive_write_program_data *pdata;
struct archive_string description;
Expand Down
2 changes: 1 addition & 1 deletion libarchive/archive_write_add_filter_uuencode.c
Expand Up @@ -69,7 +69,7 @@ static int64_t atol8(const char *, size_t);
int
archive_write_add_filter_uuencode(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_uuencode *state;

Expand Down
153 changes: 22 additions & 131 deletions libarchive/archive_write_disk_posix.c
Expand Up @@ -135,6 +135,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_write_disk_private.h"
#include "archive_entry_private.h"

#ifndef O_BINARY
#define O_BINARY 0
Expand All @@ -153,25 +154,6 @@ __FBSDID("$FreeBSD$");
#define O_NOFOLLOW 0
#endif

struct fixup_entry {
struct fixup_entry *next;
struct archive_acl acl;
mode_t mode;
int64_t atime;
int64_t birthtime;
int64_t mtime;
int64_t ctime;
unsigned long atime_nanos;
unsigned long birthtime_nanos;
unsigned long mtime_nanos;
unsigned long ctime_nanos;
unsigned long fflags_set;
size_t mac_metadata_size;
void *mac_metadata;
int fixup; /* bitmask of what needs fixing */
char *name;
};

/*
* We use a bitmask to track which operations remain to be done for
* this file. In particular, this helps us avoid unnecessary
Expand Down Expand Up @@ -201,97 +183,6 @@ struct fixup_entry {
#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA
#define TODO_HFS_COMPRESSION ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED

struct archive_write_disk {
struct archive archive;

mode_t user_umask;
struct fixup_entry *fixup_list;
struct fixup_entry *current_fixup;
int64_t user_uid;
int skip_file_set;
int64_t skip_file_dev;
int64_t skip_file_ino;
time_t start_time;

int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
void (*cleanup_gid)(void *private);
void *lookup_gid_data;
int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
void (*cleanup_uid)(void *private);
void *lookup_uid_data;

/*
* Full path of last file to satisfy symlink checks.
*/
struct archive_string path_safe;

/*
* Cached stat data from disk for the current entry.
* If this is valid, pst points to st. Otherwise,
* pst is null.
*/
struct stat st;
struct stat *pst;

/* Information about the object being restored right now. */
struct archive_entry *entry; /* Entry being extracted. */
char *name; /* Name of entry, possibly edited. */
struct archive_string _name_data; /* backing store for 'name' */
/* Tasks remaining for this object. */
int todo;
/* Tasks deferred until end-of-archive. */
int deferred;
/* Options requested by the client. */
int flags;
/* Handle for the file we're restoring. */
int fd;
/* Current offset for writing data to the file. */
int64_t offset;
/* Last offset actually written to disk. */
int64_t fd_offset;
/* Total bytes actually written to files. */
int64_t total_bytes_written;
/* Maximum size of file, -1 if unknown. */
int64_t filesize;
/* Dir we were in before this restore; only for deep paths. */
int restore_pwd;
/* Mode we should use for this entry; affected by _PERM and umask. */
mode_t mode;
/* UID/GID to use in restoring this entry. */
int64_t uid;
int64_t gid;
/*
* HFS+ Compression.
*/
/* Xattr "com.apple.decmpfs". */
uint32_t decmpfs_attr_size;
unsigned char *decmpfs_header_p;
/* ResourceFork set options used for fsetxattr. */
int rsrc_xattr_options;
/* Xattr "com.apple.ResourceFork". */
unsigned char *resource_fork;
size_t resource_fork_allocated_size;
unsigned int decmpfs_block_count;
uint32_t *decmpfs_block_info;
/* Buffer for compressed data. */
unsigned char *compressed_buffer;
size_t compressed_buffer_size;
size_t compressed_buffer_remaining;
/* The offset of the ResourceFork where compressed data will
* be placed. */
uint32_t compressed_rsrc_position;
uint32_t compressed_rsrc_position_v;
/* Buffer for uncompressed data. */
char *uncompressed_buffer;
size_t block_remaining_bytes;
size_t file_remaining_bytes;
#ifdef HAVE_ZLIB_H
z_stream stream;
int stream_valid;
int decmpfs_compression_level;
#endif
};

/*
* Default mode for dirs created automatically (will be modified by umask).
* Note that POSIX specifies 0777 for implicitly-created dirs, "modified
Expand Down Expand Up @@ -428,7 +319,7 @@ archive_write_disk_vtable(void)
static int64_t
_archive_write_disk_filter_bytes(struct archive *_a, int n)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
(void)n; /* UNUSED */
if (n == -1 || n == 0)
return (a->total_bytes_written);
Expand All @@ -439,7 +330,7 @@ _archive_write_disk_filter_bytes(struct archive *_a, int n)
int
archive_write_disk_set_options(struct archive *_a, int flags)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);

a->flags = flags;
return (ARCHIVE_OK);
Expand All @@ -460,7 +351,7 @@ archive_write_disk_set_options(struct archive *_a, int flags)
static int
_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
struct fixup_entry *fe;
int ret, r;

Expand Down Expand Up @@ -756,7 +647,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)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
a->skip_file_set = 1;
Expand Down Expand Up @@ -1141,7 +1032,7 @@ hfs_drive_compressor(struct archive_write_disk *a, const char *buff,

buffer_compressed = a->compressed_buffer +
a->compressed_buffer_size - a->compressed_buffer_remaining;
a->stream.next_in = (Bytef *)(uintptr_t)(const void *)buff;
a->stream.next_in = (Bytef *)(const void *)buff;
a->stream.avail_in = size;
a->stream.next_out = buffer_compressed;
a->stream.avail_out = a->compressed_buffer_remaining;
Expand Down Expand Up @@ -1465,7 +1356,7 @@ static ssize_t
_archive_write_disk_data_block(struct archive *_a,
const void *buff, size_t size, int64_t offset)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
ssize_t r;

archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
Expand Down Expand Up @@ -1493,7 +1384,7 @@ _archive_write_disk_data_block(struct archive *_a,
static ssize_t
_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);

archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
Expand All @@ -1506,7 +1397,7 @@ _archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
static int
_archive_write_disk_finish_entry(struct archive *_a)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
int ret = ARCHIVE_OK;

archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
Expand Down Expand Up @@ -1705,11 +1596,11 @@ archive_write_disk_set_group_lookup(struct archive *_a,
int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
void (*cleanup_gid)(void *private))
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");

if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
if (a->cleanup_gid != 0 && a->lookup_gid_data != NULL)
(a->cleanup_gid)(a->lookup_gid_data);

a->lookup_gid = lookup_gid;
Expand All @@ -1724,11 +1615,11 @@ archive_write_disk_set_user_lookup(struct archive *_a,
int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
void (*cleanup_uid)(void *private))
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");

if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
if (a->cleanup_uid != 0 && a->lookup_uid_data != NULL)
(a->cleanup_uid)(a->lookup_uid_data);

a->lookup_uid = lookup_uid;
Expand All @@ -1740,7 +1631,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)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_gid");
if (a->lookup_gid)
Expand All @@ -1751,7 +1642,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)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_uid");
if (a->lookup_uid)
Expand All @@ -1762,7 +1653,7 @@ archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
/*
* Create a new archive_write_disk object and initialize it with global state.
*/
struct archive *
struct archive_write_disk *
archive_write_disk_new(void)
{
struct archive_write_disk *a;
Expand All @@ -1775,7 +1666,7 @@ archive_write_disk_new(void)
/* We're ready to write a header immediately. */
a->archive.state = ARCHIVE_STATE_HEADER;
a->archive.vtable = archive_write_disk_vtable();
a->start_time = time(NULL);
a->start_time = time((time_t *)NULL);
/* Query and restore the umask. */
umask(a->user_umask = umask(0));
#ifdef HAVE_GETEUID
Expand All @@ -1788,7 +1679,7 @@ archive_write_disk_new(void)
#ifdef HAVE_ZLIB_H
a->decmpfs_compression_level = 5;
#endif
return (&a->archive);
return a;
}


Expand Down Expand Up @@ -2203,7 +2094,7 @@ create_filesystem_object(struct archive_write_disk *a)
static int
_archive_write_disk_close(struct archive *_a)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct archive_write_disk *a = _containerof(_a, struct archive_write_disk, archive);
struct fixup_entry *next, *p;
int ret;

Expand Down Expand Up @@ -2255,10 +2146,10 @@ _archive_write_disk_free(struct archive *_a)
return (ARCHIVE_OK);
archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
a = (struct archive_write_disk *)_a;
a = _containerof(_a, struct archive_write_disk, archive);
ret = _archive_write_disk_close(&a->archive);
archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
archive_write_disk_set_group_lookup(&a->archive, NULL, 0, 0);
archive_write_disk_set_user_lookup(&a->archive, NULL, 0, 0);
if (a->entry)
archive_entry_free(a->entry);
archive_string_free(&a->_name_data);
Expand Down
113 changes: 112 additions & 1 deletion libarchive/archive_write_disk_private.h
Expand Up @@ -34,8 +34,119 @@
#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED

#include "archive_acl_private.h"
#include "archive_private.h"
#include "archive_entry_private.h"

struct fixup_entry {
struct fixup_entry *next;
struct archive_acl acl;
mode_t mode;
int64_t atime;
int64_t birthtime;
int64_t mtime;
int64_t ctime;
unsigned long atime_nanos;
unsigned long birthtime_nanos;
unsigned long mtime_nanos;
unsigned long ctime_nanos;
unsigned long fflags_set;
size_t mac_metadata_size;
void *mac_metadata;
int fixup; /* bitmask of what needs fixing */
char *name;
};

struct archive_write_disk {
struct archive archive;

mode_t user_umask;
struct fixup_entry *fixup_list;
struct fixup_entry *current_fixup;
int64_t user_uid;
int skip_file_set;
int64_t skip_file_dev;
int64_t skip_file_ino;
time_t start_time;

int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
void (*cleanup_gid)(void *private);
void *lookup_gid_data;
int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
void (*cleanup_uid)(void *private);
void *lookup_uid_data;

/*
* Full path of last file to satisfy symlink checks.
*/
struct archive_string path_safe;

/*
* Cached stat data from disk for the current entry.
* If this is valid, pst points to st. Otherwise,
* pst is null.
*/
struct stat st;
struct stat *pst;

/* Information about the object being restored right now. */
struct archive_entry *entry; /* Entry being extracted. */
char *name; /* Name of entry, possibly edited. */
struct archive_string _name_data; /* backing store for 'name' */
/* Tasks remaining for this object. */
int todo;
/* Tasks deferred until end-of-archive. */
int deferred;
/* Options requested by the client. */
int flags;
/* Handle for the file we're restoring. */
int fd;
/* Current offset for writing data to the file. */
int64_t offset;
/* Last offset actually written to disk. */
int64_t fd_offset;
/* Total bytes actually written to files. */
int64_t total_bytes_written;
/* Maximum size of file, -1 if unknown. */
int64_t filesize;
/* Dir we were in before this restore; only for deep paths. */
int restore_pwd;
/* Mode we should use for this entry; affected by _PERM and umask. */
mode_t mode;
/* UID/GID to use in restoring this entry. */
int64_t uid;
int64_t gid;
/*
* HFS+ Compression.
*/
/* Xattr "com.apple.decmpfs". */
uint32_t decmpfs_attr_size;
unsigned char *decmpfs_header_p;
/* ResourceFork set options used for fsetxattr. */
int rsrc_xattr_options;
/* Xattr "com.apple.ResourceFork". */
unsigned char *resource_fork;
size_t resource_fork_allocated_size;
unsigned int decmpfs_block_count;
uint32_t *decmpfs_block_info;
/* Buffer for compressed data. */
unsigned char *compressed_buffer;
size_t compressed_buffer_size;
size_t compressed_buffer_remaining;
/* The offset of the ResourceFork where compressed data will
* be placed. */
uint32_t compressed_rsrc_position;
uint32_t compressed_rsrc_position_v;
/* Buffer for uncompressed data. */
char *uncompressed_buffer;
size_t block_remaining_bytes;
size_t file_remaining_bytes;
#ifdef HAVE_ZLIB_H
z_stream stream;
int stream_valid;
int decmpfs_compression_level;
#endif
};

struct archive_write_disk;

int
archive_write_disk_set_acls(struct archive *, int /* fd */, const char * /* pathname */, struct archive_acl *);
Expand Down
5 changes: 3 additions & 2 deletions libarchive/archive_write_disk_set_standard_lookup.c
Expand Up @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk_set_standard_lookup.c
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_write_disk_private.h"
#include "archive_entry_private.h"

struct bucket {
char *name;
Expand Down Expand Up @@ -239,10 +240,10 @@ lookup_uid(void *private_data, const char *uname, int64_t uid)
}

static void
cleanup(void *private)
cleanup(void *priv)
{
size_t i;
struct bucket *cache = (struct bucket *)private;
struct bucket *cache = (struct bucket *)priv;

for (i = 0; i < cache_size; i++)
free(cache[i].name);
Expand Down
13 changes: 13 additions & 0 deletions libarchive/archive_write_private.h
Expand Up @@ -128,6 +128,19 @@ struct archive_write {
void *passphrase_client_data;
};

struct archive_write_program_data {
#if defined(_WIN32) && !defined(__CYGWIN__)
HANDLE child;
#else
pid_t child;
#endif
int child_stdin, child_stdout;

char *child_buf;
size_t child_buf_len, child_buf_avail;
char *program_name;
};

/*
* Utility function to format a USTAR header into a buffer. If
* "strict" is set, this tries to create the absolutely most portable
Expand Down
4 changes: 2 additions & 2 deletions libarchive/archive_write_set_format.c
Expand Up @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format.c 201168 2009-1

/* A table that maps format codes to functions. */
static
struct { int code; int (*setter)(struct archive *); } codes[] =
struct codes_ { int code; int (*setter)(struct archive *); } codes[] =
{
{ ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip },
{ ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio },
Expand All @@ -60,7 +60,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
{ ARCHIVE_FORMAT_WARC, archive_write_set_format_warc },
{ ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
{ ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
{ 0, NULL }
{ 0, 0 }
};

int
Expand Down
47 changes: 26 additions & 21 deletions libarchive/archive_write_set_format_7zip.c
Expand Up @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include "archive_rb.h"
#include "archive_string.h"
#include "archive_write_private.h"
#include "archive_entry_private.h"

/*
* Codec ID
Expand Down Expand Up @@ -139,6 +140,11 @@ struct coder {
uint8_t *props;
};

struct times_ {
time_t time;
long time_ns;
};

struct file {
struct archive_rb_node rbnode;

Expand All @@ -153,10 +159,7 @@ struct file {
#define CRC32_IS_SET (1<<3)
#define HAS_STREAM (1<<4)

struct {
time_t time;
long time_ns;
} times[3];
struct times_ times[3];
#define MTIME 0
#define ATIME 1
#define CTIME 2
Expand All @@ -167,6 +170,11 @@ struct file {
int dir:1;
};

struct file_ {
struct file *first;
struct file **last;
};

struct _7zip {
int temp_fd;
uint64_t temp_offset;
Expand Down Expand Up @@ -207,10 +215,7 @@ struct _7zip {
* manage struct file objects.
* We use 'next' a menber of struct file to chain.
*/
struct {
struct file *first;
struct file **last;
} file_list, empty_list;
struct file_ file_list, empty_list;
struct archive_rb_tree rbtree;/* for empty files */
};

Expand Down Expand Up @@ -287,14 +292,14 @@ archive_write_set_format_7zip(struct archive *_a)
static const struct archive_rb_tree_ops rb_ops = {
file_cmp_node, file_cmp_key
};
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct _7zip *zip;

archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_format_7zip");

/* If another format was already registered, unregister it. */
if (a->format_free != NULL)
if (a->format_free != 0)
(a->format_free)(a);

zip = calloc(1, sizeof(*zip));
Expand Down Expand Up @@ -444,7 +449,7 @@ _7z_write_header(struct archive_write *a, struct archive_entry *entry)
}
if (file->size == 0 && file->dir) {
if (!__archive_rb_tree_insert_node(&(zip->rbtree),
(struct archive_rb_node *)file)) {
_containerof(file, struct archive_rb_node, rb_nodes))) {
/* We have already had the same file. */
file_free(file);
return (ARCHIVE_OK);
Expand Down Expand Up @@ -744,7 +749,7 @@ _7z_close(struct archive_write *a)
}
/* Connect a directory file list. */
ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
file_register(zip, (struct file *)n);
file_register(zip, _containerof(n, struct file, rbnode));
}

/*
Expand Down Expand Up @@ -1466,8 +1471,8 @@ static int
file_cmp_node(const struct archive_rb_node *n1,
const struct archive_rb_node *n2)
{
const struct file *f1 = (const struct file *)n1;
const struct file *f2 = (const struct file *)n2;
const struct file *f1 = _containerof(n1, struct file, rbnode);
const struct file *f2 = _containerof(n2, struct file, rbnode);

if (f1->name_len == f2->name_len)
return (memcmp(f1->utf16name, f2->utf16name, f1->name_len));
Expand All @@ -1477,7 +1482,7 @@ file_cmp_node(const struct archive_rb_node *n1,
static int
file_cmp_key(const struct archive_rb_node *n, const void *key)
{
const struct file *f = (const struct file *)n;
const struct file *f = _containerof(n, struct file, rbnode);

return (f->name_len - *(const char *)key);
}
Expand Down Expand Up @@ -1688,7 +1693,7 @@ compression_init_encoder_deflate(struct archive *a,
/* zlib.h is not const-correct, so we need this one bit
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
strm->next_in = (Bytef *)(const void *)lastrm->next_in;
strm->avail_in = (uInt)lastrm->avail_in;
strm->total_in = (uLong)lastrm->total_in;
strm->next_out = lastrm->next_out;
Expand Down Expand Up @@ -1721,7 +1726,7 @@ compression_code_deflate(struct archive *a,
/* zlib.h is not const-correct, so we need this one bit
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
strm->next_in = (Bytef *)(const void *)lastrm->next_in;
strm->avail_in = (uInt)lastrm->avail_in;
strm->total_in = (uLong)lastrm->total_in;
strm->next_out = lastrm->next_out;
Expand Down Expand Up @@ -1801,7 +1806,7 @@ compression_init_encoder_bzip2(struct archive *a,
/* bzlib.h is not const-correct, so we need this one bit
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
strm->next_in = (char *)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
Expand Down Expand Up @@ -1834,7 +1839,7 @@ compression_code_bzip2(struct archive *a,
/* bzlib.h is not const-correct, so we need this one bit
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
strm->next_in = (char *)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
Expand Down Expand Up @@ -2099,7 +2104,7 @@ static void *
ppmd_alloc(void *p, size_t size)
{
(void)p;
return malloc(size);
return (CPpmd7 *)malloc(size);
}
static void
ppmd_free(void *p, void *address)
Expand Down Expand Up @@ -2177,7 +2182,7 @@ compression_init_encoder_ppmd(struct archive *a,
return (ARCHIVE_FATAL);
}
__archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder);
strm->byteout.a = (struct archive_write *)a;
strm->byteout.a = _containerof(a, struct archive_write, archive);
strm->byteout.Write = ppmd_write;
strm->range_enc.Stream = &(strm->byteout);
__archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc));
Expand Down
8 changes: 4 additions & 4 deletions libarchive/archive_write_set_format_ar.c
Expand Up @@ -85,7 +85,7 @@ static int format_decimal(int64_t v, char *p, int s);
int
archive_write_set_format_ar_bsd(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
int r;

archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
Expand All @@ -101,7 +101,7 @@ archive_write_set_format_ar_bsd(struct archive *_a)
int
archive_write_set_format_ar_svr4(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
int r;

archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
Expand All @@ -123,7 +123,7 @@ archive_write_set_format_ar(struct archive_write *a)
struct ar_w *ar;

/* If someone else was already registered, unregister them. */
if (a->format_free != NULL)
if (a->format_free != 0)
(a->format_free)(a);

ar = (struct ar_w *)malloc(sizeof(*ar));
Expand Down Expand Up @@ -381,7 +381,7 @@ archive_write_ar_data(struct archive_write *a, const void *buff, size_t s)
"Can't allocate strtab buffer");
return (ARCHIVE_FATAL);
}
strncpy(ar->strtab, buff, s);
strncpy(ar->strtab, (const char *)buff, s);
ar->has_strtab = 1;
}

Expand Down
4 changes: 2 additions & 2 deletions libarchive/archive_write_set_format_by_name.c
Expand Up @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 20116

/* A table that maps names to functions. */
static
struct { const char *name; int (*setter)(struct archive *); } names[] =
struct names_ { const char *name; int (*setter)(struct archive *); } names[] =
{
{ "7zip", archive_write_set_format_7zip },
{ "ar", archive_write_set_format_ar_bsd },
Expand Down Expand Up @@ -73,7 +73,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
{ "warc", archive_write_set_format_warc },
{ "xar", archive_write_set_format_xar },
{ "zip", archive_write_set_format_zip },
{ NULL, NULL }
{ NULL, 0 }
};

int
Expand Down
15 changes: 9 additions & 6 deletions libarchive/archive_write_set_format_cpio.c
Expand Up @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_entry_private.h"

static ssize_t archive_write_cpio_data(struct archive_write *,
const void *buff, size_t s);
Expand All @@ -57,12 +58,14 @@ static int format_octal(int64_t, void *, int);
static int64_t format_octal_recursive(int64_t, char *, int);
static int write_header(struct archive_write *, struct archive_entry *);

struct ino_ { int64_t old; int fresh;};

struct cpio {
uint64_t entry_bytes_remaining;

int64_t ino_next;

struct { int64_t old; int new;} *ino_list;
struct ino_ *ino_list;
size_t ino_list_size;
size_t ino_list_next;

Expand Down Expand Up @@ -100,14 +103,14 @@ struct cpio {
int
archive_write_set_format_cpio(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct cpio *cpio;

archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_format_cpio");

/* If someone else was already registered, unregister them. */
if (a->format_free != NULL)
if (a->format_free != 0)
(a->format_free)(a);

cpio = (struct cpio *)calloc(1, sizeof(*cpio));
Expand Down Expand Up @@ -196,7 +199,7 @@ synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
* and we reuse the same value. */
for (i = 0; i < cpio->ino_list_next; ++i) {
if (cpio->ino_list[i].old == ino)
return (cpio->ino_list[i].new);
return (cpio->ino_list[i].fresh);
}

/* Assign a new index number. */
Expand All @@ -206,7 +209,7 @@ synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
if (cpio->ino_list_size <= cpio->ino_list_next) {
size_t newsize = cpio->ino_list_size < 512
? 512 : cpio->ino_list_size * 2;
void *newlist = realloc(cpio->ino_list,
struct ino_ *newlist = realloc(cpio->ino_list,
sizeof(cpio->ino_list[0]) * newsize);
if (newlist == NULL)
return (-1);
Expand All @@ -217,7 +220,7 @@ synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)

/* Record and return the new value. */
cpio->ino_list[cpio->ino_list_next].old = ino;
cpio->ino_list[cpio->ino_list_next].new = ino_new;
cpio->ino_list[cpio->ino_list_next].fresh = ino_new;
++cpio->ino_list_next;
return (ino_new);
}
Expand Down
5 changes: 3 additions & 2 deletions libarchive/archive_write_set_format_cpio_newc.c
Expand Up @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio_newc.c 201
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_entry_private.h"

static ssize_t archive_write_newc_data(struct archive_write *,
const void *buff, size_t s);
Expand Down Expand Up @@ -106,14 +107,14 @@ struct cpio {
int
archive_write_set_format_cpio_newc(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct cpio *cpio;

archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_newc");

/* If someone else was already registered, unregister them. */
if (a->format_free != NULL)
if (a->format_free != 0)
(a->format_free)(a);

cpio = (struct cpio *)malloc(sizeof(*cpio));
Expand Down
4 changes: 2 additions & 2 deletions libarchive/archive_write_set_format_filter_by_ext.c
Expand Up @@ -43,7 +43,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 20116

/* A table that maps names to functions. */
static
struct { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *); } names[] =
struct names_ { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *); } names[] =
{
{ ".7z", archive_write_set_format_7zip, archive_write_add_filter_none},
{ ".zip", archive_write_set_format_zip, archive_write_add_filter_none},
Expand All @@ -62,7 +62,7 @@ struct { const char *name; int (*format)(struct archive *); int (*filter)(struct
{ ".tar.gz", archive_write_set_format_pax_restricted, archive_write_add_filter_gzip},
{ ".tar.bz2", archive_write_set_format_pax_restricted, archive_write_add_filter_bzip2},
{ ".tar.xz", archive_write_set_format_pax_restricted, archive_write_add_filter_xz},
{ NULL, NULL, NULL }
{ NULL, 0, 0 }
};

static
Expand Down
3 changes: 2 additions & 1 deletion libarchive/archive_write_set_format_gnutar.c
Expand Up @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 19157
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_entry_private.h"

struct gnutar {
uint64_t entry_bytes_remaining;
Expand Down Expand Up @@ -172,7 +173,7 @@ static int format_octal(int64_t, char *, int);
int
archive_write_set_format_gnutar(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write *a = _containerof(_a, struct archive_write, archive);
struct gnutar *gnutar;

gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar));
Expand Down