MFV r368207:
Update libarchive to 3.5.0 Relevant vendor changes: Issue #1258: add archive_read_support_filter_by_code() PR #1347: mtree digest reader support Issue #1381: skip hardlinks pointing to itself on extraction PR #1387: fix writing of cpio archives with hardlinks without file type PR #1388: fix rdev field in cpio format for device nodes PR #1389: completed support for UTF-8 encoding conversion PR #1405: more formats in archive_read_support_format_by_code() PR #1408: fix uninitialized size in rar5_read_data PR #1409: system extended attribute support PR #1435: support for decompression of symbolic links in zipx archives Issue #1456: memory leak after unsuccessful archive_write_open_filename MFC after: 1 week
This commit is contained in:
commit
c3afd20f13
@ -15,7 +15,6 @@ the actual statements in the files are controlling.
|
||||
* The following source files are also subject in whole or in part to
|
||||
a 3-clause UC Regents copyright; please read the individual source
|
||||
files for details:
|
||||
libarchive/archive_entry.c
|
||||
libarchive/archive_read_support_filter_compress.c
|
||||
libarchive/archive_write_add_filter_compress.c
|
||||
libarchive/mtree.5
|
||||
|
@ -1,3 +1,7 @@
|
||||
Dec 01, 2020: libarchive 3.5.0 released
|
||||
|
||||
Oct 14, 2020: Support for system extended attributes
|
||||
|
||||
May 20, 2020: libarchive 3.4.3 released
|
||||
|
||||
Apr 30, 2020: Support for pzstd compressed files
|
||||
|
@ -36,7 +36,7 @@
|
||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3004003
|
||||
#define ARCHIVE_VERSION_NUMBER 3005000
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
|
||||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.4.3"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.5.0"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
@ -246,6 +246,8 @@ typedef int archive_open_callback(struct archive *, void *_client_data);
|
||||
|
||||
typedef int archive_close_callback(struct archive *, void *_client_data);
|
||||
|
||||
typedef int archive_free_callback(struct archive *, void *_client_data);
|
||||
|
||||
/* Switches from one client data object to the next/prev client data object.
|
||||
* This is useful for reading from different data blocks such as a set of files
|
||||
* that make up one large file.
|
||||
@ -418,6 +420,7 @@ __LA_DECL int archive_read_support_compression_xz(struct archive *)
|
||||
#endif
|
||||
|
||||
__LA_DECL int archive_read_support_filter_all(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_by_code(struct archive *, int);
|
||||
__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_compress(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
|
||||
@ -817,9 +820,13 @@ __LA_DECL int archive_write_set_format_filter_by_ext(struct archive *a, const ch
|
||||
__LA_DECL int archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext);
|
||||
__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
|
||||
__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
|
||||
/* Deprecated; use archive_write_open2 instead */
|
||||
__LA_DECL int archive_write_open(struct archive *, void *,
|
||||
archive_open_callback *, archive_write_callback *,
|
||||
archive_close_callback *);
|
||||
__LA_DECL int archive_write_open2(struct archive *, void *,
|
||||
archive_open_callback *, archive_write_callback *,
|
||||
archive_close_callback *, archive_free_callback *);
|
||||
__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
|
||||
__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
|
||||
__LA_DECL int archive_write_open_filename_w(struct archive *,
|
||||
|
@ -595,7 +595,7 @@ archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
|
||||
else
|
||||
length += sizeof(uid_t) * 3 + 1;
|
||||
} else {
|
||||
r = archive_mstring_get_mbs_l(&ap->name, &name,
|
||||
r = archive_mstring_get_mbs_l(a, &ap->name, &name,
|
||||
&len, sc);
|
||||
if (r != 0)
|
||||
return (0);
|
||||
@ -968,7 +968,7 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
else
|
||||
prefix = NULL;
|
||||
r = archive_mstring_get_mbs_l(
|
||||
&ap->name, &name, &len, sc);
|
||||
NULL, &ap->name, &name, &len, sc);
|
||||
if (r != 0) {
|
||||
free(s);
|
||||
return (NULL);
|
||||
@ -1402,14 +1402,14 @@ isint_w(const wchar_t *start, const wchar_t *end, int *result)
|
||||
if (start >= end)
|
||||
return (0);
|
||||
while (start < end) {
|
||||
if (*start < '0' || *start > '9')
|
||||
if (*start < L'0' || *start > L'9')
|
||||
return (0);
|
||||
if (n > (INT_MAX / 10) ||
|
||||
(n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
|
||||
(n == INT_MAX / 10 && (*start - L'0') > INT_MAX % 10)) {
|
||||
n = INT_MAX;
|
||||
} else {
|
||||
n *= 10;
|
||||
n += *start - '0';
|
||||
n += *start - L'0';
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ errmsg(const char *m)
|
||||
ssize_t written;
|
||||
|
||||
while (s > 0) {
|
||||
written = write(2, m, strlen(m));
|
||||
written = write(2, m, s);
|
||||
if (written <= 0)
|
||||
return;
|
||||
m += written;
|
||||
|
@ -347,8 +347,31 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
#if NETTLE_VERSION_MAJOR < 3
|
||||
aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
|
||||
aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);
|
||||
#else
|
||||
switch(ctx->key_len) {
|
||||
case AES128_KEY_SIZE:
|
||||
aes128_set_encrypt_key(&ctx->ctx.c128, ctx->key);
|
||||
aes128_encrypt(&ctx->ctx.c128, AES_BLOCK_SIZE, ctx->encr_buf,
|
||||
ctx->nonce);
|
||||
break;
|
||||
case AES192_KEY_SIZE:
|
||||
aes192_set_encrypt_key(&ctx->ctx.c192, ctx->key);
|
||||
aes192_encrypt(&ctx->ctx.c192, AES_BLOCK_SIZE, ctx->encr_buf,
|
||||
ctx->nonce);
|
||||
break;
|
||||
case AES256_KEY_SIZE:
|
||||
aes256_set_encrypt_key(&ctx->ctx.c256, ctx->key);
|
||||
aes256_encrypt(&ctx->ctx.c256, AES_BLOCK_SIZE, ctx->encr_buf,
|
||||
ctx->nonce);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -104,9 +104,18 @@ typedef struct {
|
||||
#include <nettle/pbkdf2.h>
|
||||
#endif
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/version.h>
|
||||
|
||||
typedef struct {
|
||||
#if NETTLE_VERSION_MAJOR < 3
|
||||
struct aes_ctx ctx;
|
||||
#else
|
||||
union {
|
||||
struct aes128_ctx c128;
|
||||
struct aes192_ctx c192;
|
||||
struct aes256_ctx c256;
|
||||
} ctx;
|
||||
#endif
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
|
@ -30,6 +30,10 @@
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#ifndef __LIBARCHIVE_CONFIG_H_INCLUDED
|
||||
#error "Should have include config.h first!"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Crypto support in various Operating Systems:
|
||||
*
|
||||
|
@ -208,6 +208,19 @@ archive_entry_clone(struct archive_entry *entry)
|
||||
|
||||
/* Copy encryption status */
|
||||
entry2->encryption = entry->encryption;
|
||||
|
||||
/* Copy digests */
|
||||
#define copy_digest(_e2, _e, _t) \
|
||||
memcpy(_e2->digest._t, _e->digest._t, sizeof(_e2->digest._t))
|
||||
|
||||
copy_digest(entry2, entry, md5);
|
||||
copy_digest(entry2, entry, rmd160);
|
||||
copy_digest(entry2, entry, sha1);
|
||||
copy_digest(entry2, entry, sha256);
|
||||
copy_digest(entry2, entry, sha384);
|
||||
copy_digest(entry2, entry, sha512);
|
||||
|
||||
#undef copy_digest
|
||||
|
||||
/* Copy ACL data over. */
|
||||
archive_acl_copy(&entry2->acl, &entry->acl);
|
||||
@ -450,7 +463,7 @@ int
|
||||
_archive_entry_gname_l(struct archive_entry *entry,
|
||||
const char **p, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_gname, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
|
||||
}
|
||||
|
||||
const char *
|
||||
@ -504,7 +517,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
|
||||
*len = 0;
|
||||
return (0);
|
||||
}
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
|
||||
}
|
||||
|
||||
la_int64_t
|
||||
@ -595,7 +608,7 @@ int
|
||||
_archive_entry_pathname_l(struct archive_entry *entry,
|
||||
const char **p, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_pathname, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_pathname, p, len, sc));
|
||||
}
|
||||
|
||||
__LA_MODE_T
|
||||
@ -723,7 +736,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
|
||||
*len = 0;
|
||||
return (0);
|
||||
}
|
||||
return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
|
||||
}
|
||||
|
||||
la_int64_t
|
||||
@ -769,7 +782,7 @@ int
|
||||
_archive_entry_uname_l(struct archive_entry *entry,
|
||||
const char **p, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_uname, p, len, sc));
|
||||
}
|
||||
|
||||
int
|
||||
@ -1416,6 +1429,62 @@ archive_entry_copy_mac_metadata(struct archive_entry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
/* Digest handling */
|
||||
const unsigned char *
|
||||
archive_entry_digest(struct archive_entry *entry, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_DIGEST_MD5:
|
||||
return entry->digest.md5;
|
||||
case ARCHIVE_ENTRY_DIGEST_RMD160:
|
||||
return entry->digest.rmd160;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA1:
|
||||
return entry->digest.sha1;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA256:
|
||||
return entry->digest.sha256;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA384:
|
||||
return entry->digest.sha384;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA512:
|
||||
return entry->digest.sha512;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_set_digest(struct archive_entry *entry, int type,
|
||||
const unsigned char *digest)
|
||||
{
|
||||
#define copy_digest(_e, _t, _d)\
|
||||
memcpy(_e->digest._t, _d, sizeof(_e->digest._t))
|
||||
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_DIGEST_MD5:
|
||||
copy_digest(entry, md5, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_RMD160:
|
||||
copy_digest(entry, rmd160, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA1:
|
||||
copy_digest(entry, sha1, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA256:
|
||||
copy_digest(entry, sha256, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA384:
|
||||
copy_digest(entry, sha384, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA512:
|
||||
copy_digest(entry, sha512, digest);
|
||||
break;
|
||||
default:
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
|
||||
return ARCHIVE_OK;
|
||||
#undef copy_digest
|
||||
}
|
||||
|
||||
/*
|
||||
* ACL management. The following would, of course, be a lot simpler
|
||||
* if: 1) the last draft of POSIX.1e were a really thorough and
|
||||
|
@ -30,7 +30,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3004003
|
||||
#define ARCHIVE_VERSION_NUMBER 3005000
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
@ -396,6 +396,19 @@ __LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat
|
||||
__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
|
||||
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
|
||||
|
||||
/*
|
||||
* Digest routine. This is used to query the raw hex digest for the
|
||||
* given entry. The type of digest is provided as an argument.
|
||||
*/
|
||||
#define ARCHIVE_ENTRY_DIGEST_MD5 0x00000001
|
||||
#define ARCHIVE_ENTRY_DIGEST_RMD160 0x00000002
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA1 0x00000003
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA256 0x00000004
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA384 0x00000005
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA512 0x00000006
|
||||
|
||||
__LA_DECL const unsigned char * archive_entry_digest(struct archive_entry *, int /* type */);
|
||||
|
||||
/*
|
||||
* ACL routines. This used to simply store and return text-format ACL
|
||||
* strings, but that proved insufficient for a number of reasons:
|
||||
|
@ -50,6 +50,15 @@ struct ae_sparse {
|
||||
int64_t length;
|
||||
};
|
||||
|
||||
struct ae_digest {
|
||||
unsigned char md5[16];
|
||||
unsigned char rmd160[20];
|
||||
unsigned char sha1[20];
|
||||
unsigned char sha256[32];
|
||||
unsigned char sha384[48];
|
||||
unsigned char sha512[64];
|
||||
};
|
||||
|
||||
/*
|
||||
* Description of an archive entry.
|
||||
*
|
||||
@ -162,6 +171,9 @@ struct archive_entry {
|
||||
void *mac_metadata;
|
||||
size_t mac_metadata_size;
|
||||
|
||||
/* Digest support. */
|
||||
struct ae_digest digest;
|
||||
|
||||
/* ACL support. */
|
||||
struct archive_acl acl;
|
||||
|
||||
@ -181,4 +193,8 @@ struct archive_entry {
|
||||
int ae_symlink_type;
|
||||
};
|
||||
|
||||
int
|
||||
archive_entry_set_digest(struct archive_entry *entry, int type,
|
||||
const unsigned char *digest);
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
||||
|
@ -4,7 +4,7 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "archive_ppmd7_private.h"
|
||||
|
||||
|
@ -103,6 +103,10 @@ __FBSDID("$FreeBSD");
|
||||
|
||||
static int setup_mac_metadata(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
#ifdef ARCHIVE_XATTR_FREEBSD
|
||||
static int setup_xattrs_namespace(struct archive_read_disk *,
|
||||
struct archive_entry *, int *, int);
|
||||
#endif
|
||||
static int setup_xattrs(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
static int setup_sparse(struct archive_read_disk *,
|
||||
@ -701,14 +705,13 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
|
||||
}
|
||||
|
||||
static int
|
||||
setup_xattrs(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
setup_xattrs_namespace(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd, int namespace)
|
||||
{
|
||||
char buff[512];
|
||||
char *list, *p;
|
||||
ssize_t list_size;
|
||||
const char *path;
|
||||
int namespace = EXTATTR_NAMESPACE_USER;
|
||||
|
||||
path = NULL;
|
||||
|
||||
@ -727,6 +730,8 @@ setup_xattrs(struct archive_read_disk *a,
|
||||
|
||||
if (list_size == -1 && errno == EOPNOTSUPP)
|
||||
return (ARCHIVE_OK);
|
||||
if (list_size == -1 && errno == EPERM)
|
||||
return (ARCHIVE_OK);
|
||||
if (list_size == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't list extended attributes");
|
||||
@ -760,7 +765,17 @@ setup_xattrs(struct archive_read_disk *a,
|
||||
size_t len = 255 & (int)*p;
|
||||
char *name;
|
||||
|
||||
strcpy(buff, "user.");
|
||||
if (namespace == EXTATTR_NAMESPACE_SYSTEM) {
|
||||
if (!strcmp(p + 1, "nfs4.acl") ||
|
||||
!strcmp(p + 1, "posix1e.acl_access") ||
|
||||
!strcmp(p + 1, "posix1e.acl_default")) {
|
||||
p += 1 + len;
|
||||
continue;
|
||||
}
|
||||
strcpy(buff, "system.");
|
||||
} else {
|
||||
strcpy(buff, "user.");
|
||||
}
|
||||
name = buff + strlen(buff);
|
||||
memcpy(name, p + 1, len);
|
||||
name[len] = '\0';
|
||||
@ -772,6 +787,31 @@ setup_xattrs(struct archive_read_disk *a,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
setup_xattrs(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
int namespaces[2];
|
||||
int i, res;
|
||||
|
||||
namespaces[0] = EXTATTR_NAMESPACE_USER;
|
||||
namespaces[1] = EXTATTR_NAMESPACE_SYSTEM;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
res = setup_xattrs_namespace(a, entry, fd,
|
||||
namespaces[i]);
|
||||
switch (res) {
|
||||
case (ARCHIVE_OK):
|
||||
case (ARCHIVE_WARN):
|
||||
break;
|
||||
default:
|
||||
return (res);
|
||||
}
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 14, 2014
|
||||
.Dd June 9, 2020
|
||||
.Dt ARCHIVE_READ_FILTER 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -50,6 +50,8 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_all "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_by_code "struct archive *" "int"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_bzip2 "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_compress "struct archive *"
|
||||
@ -116,6 +118,14 @@ Note that
|
||||
is always enabled by default.
|
||||
.It Fn archive_read_support_filter_all
|
||||
Enables all available decompression filters.
|
||||
.It Fn archive_read_support_filter_by_code
|
||||
Enables a single filter specified by the filter code.
|
||||
This function does not work with
|
||||
.Cm ARCHIVE_FILTER_PROGRAM .
|
||||
Note: In statically-linked executables, this will cause
|
||||
your program to include support for every filter.
|
||||
If executable size is a concern, you may wish to avoid
|
||||
using this function.
|
||||
.It Fn archive_read_support_filter_program
|
||||
Data is fed through the specified external program before being dearchived.
|
||||
Note that this disables automatic detection of the compression format,
|
||||
|
@ -61,6 +61,9 @@ archive_read_set_format(struct archive *_a, int code)
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
strcpy(str, "cpio");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_EMPTY:
|
||||
strcpy(str, "empty");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
strcpy(str, "iso9660");
|
||||
break;
|
||||
@ -76,9 +79,15 @@ archive_read_set_format(struct archive *_a, int code)
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
strcpy(str, "rar5");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAW:
|
||||
strcpy(str, "raw");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
strcpy(str, "tar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_WARC:
|
||||
strcpy(str, "warc");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
strcpy(str, "xar");
|
||||
break;
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*-
|
||||
* Copyright (c) 2020 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
int
|
||||
archive_read_support_filter_by_code(struct archive *a, int filter_code)
|
||||
{
|
||||
archive_check_magic(a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_by_code");
|
||||
|
||||
switch (filter_code) {
|
||||
case ARCHIVE_FILTER_NONE:
|
||||
return archive_read_support_filter_none(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_GZIP:
|
||||
return archive_read_support_filter_gzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_BZIP2:
|
||||
return archive_read_support_filter_bzip2(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_COMPRESS:
|
||||
return archive_read_support_filter_compress(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZMA:
|
||||
return archive_read_support_filter_lzma(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_XZ:
|
||||
return archive_read_support_filter_xz(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_UU:
|
||||
return archive_read_support_filter_uu(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_RPM:
|
||||
return archive_read_support_filter_rpm(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZIP:
|
||||
return archive_read_support_filter_lzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LRZIP:
|
||||
return archive_read_support_filter_lrzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZOP:
|
||||
return archive_read_support_filter_lzop(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_GRZIP:
|
||||
return archive_read_support_filter_grzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZ4:
|
||||
return archive_read_support_filter_lz4(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_ZSTD:
|
||||
return archive_read_support_filter_zstd(a);
|
||||
break;
|
||||
}
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
@ -26,6 +26,10 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
@ -48,6 +52,9 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
return archive_read_support_format_cpio(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_EMPTY:
|
||||
return archive_read_support_format_empty(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
return archive_read_support_format_iso9660(a);
|
||||
break;
|
||||
@ -63,9 +70,15 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
return archive_read_support_format_rar5(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAW:
|
||||
return archive_read_support_format_raw(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
return archive_read_support_format_tar(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_WARC:
|
||||
return archive_read_support_format_warc(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
return archive_read_support_format_xar(a);
|
||||
break;
|
||||
@ -73,5 +86,7 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
|
||||
return archive_read_support_format_zip(a);
|
||||
break;
|
||||
}
|
||||
archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Invalid format code specified");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
@ -1172,7 +1172,7 @@ cab_checksum_finish(struct archive_read *a)
|
||||
cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
|
||||
if (cfdata->sum_calculated != cfdata->sum) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Checksum error CFDATA[%d] %x:%x in %d bytes",
|
||||
"Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
|
||||
cab->entry_cffolder->cfdata_index -1,
|
||||
cfdata->sum, cfdata->sum_calculated,
|
||||
cfdata->compressed_size);
|
||||
|
@ -47,7 +47,7 @@ archive_read_support_format_empty(struct archive *_a)
|
||||
|
||||
r = __archive_read_register_format(a,
|
||||
NULL,
|
||||
NULL,
|
||||
"empty",
|
||||
archive_read_format_empty_bid,
|
||||
NULL,
|
||||
archive_read_format_empty_read_header,
|
||||
|
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_entry_private.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_rb.h"
|
||||
#include "archive_read_private.h"
|
||||
@ -1482,6 +1483,84 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
|
||||
#undef MAX_PACK_ARGS
|
||||
}
|
||||
|
||||
static int
|
||||
parse_hex_nibble(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return 10 + c - 'a';
|
||||
#if 0
|
||||
/* XXX: Is uppercase something we should support? */
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return 10 + c - 'A';
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_digest(struct archive_read *a, struct archive_entry *entry,
|
||||
const char *digest, int type)
|
||||
{
|
||||
unsigned char digest_buf[64];
|
||||
int high, low;
|
||||
size_t i, j, len;
|
||||
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_DIGEST_MD5:
|
||||
len = sizeof(entry->digest.md5);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_RMD160:
|
||||
len = sizeof(entry->digest.rmd160);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA1:
|
||||
len = sizeof(entry->digest.sha1);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA256:
|
||||
len = sizeof(entry->digest.sha256);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA384:
|
||||
len = sizeof(entry->digest.sha384);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA512:
|
||||
len = sizeof(entry->digest.sha512);
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unknown digest type");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
if (len > sizeof(digest_buf)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Digest storage too large");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
len *= 2;
|
||||
|
||||
if (strnlen(digest, len+1) != len) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"incorrect digest length, ignoring");
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < len; i += 2, j++) {
|
||||
high = parse_hex_nibble(digest[i]);
|
||||
low = parse_hex_nibble(digest[i+1]);
|
||||
if (high == -1 || low == -1) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"invalid digest data, ignoring");
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
|
||||
digest_buf[j] = high << 4 | low;
|
||||
}
|
||||
|
||||
return archive_entry_set_digest(entry, type, digest_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a single keyword and its value.
|
||||
*/
|
||||
@ -1580,8 +1659,10 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'm':
|
||||
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
|
||||
break;
|
||||
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_MD5);
|
||||
}
|
||||
if (strcmp(key, "mode") == 0) {
|
||||
if (val[0] >= '0' && val[0] <= '7') {
|
||||
*parsed_kws |= MTREE_HAS_PERM;
|
||||
@ -1617,21 +1698,32 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
return r;
|
||||
}
|
||||
if (strcmp(key, "rmd160") == 0 ||
|
||||
strcmp(key, "rmd160digest") == 0)
|
||||
break;
|
||||
strcmp(key, "rmd160digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_RMD160);
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 's':
|
||||
if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
|
||||
break;
|
||||
if (strcmp(key, "sha1") == 0 ||
|
||||
strcmp(key, "sha1digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA1);
|
||||
}
|
||||
if (strcmp(key, "sha256") == 0 ||
|
||||
strcmp(key, "sha256digest") == 0)
|
||||
break;
|
||||
strcmp(key, "sha256digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA256);
|
||||
}
|
||||
if (strcmp(key, "sha384") == 0 ||
|
||||
strcmp(key, "sha384digest") == 0)
|
||||
break;
|
||||
strcmp(key, "sha384digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA384);
|
||||
}
|
||||
if (strcmp(key, "sha512") == 0 ||
|
||||
strcmp(key, "sha512digest") == 0)
|
||||
break;
|
||||
strcmp(key, "sha512digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA512);
|
||||
}
|
||||
if (strcmp(key, "size") == 0) {
|
||||
archive_entry_set_size(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
|
@ -151,6 +151,9 @@
|
||||
#undef minimum
|
||||
#define minimum(a, b) ((a)<(b)?(a):(b))
|
||||
|
||||
/* Stack overflow check */
|
||||
#define MAX_COMPRESS_DEPTH 1024
|
||||
|
||||
/* Fields common to all headers */
|
||||
struct rar_header
|
||||
{
|
||||
@ -340,7 +343,7 @@ static int read_symlink_stored(struct archive_read *, struct archive_entry *,
|
||||
static int read_data_stored(struct archive_read *, const void **, size_t *,
|
||||
int64_t *);
|
||||
static int read_data_compressed(struct archive_read *, const void **, size_t *,
|
||||
int64_t *);
|
||||
int64_t *, size_t);
|
||||
static int rar_br_preparation(struct archive_read *, struct rar_br *);
|
||||
static int parse_codes(struct archive_read *);
|
||||
static void free_codes(struct archive_read *);
|
||||
@ -1026,7 +1029,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||
case COMPRESS_METHOD_NORMAL:
|
||||
case COMPRESS_METHOD_GOOD:
|
||||
case COMPRESS_METHOD_BEST:
|
||||
ret = read_data_compressed(a, buff, size, offset);
|
||||
ret = read_data_compressed(a, buff, size, offset, 0);
|
||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
rar->start_new_table = 1;
|
||||
@ -1883,8 +1886,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
|
||||
|
||||
static int
|
||||
read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
int64_t *offset)
|
||||
int64_t *offset, size_t looper)
|
||||
{
|
||||
if (looper++ > MAX_COMPRESS_DEPTH)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
struct rar *rar;
|
||||
int64_t start, end, actualend;
|
||||
size_t bs;
|
||||
@ -1982,7 +1988,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
{
|
||||
case 0:
|
||||
rar->start_new_table = 1;
|
||||
return read_data_compressed(a, buff, size, offset);
|
||||
return read_data_compressed(a, buff, size, offset, looper);
|
||||
|
||||
case 2:
|
||||
rar->ppmd_eod = 1;/* End Of ppmd Data. */
|
||||
|
@ -3831,7 +3831,7 @@ static int verify_checksums(struct archive_read* a) {
|
||||
|
||||
DEBUG_CODE {
|
||||
printf("Checksum error: CRC32 "
|
||||
"(was: %08x, expected: %08x)\n",
|
||||
"(was: %08" PRIx32 ", expected: %08" PRIx32 ")\n",
|
||||
rar->file.calculated_crc32,
|
||||
rar->file.stored_crc32);
|
||||
}
|
||||
@ -3845,7 +3845,7 @@ static int verify_checksums(struct archive_read* a) {
|
||||
} else {
|
||||
DEBUG_CODE {
|
||||
printf("Checksum OK: CRC32 "
|
||||
"(%08x/%08x)\n",
|
||||
"(%08" PRIx32 "/%08" PRIx32 ")\n",
|
||||
rar->file.stored_crc32,
|
||||
rar->file.calculated_crc32);
|
||||
}
|
||||
@ -3906,6 +3906,9 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
|
||||
int ret;
|
||||
struct rar5* rar = get_context(a);
|
||||
|
||||
if (size)
|
||||
*size = 0;
|
||||
|
||||
if(rar->file.dir > 0) {
|
||||
/* Don't process any data if this file entry was declared
|
||||
* as a directory. This is needed, because entries marked as
|
||||
|
@ -337,6 +337,14 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
|
||||
mtime = rtime;
|
||||
}
|
||||
break;
|
||||
case WT_NONE:
|
||||
case WT_INFO:
|
||||
case WT_META:
|
||||
case WT_REQ:
|
||||
case WT_RVIS:
|
||||
case WT_CONV:
|
||||
case WT_CONT:
|
||||
case LAST_WT:
|
||||
default:
|
||||
fnam.len = 0U;
|
||||
fnam.str = NULL;
|
||||
@ -361,6 +369,14 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WT_NONE:
|
||||
case WT_INFO:
|
||||
case WT_META:
|
||||
case WT_REQ:
|
||||
case WT_RVIS:
|
||||
case WT_CONV:
|
||||
case WT_CONT:
|
||||
case LAST_WT:
|
||||
default:
|
||||
/* consume the content and start over */
|
||||
_warc_skip(a);
|
||||
|
@ -899,6 +899,79 @@ process_extra(struct archive_read *a, struct archive_entry *entry,
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Auxiliary function to uncompress data chunk from zipx archive
|
||||
* (zip with lzma compression).
|
||||
*/
|
||||
static int
|
||||
zipx_lzma_uncompress_buffer(const char *compressed_buffer,
|
||||
size_t compressed_buffer_size,
|
||||
char *uncompressed_buffer,
|
||||
size_t uncompressed_buffer_size)
|
||||
{
|
||||
int status = ARCHIVE_FATAL;
|
||||
// length of 'lzma properties data' in lzma compressed
|
||||
// data segment (stream) inside zip archive
|
||||
const size_t lzma_params_length = 5;
|
||||
// offset of 'lzma properties data' from the beginning of lzma stream
|
||||
const size_t lzma_params_offset = 4;
|
||||
// end position of 'lzma properties data' in lzma stream
|
||||
const size_t lzma_params_end = lzma_params_offset + lzma_params_length;
|
||||
if (compressed_buffer == NULL ||
|
||||
compressed_buffer_size < lzma_params_end ||
|
||||
uncompressed_buffer == NULL)
|
||||
return status;
|
||||
|
||||
// prepare header for lzma_alone_decoder to replace zipx header
|
||||
// (see comments in 'zipx_lzma_alone_init' for justification)
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct _alone_header
|
||||
{
|
||||
uint8_t bytes[5]; // lzma_params_length
|
||||
uint64_t uncompressed_size;
|
||||
} alone_header;
|
||||
#pragma pack(pop)
|
||||
// copy 'lzma properties data' blob
|
||||
memcpy(&alone_header.bytes[0], compressed_buffer + lzma_params_offset,
|
||||
lzma_params_length);
|
||||
alone_header.uncompressed_size = UINT64_MAX;
|
||||
|
||||
// prepare new compressed buffer, see 'zipx_lzma_alone_init' for details
|
||||
const size_t lzma_alone_buffer_size =
|
||||
compressed_buffer_size - lzma_params_end + sizeof(alone_header);
|
||||
unsigned char *lzma_alone_compressed_buffer =
|
||||
(unsigned char*) malloc(lzma_alone_buffer_size);
|
||||
if (lzma_alone_compressed_buffer == NULL)
|
||||
return status;
|
||||
// copy lzma_alone header into new buffer
|
||||
memcpy(lzma_alone_compressed_buffer, (void*) &alone_header,
|
||||
sizeof(alone_header));
|
||||
// copy compressed data into new buffer
|
||||
memcpy(lzma_alone_compressed_buffer + sizeof(alone_header),
|
||||
compressed_buffer + lzma_params_end,
|
||||
compressed_buffer_size - lzma_params_end);
|
||||
|
||||
// create and fill in lzma_alone_decoder stream
|
||||
lzma_stream stream = LZMA_STREAM_INIT;
|
||||
lzma_ret ret = lzma_alone_decoder(&stream, UINT64_MAX);
|
||||
if (ret == LZMA_OK)
|
||||
{
|
||||
stream.next_in = lzma_alone_compressed_buffer;
|
||||
stream.avail_in = lzma_alone_buffer_size;
|
||||
stream.total_in = 0;
|
||||
stream.next_out = (unsigned char*)uncompressed_buffer;
|
||||
stream.avail_out = uncompressed_buffer_size;
|
||||
stream.total_out = 0;
|
||||
ret = lzma_code(&stream, LZMA_RUN);
|
||||
if (ret == LZMA_OK || ret == LZMA_STREAM_END)
|
||||
status = ARCHIVE_OK;
|
||||
}
|
||||
lzma_end(&stream);
|
||||
free(lzma_alone_compressed_buffer);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assumes file pointer is at beginning of local file header.
|
||||
*/
|
||||
@ -1173,18 +1246,64 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
"Truncated Zip file");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
// take into account link compression if any
|
||||
size_t linkname_full_length = linkname_length;
|
||||
if (zip->entry->compression != 0)
|
||||
{
|
||||
// symlink target string appeared to be compressed
|
||||
int status = ARCHIVE_FATAL;
|
||||
char *uncompressed_buffer =
|
||||
(char*) malloc(zip_entry->uncompressed_size);
|
||||
if (uncompressed_buffer == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory for lzma decompression");
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (zip->entry->compression)
|
||||
{
|
||||
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
||||
case 14: /* ZIPx LZMA compression. */
|
||||
/*(see zip file format specification, section 4.4.5)*/
|
||||
status = zipx_lzma_uncompress_buffer(p,
|
||||
linkname_length,
|
||||
uncompressed_buffer,
|
||||
(size_t)zip_entry->uncompressed_size);
|
||||
break;
|
||||
#endif
|
||||
default: /* Unsupported compression. */
|
||||
break;
|
||||
}
|
||||
if (status == ARCHIVE_OK)
|
||||
{
|
||||
p = uncompressed_buffer;
|
||||
linkname_full_length =
|
||||
(size_t)zip_entry->uncompressed_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Unsupported ZIP compression method "
|
||||
"during decompression of link entry (%d: %s)",
|
||||
zip->entry->compression,
|
||||
compression_name(zip->entry->compression));
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
sconv = zip->sconv;
|
||||
if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
|
||||
sconv = zip->sconv_utf8;
|
||||
if (sconv == NULL)
|
||||
sconv = zip->sconv_default;
|
||||
if (archive_entry_copy_symlink_l(entry, p, linkname_length,
|
||||
if (archive_entry_copy_symlink_l(entry, p, linkname_full_length,
|
||||
sconv) != 0) {
|
||||
if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
|
||||
(zip->entry->zip_flags & ZIP_UTF8_NAME))
|
||||
archive_entry_copy_symlink_l(entry, p,
|
||||
linkname_length, NULL);
|
||||
linkname_full_length, NULL);
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Symlink");
|
||||
@ -1901,15 +2020,15 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
|
||||
|
||||
if(order < 2 || restore_method > 2) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Invalid parameter set in PPMd8 stream (order=%d, "
|
||||
"restore=%d)", order, restore_method);
|
||||
"Invalid parameter set in PPMd8 stream (order=%" PRId32 ", "
|
||||
"restore=%" PRId32 ")", order, restore_method);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
/* Allocate the memory needed to properly decompress the file. */
|
||||
if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Unable to allocate memory for PPMd8 stream: %d bytes",
|
||||
"Unable to allocate memory for PPMd8 stream: %" PRId32 " bytes",
|
||||
mem << 20);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
@ -3881,6 +3881,11 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
|
||||
}
|
||||
|
||||
*p = NULL;
|
||||
/* Try converting WCS to MBS first if MBS does not exist yet. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *pm; /* unused */
|
||||
archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
|
||||
}
|
||||
if (aes->aes_set & AES_SET_MBS) {
|
||||
sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
|
||||
if (sc == NULL)
|
||||
@ -3903,9 +3908,9 @@ int
|
||||
archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
|
||||
const char **p)
|
||||
{
|
||||
struct archive_string_conv *sc;
|
||||
int r, ret = 0;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
/* If we already have an MBS form, return that immediately. */
|
||||
if (aes->aes_set & AES_SET_MBS) {
|
||||
*p = aes->aes_mbs.s;
|
||||
@ -3926,10 +3931,23 @@ archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only a UTF-8 form cannot avail because its conversion already
|
||||
* failed at archive_mstring_update_utf8().
|
||||
*/
|
||||
/* If there's a UTF-8 form, try converting with the native locale. */
|
||||
if (aes->aes_set & AES_SET_UTF8) {
|
||||
archive_string_empty(&(aes->aes_mbs));
|
||||
sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
|
||||
if (sc == NULL)
|
||||
return (-1);/* Couldn't allocate memory for sc. */
|
||||
r = archive_strncpy_l(&(aes->aes_mbs),
|
||||
aes->aes_utf8.s, aes->aes_utf8.length, sc);
|
||||
if (a == NULL)
|
||||
free_sconv_object(sc);
|
||||
*p = aes->aes_mbs.s;
|
||||
if (r == 0) {
|
||||
aes->aes_set |= AES_SET_MBS;
|
||||
ret = 0;/* success; overwrite previous error. */
|
||||
} else
|
||||
ret = -1;/* failure. */
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -3947,6 +3965,11 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
|
||||
}
|
||||
|
||||
*wp = NULL;
|
||||
/* Try converting UTF8 to MBS first if MBS does not exist yet. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *p; /* unused */
|
||||
archive_mstring_get_mbs(a, aes, &p); /* ignore errors, we'll handle it later */
|
||||
}
|
||||
/* Try converting MBS to WCS using native locale. */
|
||||
if (aes->aes_set & AES_SET_MBS) {
|
||||
archive_wstring_empty(&(aes->aes_wcs));
|
||||
@ -3962,11 +3985,12 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
|
||||
}
|
||||
|
||||
int
|
||||
archive_mstring_get_mbs_l(struct archive_mstring *aes,
|
||||
archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
|
||||
const char **p, size_t *length, struct archive_string_conv *sc)
|
||||
{
|
||||
int r, ret = 0;
|
||||
|
||||
(void)r; /* UNUSED */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/*
|
||||
* Internationalization programming on Windows must use Wide
|
||||
@ -3989,20 +4013,12 @@ archive_mstring_get_mbs_l(struct archive_mstring *aes,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there is not an MBS form but is a WCS form, try converting
|
||||
/* If there is not an MBS form but there is a WCS or UTF8 form, try converting
|
||||
* with the native locale to be used for translating it to specified
|
||||
* character-set. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0 &&
|
||||
(aes->aes_set & AES_SET_WCS) != 0) {
|
||||
archive_string_empty(&(aes->aes_mbs));
|
||||
r = archive_string_append_from_wcs(&(aes->aes_mbs),
|
||||
aes->aes_wcs.s, aes->aes_wcs.length);
|
||||
if (r == 0)
|
||||
aes->aes_set |= AES_SET_MBS;
|
||||
else if (errno == ENOMEM)
|
||||
return (-1);
|
||||
else
|
||||
ret = -1;
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *pm; /* unused */
|
||||
archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
|
||||
}
|
||||
/* If we already have an MBS form, use it to be translated to
|
||||
* specified character-set. */
|
||||
|
@ -226,7 +226,7 @@ void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *
|
||||
int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
|
||||
int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **);
|
||||
int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **);
|
||||
int archive_mstring_get_mbs_l(struct archive_mstring *, const char **,
|
||||
int archive_mstring_get_mbs_l(struct archive *, struct archive_mstring *, const char **,
|
||||
size_t *, struct archive_string_conv *);
|
||||
int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
|
||||
int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,
|
||||
|
@ -433,6 +433,11 @@ __archive_mktemp(const char *tmpdir)
|
||||
if (temp_name.s[temp_name.length-1] != '/')
|
||||
archive_strappend_char(&temp_name, '/');
|
||||
}
|
||||
#ifdef O_TMPFILE
|
||||
fd = open(temp_name.s, O_RDWR|O_CLOEXEC|O_TMPFILE|O_EXCL, 0600);
|
||||
if(fd >= 0)
|
||||
goto exit_tmpfile;
|
||||
#endif
|
||||
archive_strcat(&temp_name, "libarchive_XXXXXX");
|
||||
fd = mkstemp(temp_name.s);
|
||||
if (fd < 0)
|
||||
|
@ -455,6 +455,25 @@ archive_write_client_write(struct archive_write_filter *f,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_write_client_free(struct archive_write_filter *f)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)f->archive;
|
||||
|
||||
if (a->client_freer)
|
||||
(*a->client_freer)(&a->archive, a->client_data);
|
||||
a->client_data = NULL;
|
||||
|
||||
/* Clear passphrase. */
|
||||
if (a->passphrase != NULL) {
|
||||
memset(a->passphrase, 0, strlen(a->passphrase));
|
||||
free(a->passphrase);
|
||||
a->passphrase = NULL;
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_write_client_close(struct archive_write_filter *f)
|
||||
{
|
||||
@ -493,13 +512,7 @@ archive_write_client_close(struct archive_write_filter *f)
|
||||
(*a->client_closer)(&a->archive, a->client_data);
|
||||
free(state->buffer);
|
||||
free(state);
|
||||
a->client_data = NULL;
|
||||
/* Clear passphrase. */
|
||||
if (a->passphrase != NULL) {
|
||||
memset(a->passphrase, 0, strlen(a->passphrase));
|
||||
free(a->passphrase);
|
||||
a->passphrase = NULL;
|
||||
}
|
||||
|
||||
/* Clear the close handler myself not to be called again. */
|
||||
f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
|
||||
return (ret);
|
||||
@ -509,9 +522,9 @@ archive_write_client_close(struct archive_write_filter *f)
|
||||
* Open the archive using the current settings.
|
||||
*/
|
||||
int
|
||||
archive_write_open(struct archive *_a, void *client_data,
|
||||
archive_write_open2(struct archive *_a, void *client_data,
|
||||
archive_open_callback *opener, archive_write_callback *writer,
|
||||
archive_close_callback *closer)
|
||||
archive_close_callback *closer, archive_free_callback *freer)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)_a;
|
||||
struct archive_write_filter *client_filter;
|
||||
@ -524,12 +537,14 @@ archive_write_open(struct archive *_a, void *client_data,
|
||||
a->client_writer = writer;
|
||||
a->client_opener = opener;
|
||||
a->client_closer = closer;
|
||||
a->client_freer = freer;
|
||||
a->client_data = client_data;
|
||||
|
||||
client_filter = __archive_write_allocate_filter(_a);
|
||||
client_filter->open = archive_write_client_open;
|
||||
client_filter->write = archive_write_client_write;
|
||||
client_filter->close = archive_write_client_close;
|
||||
client_filter->free = archive_write_client_free;
|
||||
|
||||
ret = __archive_write_filters_open(a);
|
||||
if (ret < ARCHIVE_WARN) {
|
||||
@ -544,6 +559,15 @@ archive_write_open(struct archive *_a, void *client_data,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_open(struct archive *_a, void *client_data,
|
||||
archive_open_callback *opener, archive_write_callback *writer,
|
||||
archive_close_callback *closer)
|
||||
{
|
||||
return archive_write_open2(_a, client_data, opener, writer,
|
||||
closer, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close out the archive.
|
||||
*/
|
||||
|
@ -382,8 +382,8 @@ archive_compressor_xz_options(struct archive_write_filter *f,
|
||||
value[1] != '\0')
|
||||
return (ARCHIVE_WARN);
|
||||
data->compression_level = value[0] - '0';
|
||||
if (data->compression_level > 6)
|
||||
data->compression_level = 6;
|
||||
if (data->compression_level > 9)
|
||||
data->compression_level = 9;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "threads") == 0) {
|
||||
char *endptr;
|
||||
|
@ -546,6 +546,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
||||
{
|
||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
||||
struct fixup_entry *fe;
|
||||
const char *linkname;
|
||||
int ret, r;
|
||||
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
||||
@ -590,6 +591,17 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Check if we have a hardlink that points to itself.
|
||||
*/
|
||||
linkname = archive_entry_hardlink(a->entry);
|
||||
if (linkname != NULL && strcmp(a->name, linkname) == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Skipping hardlink pointing to itself: %s",
|
||||
a->name);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the umask so we get predictable mode settings.
|
||||
* This gets done on every call to _write_header in case the
|
||||
@ -4411,10 +4423,19 @@ set_xattrs(struct archive_write_disk *a)
|
||||
ssize_t e;
|
||||
int namespace;
|
||||
|
||||
namespace = EXTATTR_NAMESPACE_USER;
|
||||
|
||||
if (strncmp(name, "user.", 5) == 0) {
|
||||
/* "user." attributes go to user namespace */
|
||||
name += 5;
|
||||
namespace = EXTATTR_NAMESPACE_USER;
|
||||
} else if (strncmp(name, "system.", 7) == 0) {
|
||||
name += 7;
|
||||
namespace = EXTATTR_NAMESPACE_SYSTEM;
|
||||
if (!strcmp(name, "nfs4.acl") ||
|
||||
!strcmp(name, "posix1e.acl_access") ||
|
||||
!strcmp(name, "posix1e.acl_default"))
|
||||
continue;
|
||||
} else {
|
||||
/* Other namespaces are unsupported */
|
||||
archive_strcat(&errlist, name);
|
||||
@ -4425,8 +4446,29 @@ set_xattrs(struct archive_write_disk *a)
|
||||
}
|
||||
|
||||
if (a->fd >= 0) {
|
||||
/*
|
||||
* On FreeBSD, extattr_set_fd does not
|
||||
* return the same as
|
||||
* extattr_set_file. It returns zero
|
||||
* on success, non-zero on failure.
|
||||
*
|
||||
* We can detect the failure by
|
||||
* manually setting errno prior to the
|
||||
* call and checking after.
|
||||
*
|
||||
* If errno remains zero, fake the
|
||||
* return value by setting e to size.
|
||||
*
|
||||
* This is a hack for now until I
|
||||
* (Shawn Webb) get FreeBSD to fix the
|
||||
* issue, if that's even possible.
|
||||
*/
|
||||
errno = 0;
|
||||
e = extattr_set_fd(a->fd, namespace, name,
|
||||
value, size);
|
||||
if (e == 0 && errno == 0) {
|
||||
e = size;
|
||||
}
|
||||
} else {
|
||||
e = extattr_set_link(
|
||||
archive_entry_pathname(entry), namespace,
|
||||
|
@ -24,11 +24,12 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dd November 12, 2020
|
||||
.Dt ARCHIVE_WRITE_OPEN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_write_open ,
|
||||
.Nm archive_write_open2 ,
|
||||
.Nm archive_write_open_fd ,
|
||||
.Nm archive_write_open_FILE ,
|
||||
.Nm archive_write_open_filename ,
|
||||
@ -47,6 +48,15 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Fa "archive_close_callback *"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_write_open2
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *client_data"
|
||||
.Fa "archive_open_callback *"
|
||||
.Fa "archive_write_callback *"
|
||||
.Fa "archive_close_callback *"
|
||||
.Fa "archive_free_callback *"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_write_open_fd "struct archive *" "int fd"
|
||||
.Ft int
|
||||
.Fn archive_write_open_FILE "struct archive *" "FILE *file"
|
||||
@ -67,6 +77,11 @@ This is the most generic form of this function, which accepts
|
||||
pointers to three callback functions which will be invoked by
|
||||
the compression layer to write the constructed archive.
|
||||
This does not alter the default archive padding.
|
||||
.It Fn archive_write_open2
|
||||
Same as
|
||||
.Fn archive_write_open
|
||||
with an additional fourth free callback. This function should be preferred to
|
||||
.Fn archive_write_open .
|
||||
.It Fn archive_write_open_fd
|
||||
A convenience form of
|
||||
.Fn archive_write_open
|
||||
@ -106,14 +121,14 @@ to a character or block device node, it will disable padding otherwise.
|
||||
You can override this by manually invoking
|
||||
.Fn archive_write_set_bytes_in_last_block
|
||||
before calling
|
||||
.Fn archive_write_open .
|
||||
.Fn archive_write_open2 .
|
||||
The
|
||||
.Fn archive_write_open_filename
|
||||
function is safe for use with tape drives or other
|
||||
block-oriented devices.
|
||||
.It Fn archive_write_open_memory
|
||||
A convenience form of
|
||||
.Fn archive_write_open
|
||||
.Fn archive_write_open2
|
||||
that accepts a pointer to a block of memory that will receive
|
||||
the archive.
|
||||
The final
|
||||
@ -145,7 +160,7 @@ To use this library, you will need to define and register
|
||||
callback functions that will be invoked to write data to the
|
||||
resulting archive.
|
||||
These functions are registered by calling
|
||||
.Fn archive_write_open :
|
||||
.Fn archive_write_open2 :
|
||||
.Bl -item -offset indent
|
||||
.It
|
||||
.Ft typedef int
|
||||
@ -162,6 +177,8 @@ If the open fails, it should call
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and return
|
||||
.Cm ARCHIVE_FATAL .
|
||||
Please note that if open fails, close is not called and resources must be
|
||||
freed inside the open callback or with the free callback.
|
||||
.Bl -item -offset indent
|
||||
.It
|
||||
.Ft typedef la_ssize_t
|
||||
@ -192,7 +209,8 @@ to register an error code and message and return -1.
|
||||
.El
|
||||
.Pp
|
||||
The close callback is invoked by archive_close when
|
||||
the archive processing is complete.
|
||||
the archive processing is complete. If the open callback fails, the close
|
||||
callback is not invoked.
|
||||
The callback should return
|
||||
.Cm ARCHIVE_OK
|
||||
on success.
|
||||
@ -200,7 +218,14 @@ On failure, the callback should invoke
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and
|
||||
return
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.Bl -item -offset indent
|
||||
.It
|
||||
.Ft typedef int
|
||||
.Fn archive_free_callback "struct archive *" "void *client_data"
|
||||
.El
|
||||
.Pp
|
||||
The free callback is always invoked on archive_free.
|
||||
The return code of this callback is not processed.
|
||||
.Pp
|
||||
Note that if the client-provided write callback function
|
||||
returns a non-zero value, that error will be propagated back to the caller
|
||||
|
@ -54,7 +54,7 @@ struct write_fd_data {
|
||||
int fd;
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_free(struct archive *, void *);
|
||||
static int file_open(struct archive *, void *);
|
||||
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
|
||||
|
||||
@ -72,8 +72,8 @@ archive_write_open_fd(struct archive *a, int fd)
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
setmode(mine->fd, O_BINARY);
|
||||
#endif
|
||||
return (archive_write_open(a, mine,
|
||||
file_open, file_write, file_close));
|
||||
return (archive_write_open2(a, mine,
|
||||
file_open, file_write, NULL, file_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -134,11 +134,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
file_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_fd_data *mine = (struct write_fd_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ struct write_FILE_data {
|
||||
FILE *f;
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_free(struct archive *, void *);
|
||||
static int file_open(struct archive *, void *);
|
||||
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
|
||||
|
||||
@ -66,8 +66,8 @@ archive_write_open_FILE(struct archive *a, FILE *f)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->f = f;
|
||||
return (archive_write_open(a, mine,
|
||||
file_open, file_write, file_close));
|
||||
return (archive_write_open2(a, mine, file_open, file_write,
|
||||
NULL, file_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -99,11 +99,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
file_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_FILE_data *mine = client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ struct write_file_data {
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_free(struct archive *, void *);
|
||||
static int file_open(struct archive *, void *);
|
||||
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
|
||||
static int open_filename(struct archive *, int, const void *);
|
||||
@ -123,8 +124,8 @@ open_filename(struct archive *a, int mbs_fn, const void *filename)
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
mine->fd = -1;
|
||||
return (archive_write_open(a, mine,
|
||||
file_open, file_write, file_close));
|
||||
return (archive_write_open2(a, mine,
|
||||
file_open, file_write, file_close, file_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -244,9 +245,25 @@ file_close(struct archive *a, void *client_data)
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
if (mine->fd >= 0)
|
||||
close(mine->fd);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
file_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_file_data *mine = (struct write_file_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
archive_mstring_clean(&mine->filename);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
|
@ -39,7 +39,7 @@ struct write_memory_data {
|
||||
unsigned char * buff;
|
||||
};
|
||||
|
||||
static int memory_write_close(struct archive *, void *);
|
||||
static int memory_write_free(struct archive *, void *);
|
||||
static int memory_write_open(struct archive *, void *);
|
||||
static ssize_t memory_write(struct archive *, void *, const void *buff, size_t);
|
||||
|
||||
@ -61,8 +61,8 @@ archive_write_open_memory(struct archive *a, void *buff, size_t buffSize, size_t
|
||||
mine->buff = buff;
|
||||
mine->size = buffSize;
|
||||
mine->client_size = used;
|
||||
return (archive_write_open(a, mine,
|
||||
memory_write_open, memory_write, memory_write_close));
|
||||
return (archive_write_open2(a, mine,
|
||||
memory_write_open, memory_write, NULL, memory_write_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -103,11 +103,13 @@ memory_write(struct archive *a, void *client_data, const void *buff, size_t leng
|
||||
}
|
||||
|
||||
static int
|
||||
memory_write_close(struct archive *a, void *client_data)
|
||||
memory_write_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_memory_data *mine;
|
||||
(void)a; /* UNUSED */
|
||||
mine = client_data;
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ struct archive_write {
|
||||
archive_open_callback *client_opener;
|
||||
archive_write_callback *client_writer;
|
||||
archive_close_callback *client_closer;
|
||||
archive_free_callback *client_freer;
|
||||
void *client_data;
|
||||
|
||||
/*
|
||||
|
@ -1927,8 +1927,8 @@ compression_init_encoder_lzma(struct archive *a,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
lzmafilters = (lzma_filter *)(strm+1);
|
||||
if (level > 6)
|
||||
level = 6;
|
||||
if (level > 9)
|
||||
level = 9;
|
||||
if (lzma_lzma_preset(&lzma_opt, level)) {
|
||||
free(strm);
|
||||
lastrm->real_stream = NULL;
|
||||
|
@ -250,7 +250,7 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
|
||||
const char *path;
|
||||
size_t len;
|
||||
|
||||
if (archive_entry_filetype(entry) == 0) {
|
||||
if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
|
||||
archive_set_error(&a->archive, -1, "Filetype required");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
@ -348,7 +348,7 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
|
||||
if (archive_entry_filetype(entry) == AE_IFBLK
|
||||
|| archive_entry_filetype(entry) == AE_IFCHR)
|
||||
format_octal(archive_entry_dev(entry), h + c_rdev_offset, c_rdev_size);
|
||||
format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size);
|
||||
else
|
||||
format_octal(0, h + c_rdev_offset, c_rdev_size);
|
||||
format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
|
||||
|
@ -190,7 +190,7 @@ archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
|
||||
const char *path;
|
||||
size_t len;
|
||||
|
||||
if (archive_entry_filetype(entry) == 0) {
|
||||
if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
|
||||
archive_set_error(&a->archive, -1, "Filetype required");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
@ -2178,7 +2178,8 @@ get_system_identitier(char *system_id, size_t size)
|
||||
strncpy(system_id, "Windows", size-1);
|
||||
system_id[size-1] = '\0';
|
||||
#else
|
||||
#error no way to get the system identifier on your platform.
|
||||
strncpy(system_id, "Unknown", size-1);
|
||||
system_id[size-1] = '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "archive.h"
|
||||
#include "archive_digest_private.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_entry_private.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_rb.h"
|
||||
#include "archive_string.h"
|
||||
@ -82,24 +83,7 @@ struct dir_info {
|
||||
struct reg_info {
|
||||
int compute_sum;
|
||||
uint32_t crc;
|
||||
#ifdef ARCHIVE_HAS_MD5
|
||||
unsigned char buf_md5[16];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_RMD160
|
||||
unsigned char buf_rmd160[20];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA1
|
||||
unsigned char buf_sha1[20];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA256
|
||||
unsigned char buf_sha256[32];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA384
|
||||
unsigned char buf_sha384[48];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA512
|
||||
unsigned char buf_sha512[64];
|
||||
#endif
|
||||
struct ae_digest digest;
|
||||
};
|
||||
|
||||
struct mtree_entry {
|
||||
@ -1571,27 +1555,27 @@ sum_final(struct mtree_writer *mtree, struct reg_info *reg)
|
||||
}
|
||||
#ifdef ARCHIVE_HAS_MD5
|
||||
if (mtree->compute_sum & F_MD5)
|
||||
archive_md5_final(&mtree->md5ctx, reg->buf_md5);
|
||||
archive_md5_final(&mtree->md5ctx, reg->digest.md5);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_RMD160
|
||||
if (mtree->compute_sum & F_RMD160)
|
||||
archive_rmd160_final(&mtree->rmd160ctx, reg->buf_rmd160);
|
||||
archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA1
|
||||
if (mtree->compute_sum & F_SHA1)
|
||||
archive_sha1_final(&mtree->sha1ctx, reg->buf_sha1);
|
||||
archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA256
|
||||
if (mtree->compute_sum & F_SHA256)
|
||||
archive_sha256_final(&mtree->sha256ctx, reg->buf_sha256);
|
||||
archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA384
|
||||
if (mtree->compute_sum & F_SHA384)
|
||||
archive_sha384_final(&mtree->sha384ctx, reg->buf_sha384);
|
||||
archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA512
|
||||
if (mtree->compute_sum & F_SHA512)
|
||||
archive_sha512_final(&mtree->sha512ctx, reg->buf_sha512);
|
||||
archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
|
||||
#endif
|
||||
/* Save what types of sum are computed. */
|
||||
reg->compute_sum = mtree->compute_sum;
|
||||
@ -1621,42 +1605,47 @@ sum_write(struct archive_string *str, struct reg_info *reg)
|
||||
archive_string_sprintf(str, " cksum=%ju",
|
||||
(uintmax_t)reg->crc);
|
||||
}
|
||||
|
||||
#define append_digest(_s, _r, _t) \
|
||||
strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
|
||||
|
||||
#ifdef ARCHIVE_HAS_MD5
|
||||
if (reg->compute_sum & F_MD5) {
|
||||
archive_strcat(str, " md5digest=");
|
||||
strappend_bin(str, reg->buf_md5, sizeof(reg->buf_md5));
|
||||
append_digest(str, reg, md5);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_RMD160
|
||||
if (reg->compute_sum & F_RMD160) {
|
||||
archive_strcat(str, " rmd160digest=");
|
||||
strappend_bin(str, reg->buf_rmd160, sizeof(reg->buf_rmd160));
|
||||
append_digest(str, reg, rmd160);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA1
|
||||
if (reg->compute_sum & F_SHA1) {
|
||||
archive_strcat(str, " sha1digest=");
|
||||
strappend_bin(str, reg->buf_sha1, sizeof(reg->buf_sha1));
|
||||
append_digest(str, reg, sha1);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA256
|
||||
if (reg->compute_sum & F_SHA256) {
|
||||
archive_strcat(str, " sha256digest=");
|
||||
strappend_bin(str, reg->buf_sha256, sizeof(reg->buf_sha256));
|
||||
append_digest(str, reg, sha256);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA384
|
||||
if (reg->compute_sum & F_SHA384) {
|
||||
archive_strcat(str, " sha384digest=");
|
||||
strappend_bin(str, reg->buf_sha384, sizeof(reg->buf_sha384));
|
||||
append_digest(str, reg, sha384);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA512
|
||||
if (reg->compute_sum & F_SHA512) {
|
||||
archive_strcat(str, " sha512digest=");
|
||||
strappend_bin(str, reg->buf_sha512, sizeof(reg->buf_sha512));
|
||||
append_digest(str, reg, sha512);
|
||||
}
|
||||
#endif
|
||||
#undef append_digest
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2931,8 +2931,8 @@ compression_init_encoder_xz(struct archive *a,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
lzmafilters = (lzma_filter *)(strm+1);
|
||||
if (level > 6)
|
||||
level = 6;
|
||||
if (level > 9)
|
||||
level = 9;
|
||||
if (lzma_lzma_preset(&lzma_opt, level)) {
|
||||
free(strm);
|
||||
lastrm->real_stream = NULL;
|
||||
|
@ -584,6 +584,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||
zip->entry_flags |= ZIP_ENTRY_FLAG_ENCRYPTED;
|
||||
zip->entry_encryption = zip->encryption_type;
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -710,6 +711,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||
+ AUTH_CODE_SIZE;
|
||||
version_needed = 20;
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -762,6 +764,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||
if (version_needed < 20)
|
||||
version_needed = 20;
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1029,6 +1032,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
|
||||
zip->cctx_valid = zip->hctx_valid = 1;
|
||||
}
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1117,6 +1121,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case COMPRESSION_UNSPECIFIED:
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ZIP compression type");
|
||||
|
@ -44,14 +44,9 @@ test_empty_file1(void)
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty_file2(void)
|
||||
test_empty_file2_check(struct archive* a)
|
||||
{
|
||||
struct archive* a = archive_read_new();
|
||||
struct archive_entry* e;
|
||||
|
||||
/* Try opening an empty file with raw and empty handlers. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a));
|
||||
assertEqualInt(0, archive_errno(a));
|
||||
assertEqualString(NULL, archive_error_string(a));
|
||||
|
||||
@ -66,6 +61,25 @@ test_empty_file2(void)
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty_file2(void)
|
||||
{
|
||||
struct archive* a = archive_read_new();
|
||||
|
||||
/* Try opening an empty file with raw and empty handlers. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a));
|
||||
test_empty_file2_check(a);
|
||||
|
||||
a = archive_read_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_support_format_by_code(a, ARCHIVE_FORMAT_EMPTY));
|
||||
test_empty_file2_check(a);
|
||||
|
||||
a = archive_read_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_set_format(a, ARCHIVE_FORMAT_EMPTY));
|
||||
test_empty_file2_check(a);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty_tarfile(void)
|
||||
{
|
||||
|
@ -35,6 +35,17 @@ typedef struct archive *constructor(void);
|
||||
typedef int enabler(struct archive *);
|
||||
typedef int destructor(struct archive *);
|
||||
|
||||
static int format_code = 0;
|
||||
static int format_code_enabler(struct archive *a)
|
||||
{
|
||||
return archive_read_support_format_by_code(a, format_code);
|
||||
}
|
||||
|
||||
static int format_code_setter(struct archive *a)
|
||||
{
|
||||
return archive_read_set_format(a, format_code);
|
||||
}
|
||||
|
||||
static void
|
||||
test_success(constructor new_, enabler enable_, destructor free_)
|
||||
{
|
||||
@ -85,6 +96,42 @@ DEFINE_TEST(test_archive_read_support)
|
||||
test_filter_or_format(archive_read_support_format_xar);
|
||||
test_filter_or_format(archive_read_support_format_zip);
|
||||
|
||||
int format_codes[] = {
|
||||
ARCHIVE_FORMAT_CPIO,
|
||||
ARCHIVE_FORMAT_CPIO_POSIX,
|
||||
ARCHIVE_FORMAT_CPIO_BIN_LE,
|
||||
ARCHIVE_FORMAT_CPIO_BIN_BE,
|
||||
ARCHIVE_FORMAT_CPIO_SVR4_NOCRC,
|
||||
ARCHIVE_FORMAT_CPIO_SVR4_CRC,
|
||||
ARCHIVE_FORMAT_CPIO_AFIO_LARGE,
|
||||
ARCHIVE_FORMAT_TAR,
|
||||
ARCHIVE_FORMAT_TAR_USTAR,
|
||||
ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
|
||||
ARCHIVE_FORMAT_TAR_PAX_RESTRICTED,
|
||||
ARCHIVE_FORMAT_TAR_GNUTAR,
|
||||
ARCHIVE_FORMAT_ISO9660,
|
||||
ARCHIVE_FORMAT_ISO9660_ROCKRIDGE,
|
||||
ARCHIVE_FORMAT_ZIP,
|
||||
ARCHIVE_FORMAT_EMPTY,
|
||||
ARCHIVE_FORMAT_AR,
|
||||
ARCHIVE_FORMAT_AR_GNU,
|
||||
ARCHIVE_FORMAT_AR_BSD,
|
||||
ARCHIVE_FORMAT_MTREE,
|
||||
ARCHIVE_FORMAT_RAW,
|
||||
ARCHIVE_FORMAT_XAR,
|
||||
ARCHIVE_FORMAT_LHA,
|
||||
ARCHIVE_FORMAT_CAB,
|
||||
ARCHIVE_FORMAT_RAR,
|
||||
ARCHIVE_FORMAT_7ZIP,
|
||||
ARCHIVE_FORMAT_WARC,
|
||||
ARCHIVE_FORMAT_RAR_V5,
|
||||
};
|
||||
for (unsigned i = 0; i < sizeof(format_codes) / sizeof(int); i++) {
|
||||
format_code = format_codes[i];
|
||||
test_filter_or_format(format_code_enabler);
|
||||
test_filter_or_format(format_code_setter);
|
||||
}
|
||||
|
||||
test_filter_or_format(archive_read_support_filter_all);
|
||||
test_filter_or_format(archive_read_support_filter_bzip2);
|
||||
test_filter_or_format(archive_read_support_filter_compress);
|
||||
|
@ -445,7 +445,7 @@ test_archive_string_normalization_nfc(const char *testdata)
|
||||
assertEqualInt(0,
|
||||
archive_mstring_copy_wcs(&mstr, wc_nfc));
|
||||
assertEqualInt(0, archive_mstring_get_mbs_l(
|
||||
&mstr, &mp, &mplen, t_sconv8));
|
||||
a, &mstr, &mp, &mplen, t_sconv8));
|
||||
failure("WCS NFC(%s) should be UTF-8 NFC:%d"
|
||||
,nfc, line);
|
||||
assertEqualUTF8String(utf8_nfc, mp);
|
||||
@ -695,7 +695,7 @@ test_archive_string_normalization_mac_nfd(const char *testdata)
|
||||
assertEqualInt(0, archive_mstring_copy_wcs(
|
||||
&mstr, wc_nfd));
|
||||
assertEqualInt(0, archive_mstring_get_mbs_l(
|
||||
&mstr, &mp, &mplen, t_sconv8));
|
||||
a, &mstr, &mp, &mplen, t_sconv8));
|
||||
failure("WCS NFD(%s) should be UTF-8 NFD:%d"
|
||||
,nfd, line);
|
||||
assertEqualUTF8String(utf8_nfd, mp);
|
||||
@ -777,6 +777,80 @@ test_archive_string_canonicalization(void)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
check_string(struct archive *a, struct archive_mstring *mstr, struct archive_string_conv *sc,
|
||||
const char *exp, const wchar_t *wexp)
|
||||
{
|
||||
/* Do all the tests on a copy so that we can have a clear initial state every time */
|
||||
struct archive_mstring mstr2;
|
||||
const char *p = NULL;
|
||||
const wchar_t *wp = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
memset(&mstr2, 0, sizeof(mstr2));
|
||||
|
||||
archive_mstring_copy(&mstr2, mstr);
|
||||
assertEqualInt(0, archive_mstring_get_mbs(a, &mstr2, &p));
|
||||
assertEqualString(exp, p);
|
||||
p = NULL;
|
||||
|
||||
archive_mstring_copy(&mstr2, mstr);
|
||||
assertEqualInt(0, archive_mstring_get_utf8(a, &mstr2, &p));
|
||||
assertEqualString(exp, p);
|
||||
p = NULL;
|
||||
|
||||
archive_mstring_copy(&mstr2, mstr);
|
||||
assertEqualInt(0, archive_mstring_get_wcs(a, &mstr2, &wp));
|
||||
assertEqualWString(wexp, wp);
|
||||
wp = NULL;
|
||||
|
||||
archive_mstring_copy(&mstr2, mstr);
|
||||
assertEqualInt(0, archive_mstring_get_mbs_l(a, &mstr2, &p, &len, sc));
|
||||
assertEqualString(exp, p);
|
||||
assertEqualInt(len, strlen(exp));
|
||||
p = NULL;
|
||||
len = 0;
|
||||
|
||||
archive_mstring_clean(&mstr2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure no matter what the input encoding is, the string can be
|
||||
* converted too all the output encodings.
|
||||
*/
|
||||
static void
|
||||
test_archive_string_set_get(void)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_mstring mstr;
|
||||
struct archive_string_conv *sc;
|
||||
|
||||
setlocale(LC_ALL, "en_US.UTF-8");
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
memset(&mstr, 0, sizeof(mstr));
|
||||
|
||||
assertA(NULL != (sc =
|
||||
archive_string_conversion_to_charset(a, "UTF-8", 1)));
|
||||
failure("Charset name should be UTF-8");
|
||||
assertEqualString("UTF-8",
|
||||
archive_string_conversion_charset_name(sc));
|
||||
|
||||
assertEqualInt(0, archive_mstring_copy_mbs(&mstr, "AAA"));
|
||||
check_string(a, &mstr, sc, "AAA", L"AAA");
|
||||
assertEqualInt(4, archive_mstring_copy_utf8(&mstr, "BBBB"));
|
||||
check_string(a, &mstr, sc, "BBBB", L"BBBB");
|
||||
assertEqualInt(0, archive_mstring_copy_wcs(&mstr, L"CCC12"));
|
||||
check_string(a, &mstr, sc, "CCC12", L"CCC12");
|
||||
assertEqualInt(0, archive_mstring_copy_mbs_len_l(&mstr, "DDDD-l", 6, sc));
|
||||
check_string(a, &mstr, sc, "DDDD-l", L"DDDD-l");
|
||||
assertEqualInt(0, archive_mstring_update_utf8(a, &mstr, "EEEEE---H"));
|
||||
check_string(a, &mstr, sc, "EEEEE---H", L"EEEEE---H");
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string_conversion)
|
||||
{
|
||||
static const char reffile[] = "test_archive_string_conversion.txt.Z";
|
||||
@ -807,4 +881,5 @@ DEFINE_TEST(test_archive_string_conversion)
|
||||
test_archive_string_normalization_nfc(testdata);
|
||||
test_archive_string_normalization_mac_nfd(testdata);
|
||||
test_archive_string_canonicalization();
|
||||
test_archive_string_set_get();
|
||||
}
|
||||
|
@ -177,31 +177,60 @@ DEFINE_TEST(test_entry)
|
||||
/* gname */
|
||||
archive_entry_set_gname(e, "group");
|
||||
assertEqualString(archive_entry_gname(e), "group");
|
||||
assertEqualString(archive_entry_gname_utf8(e), "group");
|
||||
assertEqualWString(archive_entry_gname_w(e), L"group");
|
||||
wcscpy(wbuff, L"wgroup");
|
||||
archive_entry_copy_gname_w(e, wbuff);
|
||||
assertEqualWString(archive_entry_gname_w(e), L"wgroup");
|
||||
memset(wbuff, 0, sizeof(wbuff));
|
||||
assertEqualWString(archive_entry_gname_w(e), L"wgroup");
|
||||
assertEqualString(archive_entry_gname_utf8(e), "wgroup");
|
||||
assertEqualString(archive_entry_gname(e), "wgroup");
|
||||
archive_entry_set_gname_utf8(e, "group");
|
||||
assertEqualString(archive_entry_gname_utf8(e), "group");
|
||||
assertEqualWString(archive_entry_gname_w(e), L"group");
|
||||
assertEqualString(archive_entry_gname(e), "group");
|
||||
archive_entry_update_gname_utf8(e, "group2");
|
||||
assertEqualString(archive_entry_gname_utf8(e), "group2");
|
||||
assertEqualWString(archive_entry_gname_w(e), L"group2");
|
||||
assertEqualString(archive_entry_gname(e), "group2");
|
||||
|
||||
/* hardlink */
|
||||
archive_entry_set_hardlink(e, "hardlinkname");
|
||||
assertEqualString(archive_entry_hardlink(e), "hardlinkname");
|
||||
assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname");
|
||||
assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname");
|
||||
strcpy(buff, "hardlinkname2");
|
||||
archive_entry_copy_hardlink(e, buff);
|
||||
assertEqualString(archive_entry_hardlink(e), "hardlinkname2");
|
||||
assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname2");
|
||||
assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname2");
|
||||
memset(buff, 0, sizeof(buff));
|
||||
assertEqualString(archive_entry_hardlink(e), "hardlinkname2");
|
||||
assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname2");
|
||||
assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname2");
|
||||
archive_entry_copy_hardlink(e, NULL);
|
||||
assertEqualString(archive_entry_hardlink(e), NULL);
|
||||
assertEqualWString(archive_entry_hardlink_w(e), NULL);
|
||||
assertEqualString(archive_entry_hardlink_utf8(e), NULL);
|
||||
wcscpy(wbuff, L"whardlink");
|
||||
archive_entry_copy_hardlink_w(e, wbuff);
|
||||
assertEqualWString(archive_entry_hardlink_w(e), L"whardlink");
|
||||
assertEqualString(archive_entry_hardlink_utf8(e), "whardlink");
|
||||
assertEqualString(archive_entry_hardlink(e), "whardlink");
|
||||
memset(wbuff, 0, sizeof(wbuff));
|
||||
assertEqualWString(archive_entry_hardlink_w(e), L"whardlink");
|
||||
archive_entry_copy_hardlink_w(e, NULL);
|
||||
assertEqualString(archive_entry_hardlink(e), NULL);
|
||||
assertEqualWString(archive_entry_hardlink_w(e), NULL);
|
||||
archive_entry_set_hardlink_utf8(e, "hardlinkname");
|
||||
assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname");
|
||||
assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname");
|
||||
assertEqualString(archive_entry_hardlink(e), "hardlinkname");
|
||||
archive_entry_update_hardlink_utf8(e, "hardlinkname2");
|
||||
assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname2");
|
||||
assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname2");
|
||||
assertEqualString(archive_entry_hardlink(e), "hardlinkname2");
|
||||
|
||||
/* ino */
|
||||
assert(!archive_entry_ino_is_set(e));
|
||||
@ -270,18 +299,38 @@ DEFINE_TEST(test_entry)
|
||||
/* pathname */
|
||||
archive_entry_set_pathname(e, "path");
|
||||
assertEqualString(archive_entry_pathname(e), "path");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "path");
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"path");
|
||||
archive_entry_set_pathname(e, "path");
|
||||
assertEqualString(archive_entry_pathname(e), "path");
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"path");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "path");
|
||||
strcpy(buff, "path2");
|
||||
archive_entry_copy_pathname(e, buff);
|
||||
assertEqualString(archive_entry_pathname(e), "path2");
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"path2");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "path2");
|
||||
memset(buff, 0, sizeof(buff));
|
||||
assertEqualString(archive_entry_pathname(e), "path2");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "path2");
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"path2");
|
||||
wcscpy(wbuff, L"wpath");
|
||||
archive_entry_copy_pathname_w(e, wbuff);
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"wpath");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "wpath");
|
||||
assertEqualString(archive_entry_pathname(e), "wpath");
|
||||
memset(wbuff, 0, sizeof(wbuff));
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"wpath");
|
||||
assertEqualString(archive_entry_pathname(e), "wpath");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "wpath");
|
||||
archive_entry_set_pathname_utf8(e, "path");
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"path");
|
||||
assertEqualString(archive_entry_pathname(e), "path");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "path");
|
||||
archive_entry_update_pathname_utf8(e, "path2");
|
||||
assertEqualWString(archive_entry_pathname_w(e), L"path2");
|
||||
assertEqualString(archive_entry_pathname(e), "path2");
|
||||
assertEqualString(archive_entry_pathname_utf8(e), "path2");
|
||||
|
||||
/* rdev */
|
||||
archive_entry_set_rdev(e, 532);
|
||||
@ -302,19 +351,37 @@ DEFINE_TEST(test_entry)
|
||||
/* symlink */
|
||||
archive_entry_set_symlink(e, "symlinkname");
|
||||
assertEqualString(archive_entry_symlink(e), "symlinkname");
|
||||
assertEqualString(archive_entry_symlink_utf8(e), "symlinkname");
|
||||
assertEqualWString(archive_entry_symlink_w(e), L"symlinkname");
|
||||
strcpy(buff, "symlinkname2");
|
||||
archive_entry_copy_symlink(e, buff);
|
||||
assertEqualString(archive_entry_symlink(e), "symlinkname2");
|
||||
assertEqualWString(archive_entry_symlink_w(e), L"symlinkname2");
|
||||
assertEqualString(archive_entry_symlink_utf8(e), "symlinkname2");
|
||||
memset(buff, 0, sizeof(buff));
|
||||
assertEqualString(archive_entry_symlink(e), "symlinkname2");
|
||||
assertEqualString(archive_entry_symlink_utf8(e), "symlinkname2");
|
||||
assertEqualWString(archive_entry_symlink_w(e), L"symlinkname2");
|
||||
archive_entry_copy_symlink_w(e, NULL);
|
||||
assertEqualWString(archive_entry_symlink_w(e), NULL);
|
||||
assertEqualString(archive_entry_symlink(e), NULL);
|
||||
assertEqualString(archive_entry_symlink_utf8(e), NULL);
|
||||
archive_entry_copy_symlink_w(e, L"wsymlink");
|
||||
assertEqualWString(archive_entry_symlink_w(e), L"wsymlink");
|
||||
assertEqualString(archive_entry_symlink_utf8(e), "wsymlink");
|
||||
assertEqualString(archive_entry_symlink(e), "wsymlink");
|
||||
archive_entry_copy_symlink(e, NULL);
|
||||
assertEqualWString(archive_entry_symlink_w(e), NULL);
|
||||
assertEqualString(archive_entry_symlink(e), NULL);
|
||||
assertEqualString(archive_entry_symlink_utf8(e), NULL);
|
||||
archive_entry_set_symlink_utf8(e, "symlinkname");
|
||||
assertEqualWString(archive_entry_symlink_w(e), L"symlinkname");
|
||||
assertEqualString(archive_entry_symlink(e), "symlinkname");
|
||||
assertEqualString(archive_entry_symlink_utf8(e), "symlinkname");
|
||||
archive_entry_update_symlink_utf8(e, "symlinkname2");
|
||||
assertEqualWString(archive_entry_symlink_w(e), L"symlinkname2");
|
||||
assertEqualString(archive_entry_symlink(e), "symlinkname2");
|
||||
assertEqualString(archive_entry_symlink_utf8(e), "symlinkname2");
|
||||
|
||||
/* uid */
|
||||
archive_entry_set_uid(e, 83);
|
||||
@ -323,11 +390,27 @@ DEFINE_TEST(test_entry)
|
||||
/* uname */
|
||||
archive_entry_set_uname(e, "user");
|
||||
assertEqualString(archive_entry_uname(e), "user");
|
||||
assertEqualString(archive_entry_uname_utf8(e), "user");
|
||||
assertEqualWString(archive_entry_uname_w(e), L"user");
|
||||
wcscpy(wbuff, L"wuser");
|
||||
archive_entry_copy_gname_w(e, wbuff);
|
||||
assertEqualWString(archive_entry_gname_w(e), L"wuser");
|
||||
archive_entry_copy_uname_w(e, wbuff);
|
||||
assertEqualWString(archive_entry_uname_w(e), L"wuser");
|
||||
memset(wbuff, 0, sizeof(wbuff));
|
||||
assertEqualWString(archive_entry_gname_w(e), L"wuser");
|
||||
assertEqualWString(archive_entry_uname_w(e), L"wuser");
|
||||
assertEqualString(archive_entry_uname_utf8(e), "wuser");
|
||||
assertEqualString(archive_entry_uname(e), "wuser");
|
||||
archive_entry_set_uname_utf8(e, "user");
|
||||
assertEqualString(archive_entry_uname_utf8(e), "user");
|
||||
assertEqualWString(archive_entry_uname_w(e), L"user");
|
||||
assertEqualString(archive_entry_uname(e), "user");
|
||||
archive_entry_set_uname_utf8(e, "user");
|
||||
assertEqualWString(archive_entry_uname_w(e), L"user");
|
||||
assertEqualString(archive_entry_uname(e), "user");
|
||||
assertEqualString(archive_entry_uname_utf8(e), "user");
|
||||
archive_entry_update_uname_utf8(e, "user2");
|
||||
assertEqualWString(archive_entry_uname_w(e), L"user2");
|
||||
assertEqualString(archive_entry_uname(e), "user2");
|
||||
assertEqualString(archive_entry_uname_utf8(e), "user2");
|
||||
|
||||
/* Test fflags interface. */
|
||||
archive_entry_set_fflags(e, 0x55, 0xAA);
|
||||
|
@ -1833,6 +1833,8 @@ test_parent(void)
|
||||
}
|
||||
|
||||
assertChdir("..");
|
||||
assertChmod("lock", 0755);
|
||||
assertChmod("lock/lock2", 0755);
|
||||
|
||||
/* Destroy the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
@ -196,8 +196,80 @@ test_read_format_mtree1(void)
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
|
||||
|
||||
/* md5digest */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/md5file");
|
||||
assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
|
||||
"\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e",
|
||||
16);
|
||||
|
||||
/* rmd160digest */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/rmd160file");
|
||||
assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_RMD160),
|
||||
"\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90"
|
||||
"\xaf\xd8\x07\x09", 20);
|
||||
|
||||
/* sha1digest */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/sha1file");
|
||||
assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA1),
|
||||
"\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90"
|
||||
"\xaf\xd8\x07\x09", 20);
|
||||
|
||||
/* sha256digest */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/sha256file");
|
||||
assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA256),
|
||||
"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
|
||||
"\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55",
|
||||
32);
|
||||
|
||||
/* sha384digest */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/sha384file");
|
||||
assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA384),
|
||||
"\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a"
|
||||
"\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda"
|
||||
"\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b",
|
||||
48);
|
||||
|
||||
/* sha512digest */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/sha512file");
|
||||
assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA512),
|
||||
"\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07"
|
||||
"\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce"
|
||||
"\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f"
|
||||
"\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e",
|
||||
64);
|
||||
|
||||
/* md5 digest is too short */
|
||||
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/md5tooshort");
|
||||
assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
|
||||
16, 0x00);
|
||||
|
||||
/* md5 digest is too long */
|
||||
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/md5toolong");
|
||||
assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
|
||||
16, 0x00);
|
||||
|
||||
/* md5 digest is uppercase hex */
|
||||
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/md5caphex");
|
||||
assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
|
||||
16, 0x00);
|
||||
|
||||
/* md5 digest is not hex */
|
||||
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/md5nothex");
|
||||
assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5),
|
||||
16, 0x00);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualInt(20, archive_file_count(a));
|
||||
assertEqualInt(30, archive_file_count(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
@ -16,6 +16,26 @@ M<&4]9FEL92!S:7IE/3DR,C,S-S(P,S8X-30W-S4X,#<*9&ER,B]T;V]B:6=F
|
||||
M:6QE('1Y<&4]9FEL92!S:7IE/3DR,C,S-S(P,S8X-30W-S4X,#@*9&ER,B]V
|
||||
M97)Y;VQD9FEL92!T>7!E/69I;&4@=&EM93TM.3(R,S,W,C`S-C@U-#<W-3@P
|
||||
M.`ID:7(R+W1O;V]L9&9I;&4@='EP93UF:6QE('1I;64]+3DR,C,S-S(P,S8X
|
||||
*-30W-S4X,#D*"@``
|
||||
M-30W-S4X,#D*9&ER,B]M9#5F:6QE('1Y<&4]9FEL92!M9#5D:6=E<W0]9#0Q
|
||||
M9#AC9#DX9C`P8C(P-&4Y.#`P.3DX96-F.#0R-V4@("`@("`@("`@("`@("`*
|
||||
M9&ER,B]R;60Q-C!F:6QE('1Y<&4]9FEL92!R;60Q-C!D:6=E<W0]9&$S.6$S
|
||||
M964U939B-&(P9#,R-35B9F5F.34V,#$X.3!A9F0X,#<P.2`@("`@("`@(`ID
|
||||
M:7(R+W-H83%F:6QE('1Y<&4]9FEL92!S:&$Q9&EG97-T/61A,SEA,V5E-64V
|
||||
M8C1B,&0S,C4U8F9E9CDU-C`Q.#DP869D.#`W,#D@("`@(`ID:7(R+W-H83(U
|
||||
M-F9I;&4@='EP93UF:6QE('-H83(U-F1I9V5S=#UE,V(P8S0T,CDX9F,Q8S$T
|
||||
M.6%F8F8T8S@Y.39F8CDR-#(W864T,64T-C0Y8CDS-&-A-#DU.3DQ8C<X-3)B
|
||||
M.#4U"F1I<C(O<VAA,S@T9FEL92!T>7!E/69I;&4@<VAA,S@T9&EG97-T/3,X
|
||||
M8C`V,&$W-3%A8SDV,S@T8V0Y,S(W96(Q8C%E,S9A,C%F9&(W,3$Q-&)E,#<T
|
||||
M,S1C,&-C-V)F-C-F-F4Q9&$R-S1E9&5B9F4W-F8V-69B9#4Q860R9C$T.#DX
|
||||
M8CDU8@ID:7(R+W-H834Q,F9I;&4@='EP93UF:6QE('-H834Q,F1I9V5S=#UC
|
||||
M9C@S93$S-3=E969B.&)D9C$U-#(X-3!D-C9D.#`P-V0V,C!E-#`U,&(U-S$U
|
||||
M9&,X,V8T83DR,60S-F-E.6-E-#=D,&0Q,V,U9#@U9C)B,&9F.#,Q.&0R.#<W
|
||||
M965C,F8V,V(Y,S%B9#0W-#$W83@Q834S.#,R-V%F.3(W9&$S90ID:7(R+VUD
|
||||
M-71O;W-H;W)T('1Y<&4]9FEL92!M9#5D:6=E<W0]9#0Q9#AC9#DX9C`P8C(P
|
||||
M-&4Y.#`P.3DX96-F.#0R-PID:7(R+VUD-71O;VQO;F<@='EP93UF:6QE(&UD
|
||||
M-61I9V5S=#UD-#%D.&-D.3AF,#!B,C`T93DX,#`Y.3AE8V8X-#(W96$*9&ER
|
||||
M,B]M9#5C87!H97@@='EP93UF:6QE(&UD-61I9V5S=#U$-#%$.$-$.3A&,#!"
|
||||
M,C`T13DX,#`Y.3A%0T8X-#(W10ID:7(R+VUD-6YO=&AE>"!T>7!E/69I;&4@
|
||||
K;60U9&EG97-T/7$T,60X8V0Y.&8P,&(R,#1E.3@P,#DY.&5C9C@T,C=E"@``
|
||||
`
|
||||
end
|
||||
|
@ -72,7 +72,7 @@ DEFINE_TEST(test_read_format_raw)
|
||||
extract_reference_file(reffile2);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_by_code(a, ARCHIVE_FORMAT_RAW));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, reffile2, 1));
|
||||
@ -100,8 +100,7 @@ DEFINE_TEST(test_read_format_raw)
|
||||
extract_reference_file(reffile3);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_set_format(a, ARCHIVE_FORMAT_RAW));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, reffile3, 1));
|
||||
|
||||
|
@ -966,3 +966,35 @@ DEFINE_TEST(test_read_format_zip_lzma_stream_end_blockread)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_7z_lzma)
|
||||
{
|
||||
const char *refname = "test_read_format_zip_7z_lzma.zip";
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, refname, 10240));
|
||||
//read directories
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
//read symlink
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
|
||||
assertEqualString("../samples/abc_measurement_analysis_sample"
|
||||
"/src/abc_measurement_analysis_sample.py",
|
||||
archive_entry_symlink(ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
begin 644 test_read_format_zip_7z_lzma.zip
|
||||
M4$L#!`H#`````.$#)%$````````````````,````7VEN<W1A;&QD:7(O4$L#
|
||||
M!`H#`````,0#)%$````````````````6````7VEN<W1A;&QD:7(O86)C7W1O
|
||||
M;VQS+U!+`P0*`P````"``R11````````````````)````%]I;G-T86QL9&ER
|
||||
M+V%B8U]T;V]L<R\R,#`P+CDM8F5T83$Q+U!+`P0*`P````"%!"11````````
|
||||
M````````*````%]I;G-T86QL9&ER+V%B8U]T;V]L<R\R,#`P+CDM8F5T83$Q
|
||||
M+V)I;B]02P,$%`,```X`?00D4<2?]W$]````40```$<```!?:6YS=&%L;&1I
|
||||
M<B]A8F-?=&]O;',O,C`P,"XY+6)E=&$Q,2]B:6XO86)C7VUE87-U<F5M96YT
|
||||
M7V%N86QY<VES7W-A;7!L900]!0!=````!``78+CF838[WSK=V4<NKP&%(\A'
|
||||
MDM]PR'OV^=/9>A79\GCDS+I*=O.=!+"5(),_1O%5^1102P,$"@,`````]0,D
|
||||
M40```````````````"P```!?:6YS=&%L;&1I<B]A8F-?=&]O;',O,C`P,"XY
|
||||
M+6)E=&$Q,2]S86UP;&5S+U!+`P0*`P````!J`R11````````````````3```
|
||||
M`%]I;G-T86QL9&ER+V%B8U]T;V]L<R\R,#`P+CDM8F5T83$Q+W-A;7!L97,O
|
||||
M86)C7VUE87-U<F5M96YT7V%N86QY<VES7W-A;7!L92]02P,$"@,`````R00D
|
||||
M40```````````````%````!?:6YS=&%L;&1I<B]A8F-?=&]O;',O,C`P,"XY
|
||||
M+6)E=&$Q,2]S86UP;&5S+V%B8U]M96%S=7)E;65N=%]A;F%L>7-I<U]S86UP
|
||||
M;&4O<W)C+U!+`P04`P``#@#)!"11&O[CEV0```#Z````<@```%]I;G-T86QL
|
||||
M9&ER+V%B8U]T;V]L<R\R,#`P+CDM8F5T83$Q+W-A;7!L97,O86)C7VUE87-U
|
||||
M<F5M96YT7V%N86QY<VES7W-A;7!L92]S<F,O86)C7VUE87-U<F5M96YT7V%N
|
||||
M86QY<VES7W-A;7!L92YP>00]!0!=````!``1B$)'BB,SPW</,_U5E^VGQ_#J
|
||||
M*D,VRB^`L-1YB&E9ZQ@#)Z;.!DA4-N"JARAW#NR&V]%F']BN`WU@#,0-<1)%
|
||||
M/6DBM+7=&`\IF.F\E3\E9D*1:/'I+057:TA02P$"%`,*`P````#A`R11````
|
||||
M````````````#````````````!"`Z$$`````7VEN<W1A;&QD:7(O4$L!`A0#
|
||||
M"@,`````Q`,D40```````````````!8````````````0@.A!*@```%]I;G-T
|
||||
M86QL9&ER+V%B8U]T;V]L<R]02P$"%`,*`P````"``R11````````````````
|
||||
M)````````````!"`Z$%>````7VEN<W1A;&QD:7(O86)C7W1O;VQS+S(P,#`N
|
||||
M.2UB971A,3$O4$L!`A0#"@,`````A00D40```````````````"@`````````
|
||||
M```0@.A!H````%]I;G-T86QL9&ER+V%B8U]T;V]L<R\R,#`P+CDM8F5T83$Q
|
||||
M+V)I;B]02P$"%`,4`P``#@!]!"11Q)_W<3T```!1````1P```````````""`
|
||||
M_Z'F````7VEN<W1A;&QD:7(O86)C7W1O;VQS+S(P,#`N.2UB971A,3$O8FEN
|
||||
M+V%B8U]M96%S=7)E;65N=%]A;F%L>7-I<U]S86UP;&502P$"%`,*`P````#U
|
||||
M`R11````````````````+````````````!"`Z$&(`0``7VEN<W1A;&QD:7(O
|
||||
M86)C7W1O;VQS+S(P,#`N.2UB971A,3$O<V%M<&QE<R]02P$"%`,*`P````!J
|
||||
M`R11````````````````3````````````!"`Z$'2`0``7VEN<W1A;&QD:7(O
|
||||
M86)C7W1O;VQS+S(P,#`N.2UB971A,3$O<V%M<&QE<R]A8F-?;65A<W5R96UE
|
||||
M;G1?86YA;'ES:7-?<V%M<&QE+U!+`0(4`PH#`````,D$)%$`````````````
|
||||
M``!0````````````$(#H03P"``!?:6YS=&%L;&1I<B]A8F-?=&]O;',O,C`P
|
||||
M,"XY+6)E=&$Q,2]S86UP;&5S+V%B8U]M96%S=7)E;65N=%]A;F%L>7-I<U]S
|
||||
M86UP;&4O<W)C+U!+`0(4`Q0#```.`,D$)%$:_N.79````/H```!R````````
|
||||
M````((#H@:H"``!?:6YS=&%L;&1I<B]A8F-?=&]O;',O,C`P,"XY+6)E=&$Q
|
||||
M,2]S86UP;&5S+V%B8U]M96%S=7)E;65N=%]A;F%L>7-I<U]S86UP;&4O<W)C
|
||||
M+V%B8U]M96%S=7)E;65N=%]A;F%L>7-I<U]S86UP;&4N<'E02P4&``````D`
|
||||
,"0"-`P``G@,`````
|
||||
`
|
||||
end
|
@ -201,11 +201,6 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
FILE * fp;
|
||||
int fd;
|
||||
fpos_t pos;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we have "bunzip2 -q", try using that.
|
||||
@ -215,14 +210,6 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
/* bunzip2 will write to stderr, redirect it to a file */
|
||||
fflush(stderr);
|
||||
fgetpos(stderr, &pos);
|
||||
assert((fd = dup(fileno(stderr))) != -1);
|
||||
fp = freopen("stderr1", "w", stderr);
|
||||
#endif
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
@ -232,16 +219,4 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
|
||||
assertA(archive_read_next_header(a, &ae) < (ARCHIVE_WARN));
|
||||
assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
/* restore stderr and verify results */
|
||||
if (fp != NULL) {
|
||||
fflush(stderr);
|
||||
dup2(fd, fileno(stderr));
|
||||
clearerr(stderr);
|
||||
(void)fsetpos(stderr, &pos);
|
||||
}
|
||||
close(fd);
|
||||
assertTextFileContents("bunzip2: (stdin) is not a bzip2 file.\n", "stderr1");
|
||||
#endif
|
||||
}
|
||||
|
@ -40,6 +40,10 @@ DEFINE_TEST(test_write_disk_secure)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct stat st;
|
||||
#if defined(HAVE_LCHMOD) && defined(HAVE_SYMLINK) && \
|
||||
defined(S_IRUSR) && defined(S_IWUSR) && defined(S_IXUSR)
|
||||
int working_lchmod;
|
||||
#endif
|
||||
|
||||
/* Start with a known umask. */
|
||||
assertUmask(UMASK);
|
||||
@ -251,10 +255,32 @@ DEFINE_TEST(test_write_disk_secure)
|
||||
assert(0 == lstat("link_to_dir", &st));
|
||||
failure("link_to_dir: st.st_mode=%o", st.st_mode);
|
||||
assert(S_ISLNK(st.st_mode));
|
||||
#if HAVE_LCHMOD
|
||||
/* Systems that lack lchmod() can't set symlink perms, so skip this. */
|
||||
failure("link_to_dir: st.st_mode=%o", st.st_mode);
|
||||
assert((st.st_mode & 07777) == 0755);
|
||||
#if defined(HAVE_SYMLINK) && defined(HAVE_LCHMOD) && \
|
||||
defined(S_IRUSR) && defined(S_IWUSR) && defined(S_IXUSR)
|
||||
/* Verify if we are able to lchmod() */
|
||||
if (symlink("dir", "testlink_to_dir") == 0) {
|
||||
if (lchmod("testlink_to_dir",
|
||||
S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
|
||||
switch (errno) {
|
||||
case ENOTSUP:
|
||||
case ENOSYS:
|
||||
#if ENOTSUP != EOPNOTSUPP
|
||||
case EOPNOTSUPP:
|
||||
#endif
|
||||
working_lchmod = 0;
|
||||
break;
|
||||
default:
|
||||
working_lchmod = 1;
|
||||
}
|
||||
} else
|
||||
working_lchmod = 1;
|
||||
} else
|
||||
working_lchmod = 0;
|
||||
|
||||
if (working_lchmod) {
|
||||
failure("link_to_dir: st.st_mode=%o", st.st_mode);
|
||||
assert((st.st_mode & 07777) == 0755);
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(0 == lstat("dir/filea", &st));
|
||||
|
@ -141,6 +141,17 @@ test_format(int (*set_format)(struct archive *))
|
||||
archive_entry_free(ae);
|
||||
assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
|
||||
|
||||
/*
|
||||
* Write a character device to it.
|
||||
*/
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "tty0");
|
||||
archive_entry_set_mode(ae, S_IFCHR | 0600);
|
||||
archive_entry_set_size(ae, 0);
|
||||
archive_entry_set_rdev(ae, 1024);
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
archive_entry_free(ae);
|
||||
|
||||
|
||||
/* Close out the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
|
||||
@ -212,6 +223,15 @@ test_format(int (*set_format)(struct archive *))
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
|
||||
|
||||
/*
|
||||
* Read the character device entry back.
|
||||
*/
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("tty0", archive_entry_pathname(ae));
|
||||
assertEqualInt((S_IFCHR | 0600), archive_entry_mode(ae));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
assertEqualInt(1024, archive_entry_rdev(ae));
|
||||
|
||||
/* Verify the end of the archive. */
|
||||
assertEqualIntA(a, 1, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
|
@ -26,6 +26,19 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
static void test_read(struct archive *a, char *buff, size_t used, char *filedata)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, 9, archive_read_data(a, filedata, 10));
|
||||
assertEqualMem(filedata, "12345678", 9);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_write_format_warc)
|
||||
{
|
||||
char filedata[64];
|
||||
@ -62,14 +75,15 @@ DEFINE_TEST(test_write_format_warc)
|
||||
*/
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_warc(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
|
||||
test_read(a, buff, used, filedata);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, 9, archive_read_data(a, filedata, 10));
|
||||
assertEqualMem(filedata, "12345678", 9);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_by_code(a, ARCHIVE_FORMAT_WARC));
|
||||
test_read(a, buff, used, filedata);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_set_format(a, ARCHIVE_FORMAT_WARC));
|
||||
test_read(a, buff, used, filedata);
|
||||
|
||||
/* Create a new archive */
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
|
@ -169,6 +169,9 @@
|
||||
/* chdir() and error if it fails */
|
||||
#define assertChdir(path) \
|
||||
assertion_chdir(__FILE__, __LINE__, path)
|
||||
/* change file/directory permissions and errors if it fails */
|
||||
#define assertChmod(pathname, mode) \
|
||||
assertion_chmod(__FILE__, __LINE__, pathname, mode)
|
||||
/* Assert two files have the same file flags */
|
||||
#define assertEqualFflags(patha, pathb) \
|
||||
assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0)
|
||||
@ -282,6 +285,7 @@
|
||||
void failure(const char *fmt, ...) __LA_PRINTFLIKE(1, 2);
|
||||
int assertion_assert(const char *, int, int, const char *, void *);
|
||||
int assertion_chdir(const char *, int, const char *);
|
||||
int assertion_chmod(const char *, int, const char *, int);
|
||||
int assertion_compare_fflags(const char *, int, const char *, const char *,
|
||||
int);
|
||||
int assertion_empty_file(const char *, int, const char *);
|
||||
|
@ -597,6 +597,19 @@ assertion_chdir(const char *file, int line, const char *pathname)
|
||||
|
||||
}
|
||||
|
||||
/* change file/directory permissions and errors if it fails */
|
||||
int
|
||||
assertion_chmod(const char *file, int line, const char *pathname, int mode)
|
||||
{
|
||||
assertion_count(file, line);
|
||||
if (chmod(pathname, mode) == 0)
|
||||
return (1);
|
||||
failure_start(file, line, "chmod(\"%s\", %4.o)", pathname, mode);
|
||||
failure_finish(NULL);
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
/* Verify two integers are equal. */
|
||||
int
|
||||
assertion_equal_int(const char *file, int line,
|
||||
|
@ -71,6 +71,7 @@ SRCS= archive_acl.c \
|
||||
archive_read_set_options.c \
|
||||
archive_read_support_filter_all.c \
|
||||
archive_read_support_filter_bzip2.c \
|
||||
archive_read_support_filter_by_code.c \
|
||||
archive_read_support_filter_compress.c \
|
||||
archive_read_support_filter_gzip.c \
|
||||
archive_read_support_filter_grzip.c \
|
||||
|
@ -26,6 +26,7 @@
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
|
||||
|
||||
#include <osreldate.h>
|
||||
|
||||
|
@ -577,6 +577,7 @@ ${PACKAGE}FILES+= test_read_format_ustar_filename_koi8r.tar.Z.uu
|
||||
${PACKAGE}FILES+= test_read_format_warc.warc.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_7075_utf8_paths.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_7z_lzma.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_bz2_hang.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_bzip2.zipx.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_bzip2_multi.zipx.uu
|
||||
|
@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive
|
||||
_LIBARCHIVECONFDIR= ${SRCTOP}/lib/libarchive
|
||||
|
||||
PROG= bsdcat
|
||||
BSDCAT_VERSION_STRING= 3.4.3
|
||||
BSDCAT_VERSION_STRING= 3.5.0
|
||||
|
||||
.PATH: ${_LIBARCHIVEDIR}/cat
|
||||
SRCS= bsdcat.c cmdline.c
|
||||
|
@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive
|
||||
_LIBARCHIVECONFDIR= ${SRCTOP}/lib/libarchive
|
||||
|
||||
PROG= bsdcpio
|
||||
BSDCPIO_VERSION_STRING= 3.4.3
|
||||
BSDCPIO_VERSION_STRING= 3.5.0
|
||||
|
||||
.PATH: ${_LIBARCHIVEDIR}/cpio
|
||||
SRCS= cpio.c cmdline.c
|
||||
|
@ -5,7 +5,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive
|
||||
|
||||
PACKAGE= runtime
|
||||
PROG= bsdtar
|
||||
BSDTAR_VERSION_STRING= 3.4.3
|
||||
BSDTAR_VERSION_STRING= 3.5.0
|
||||
|
||||
.PATH: ${_LIBARCHIVEDIR}/tar
|
||||
SRCS= bsdtar.c \
|
||||
|
Loading…
Reference in New Issue
Block a user