Update vendor/libarchive/dist to git 833821f55b1807cac22a63a58b759a7802df2fb7

Libarchive 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
This commit is contained in:
Martin Matuska 2020-12-01 10:36:46 +00:00
parent 4dd2ae60c2
commit d5f2a5ff11
68 changed files with 1346 additions and 199 deletions

View File

@ -12,7 +12,7 @@ FreeBSD_task:
freebsd_instance: freebsd_instance:
image_family: freebsd-12-1 image_family: freebsd-12-1
freebsd_instance: freebsd_instance:
image: freebsd-11-3-stable-amd64-v20190801 image_family: freebsd-11-4
prepare_script: prepare_script:
- ./build/ci/cirrus_ci/ci.sh prepare - ./build/ci/cirrus_ci/ci.sh prepare
configure_script: configure_script:

View File

@ -43,7 +43,7 @@ jobs:
path: libarchive.tar.xz path: libarchive.tar.xz
Ubuntu: Ubuntu:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
strategy: strategy:
matrix: matrix:
bs: [autotools, cmake] bs: [autotools, cmake]
@ -83,7 +83,7 @@ jobs:
name: libarchive-ubuntu-${{ matrix.bs }}-${{ matrix.crypto }}-${{ github.sha }} name: libarchive-ubuntu-${{ matrix.bs }}-${{ matrix.crypto }}-${{ github.sha }}
path: libarchive.tar.xz path: libarchive.tar.xz
Ubuntu-distcheck: Ubuntu-distcheck:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: Install dependencies - name: Install dependencies

View File

@ -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 * The following source files are also subject in whole or in part to
a 3-clause UC Regents copyright; please read the individual source a 3-clause UC Regents copyright; please read the individual source
files for details: files for details:
libarchive/archive_entry.c
libarchive/archive_read_support_filter_compress.c libarchive/archive_read_support_filter_compress.c
libarchive/archive_write_add_filter_compress.c libarchive/archive_write_add_filter_compress.c
libarchive/mtree.5 libarchive/mtree.5

View File

@ -158,6 +158,7 @@ libarchive_la_SOURCES= \
libarchive/archive_read_set_options.c \ libarchive/archive_read_set_options.c \
libarchive/archive_read_support_filter_all.c \ libarchive/archive_read_support_filter_all.c \
libarchive/archive_read_support_filter_bzip2.c \ libarchive/archive_read_support_filter_bzip2.c \
libarchive/archive_read_support_filter_by_code.c \
libarchive/archive_read_support_filter_compress.c \ libarchive/archive_read_support_filter_compress.c \
libarchive/archive_read_support_filter_grzip.c \ libarchive/archive_read_support_filter_grzip.c \
libarchive/archive_read_support_filter_gzip.c \ libarchive/archive_read_support_filter_gzip.c \
@ -897,6 +898,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_warc.warc.uu \ libarchive/test/test_read_format_warc.warc.uu \
libarchive/test/test_read_format_zip.zip.uu \ libarchive/test/test_read_format_zip.zip.uu \
libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \ libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \
libarchive/test/test_read_format_zip_7z_lzma.zip.uu \
libarchive/test/test_read_format_zip_bz2_hang.zip.uu \ libarchive/test/test_read_format_zip_bz2_hang.zip.uu \
libarchive/test/test_read_format_zip_bzip2.zipx.uu \ libarchive/test/test_read_format_zip_bzip2.zipx.uu \
libarchive/test/test_read_format_zip_bzip2_multi.zipx.uu \ libarchive/test/test_read_format_zip_bzip2_multi.zipx.uu \

4
NEWS
View File

@ -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 May 20, 2020: libarchive 3.4.3 released
Apr 30, 2020: Support for pzstd compressed files Apr 30, 2020: Support for pzstd compressed files

View File

@ -1,9 +1,24 @@
#!/bin/sh #!/bin/sh
if [ "$1" = "prepare" ] if [ "$1" = "prepare" ]
then then
set -x -e set -x
brew uninstall openssl@1.0.2t > /dev/null
brew uninstall python@2.7.17 > /dev/null
brew untap local/openssl > /dev/null
brew untap local/python2 > /dev/null
brew update > /dev/null brew update > /dev/null
for pkg in autoconf automake libtool pkg-config cmake xz lz4 zstd brew upgrade > /dev/null
set -x -e
for pkg in \
autoconf \
automake \
libtool \
pkg-config \
cmake \
xz \
lz4 \
zstd \
openssl
do do
brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg
done done

View File

@ -1,4 +1,5 @@
/* config.h. Generated from build/cmake/config.h.in by cmake configure */ /* config.h. Generated from build/cmake/config.h.in by cmake configure */
#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
/* /*
* Ensure we have C99-style int64_t, etc, all defined. * Ensure we have C99-style int64_t, etc, all defined.

View File

@ -1,5 +1,7 @@
FROM ubuntu:18.04 FROM ubuntu:20.04
RUN apt-get update && apt-get install -y build-essential autoconf automake libtool pkg-config cmake libssl-dev libacl1-dev libbz2-dev liblzma-dev liblz4-dev libzstd-dev lzop groff ghostscript bsdmainutils zip ENV DEBIAN_FRONTEND=noninteractive
RUN ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
RUN apt-get update && apt-get install -y build-essential autoconf automake libtool pkg-config cmake zlib1g-dev libssl-dev libacl1-dev libbz2-dev liblzma-dev liblz4-dev libzstd-dev lzop groff ghostscript bsdmainutils zip
ADD . $HOME/libarchive/ ADD . $HOME/libarchive/
ADD "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD" $HOME/libarchive/build/autoconf/config.guess ADD "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD" $HOME/libarchive/build/autoconf/config.guess
ADD "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD" $HOME/libarchive/build/autoconf/config.sub ADD "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD" $HOME/libarchive/build/autoconf/config.sub

View File

@ -1 +1 @@
3004003 3005000

View File

@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release. dnl These first two version numbers are updated automatically on each release.
m4_define([LIBARCHIVE_VERSION_S],[3.4.3]) m4_define([LIBARCHIVE_VERSION_S],[3.5.0])
m4_define([LIBARCHIVE_VERSION_N],[3004003]) m4_define([LIBARCHIVE_VERSION_N],[3005000])
dnl bsdtar and bsdcpio versioning tracks libarchive dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
@ -47,6 +47,8 @@ ARCHIVE_REVISION=$(( LIBARCHIVE_VERSION_N() % 1000 ))
ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR
# Stick the version numbers into config.h # Stick the version numbers into config.h
AC_DEFINE([__LIBARCHIVE_CONFIG_H_INCLUDED], [1],
[Internal macro for sanity checks])
AC_DEFINE([LIBARCHIVE_VERSION_STRING],"LIBARCHIVE_VERSION_S()", AC_DEFINE([LIBARCHIVE_VERSION_STRING],"LIBARCHIVE_VERSION_S()",
[Version number of libarchive]) [Version number of libarchive])
AC_DEFINE_UNQUOTED([LIBARCHIVE_VERSION_NUMBER],"LIBARCHIVE_VERSION_N()", AC_DEFINE_UNQUOTED([LIBARCHIVE_VERSION_NUMBER],"LIBARCHIVE_VERSION_N()",
@ -103,6 +105,7 @@ AC_SUBST(PLATFORMCPPFLAGS)
# Checks for programs. # Checks for programs.
AC_PROG_CC AC_PROG_CC
AC_PROG_CC_C99
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_USE_SYSTEM_EXTENSIONS AC_USE_SYSTEM_EXTENSIONS
AC_LIBTOOL_WIN32_DLL AC_LIBTOOL_WIN32_DLL
@ -244,9 +247,23 @@ AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ])
# Set up defines needed before including any headers # Set up defines needed before including any headers
case $host in case $host in
*mingw* | *cygwin* | *msys* ) *mingw* | *cygwin* | *msys* )
AC_DEFINE([_WIN32_WINNT], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.]) AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
AC_DEFINE([WINVER], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.]) [[#ifdef _WIN32_WINNT
AC_DEFINE([NTDDI_VERSION], 0x05020000, [Define to '0x05020000' for Windows Server 2003 APIs.]) # error _WIN32_WINNT already defined
#endif
]],[[;]])
],[
AC_DEFINE([_WIN32_WINNT], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.])
AC_DEFINE([NTDDI_VERSION], 0x05020000, [Define to '0x05020000' for Windows Server 2003 APIs.])
])
AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
[[#ifdef WINVER
# error WINVER already defined
#endif
]],[[;]])
],[
AC_DEFINE([WINVER], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.])
])
;; ;;
esac esac

View File

@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108. * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/ */
/* Note: Compiler will complain if this does not match archive_entry.h! */ /* 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 <sys/stat.h>
#include <stddef.h> /* for wchar_t */ #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. * 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 #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void); __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_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. /* 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 * This is useful for reading from different data blocks such as a set of files
* that make up one large file. * that make up one large file.
@ -418,6 +420,7 @@ __LA_DECL int archive_read_support_compression_xz(struct archive *)
#endif #endif
__LA_DECL int archive_read_support_filter_all(struct archive *); __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_bzip2(struct archive *);
__LA_DECL int archive_read_support_filter_compress(struct archive *); __LA_DECL int archive_read_support_filter_compress(struct archive *);
__LA_DECL int archive_read_support_filter_gzip(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_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_deflate(struct archive *);
__LA_DECL int archive_write_zip_set_compression_store(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 *, __LA_DECL int archive_write_open(struct archive *, void *,
archive_open_callback *, archive_write_callback *, archive_open_callback *, archive_write_callback *,
archive_close_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_fd(struct archive *, int _fd);
__LA_DECL int archive_write_open_filename(struct archive *, const char *_file); __LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
__LA_DECL int archive_write_open_filename_w(struct archive *, __LA_DECL int archive_write_open_filename_w(struct archive *,

View File

@ -595,7 +595,7 @@ archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
else else
length += sizeof(uid_t) * 3 + 1; length += sizeof(uid_t) * 3 + 1;
} else { } else {
r = archive_mstring_get_mbs_l(&ap->name, &name, r = archive_mstring_get_mbs_l(a, &ap->name, &name,
&len, sc); &len, sc);
if (r != 0) if (r != 0)
return (0); return (0);
@ -968,7 +968,7 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
else else
prefix = NULL; prefix = NULL;
r = archive_mstring_get_mbs_l( r = archive_mstring_get_mbs_l(
&ap->name, &name, &len, sc); NULL, &ap->name, &name, &len, sc);
if (r != 0) { if (r != 0) {
free(s); free(s);
return (NULL); return (NULL);
@ -1402,14 +1402,14 @@ isint_w(const wchar_t *start, const wchar_t *end, int *result)
if (start >= end) if (start >= end)
return (0); return (0);
while (start < end) { while (start < end) {
if (*start < '0' || *start > '9') if (*start < L'0' || *start > L'9')
return (0); return (0);
if (n > (INT_MAX / 10) || 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; n = INT_MAX;
} else { } else {
n *= 10; n *= 10;
n += *start - '0'; n += *start - L'0';
} }
start++; start++;
} }

View File

@ -54,7 +54,7 @@ errmsg(const char *m)
ssize_t written; ssize_t written;
while (s > 0) { while (s > 0) {
written = write(2, m, strlen(m)); written = write(2, m, s);
if (written <= 0) if (written <= 0)
return; return;
m += written; m += written;

View File

@ -347,8 +347,31 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
static int static int
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) 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_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce); 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; return 0;
} }

View File

@ -104,9 +104,18 @@ typedef struct {
#include <nettle/pbkdf2.h> #include <nettle/pbkdf2.h>
#endif #endif
#include <nettle/aes.h> #include <nettle/aes.h>
#include <nettle/version.h>
typedef struct { typedef struct {
#if NETTLE_VERSION_MAJOR < 3
struct aes_ctx ctx; 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]; uint8_t key[AES_MAX_KEY_SIZE];
unsigned key_len; unsigned key_len;
uint8_t nonce[AES_BLOCK_SIZE]; uint8_t nonce[AES_BLOCK_SIZE];

View File

@ -30,6 +30,10 @@
#ifndef __LIBARCHIVE_BUILD #ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive. #error This header is only to be used internally to libarchive.
#endif #endif
#ifndef __LIBARCHIVE_CONFIG_H_INCLUDED
#error "Should have include config.h first!"
#endif
/* /*
* Crypto support in various Operating Systems: * Crypto support in various Operating Systems:
* *

View File

@ -208,6 +208,19 @@ archive_entry_clone(struct archive_entry *entry)
/* Copy encryption status */ /* Copy encryption status */
entry2->encryption = entry->encryption; 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. */ /* Copy ACL data over. */
archive_acl_copy(&entry2->acl, &entry->acl); archive_acl_copy(&entry2->acl, &entry->acl);
@ -450,7 +463,7 @@ int
_archive_entry_gname_l(struct archive_entry *entry, _archive_entry_gname_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc) 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 * const char *
@ -504,7 +517,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
*len = 0; *len = 0;
return (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 la_int64_t
@ -595,7 +608,7 @@ int
_archive_entry_pathname_l(struct archive_entry *entry, _archive_entry_pathname_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc) 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 __LA_MODE_T
@ -723,7 +736,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
*len = 0; *len = 0;
return (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 la_int64_t
@ -769,7 +782,7 @@ int
_archive_entry_uname_l(struct archive_entry *entry, _archive_entry_uname_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc) 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 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 * ACL management. The following would, of course, be a lot simpler
* if: 1) the last draft of POSIX.1e were a really thorough and * if: 1) the last draft of POSIX.1e were a really thorough and

View File

@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED #define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */ /* 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 * 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 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); __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 * ACL routines. This used to simply store and return text-format ACL
* strings, but that proved insufficient for a number of reasons: * strings, but that proved insufficient for a number of reasons:

View File

@ -50,6 +50,15 @@ struct ae_sparse {
int64_t length; 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. * Description of an archive entry.
* *
@ -162,6 +171,9 @@ struct archive_entry {
void *mac_metadata; void *mac_metadata;
size_t mac_metadata_size; size_t mac_metadata_size;
/* Digest support. */
struct ae_digest digest;
/* ACL support. */ /* ACL support. */
struct archive_acl acl; struct archive_acl acl;
@ -181,4 +193,8 @@ struct archive_entry {
int ae_symlink_type; 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 */ #endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

View File

@ -4,7 +4,7 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "archive_platform.h" #include "archive_platform.h"
#include <memory.h> #include <stdlib.h>
#include "archive_ppmd7_private.h" #include "archive_ppmd7_private.h"

View File

@ -103,6 +103,10 @@ __FBSDID("$FreeBSD");
static int setup_mac_metadata(struct archive_read_disk *, static int setup_mac_metadata(struct archive_read_disk *,
struct archive_entry *, int *fd); 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 *, static int setup_xattrs(struct archive_read_disk *,
struct archive_entry *, int *fd); struct archive_entry *, int *fd);
static int setup_sparse(struct archive_read_disk *, 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 static int
setup_xattrs(struct archive_read_disk *a, setup_xattrs_namespace(struct archive_read_disk *a,
struct archive_entry *entry, int *fd) struct archive_entry *entry, int *fd, int namespace)
{ {
char buff[512]; char buff[512];
char *list, *p; char *list, *p;
ssize_t list_size; ssize_t list_size;
const char *path; const char *path;
int namespace = EXTATTR_NAMESPACE_USER;
path = NULL; path = NULL;
@ -727,6 +730,8 @@ setup_xattrs(struct archive_read_disk *a,
if (list_size == -1 && errno == EOPNOTSUPP) if (list_size == -1 && errno == EOPNOTSUPP)
return (ARCHIVE_OK); return (ARCHIVE_OK);
if (list_size == -1 && errno == EPERM)
return (ARCHIVE_OK);
if (list_size == -1) { if (list_size == -1) {
archive_set_error(&a->archive, errno, archive_set_error(&a->archive, errno,
"Couldn't list extended attributes"); "Couldn't list extended attributes");
@ -760,7 +765,17 @@ setup_xattrs(struct archive_read_disk *a,
size_t len = 255 & (int)*p; size_t len = 255 & (int)*p;
char *name; 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); name = buff + strlen(buff);
memcpy(name, p + 1, len); memcpy(name, p + 1, len);
name[len] = '\0'; name[len] = '\0';
@ -772,6 +787,31 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_OK); 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 #else
/* /*

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd August 14, 2014 .Dd June 9, 2020
.Dt ARCHIVE_READ_FILTER 3 .Dt ARCHIVE_READ_FILTER 3
.Os .Os
.Sh NAME .Sh NAME
@ -50,6 +50,8 @@ Streaming Archive Library (libarchive, -larchive)
.Ft int .Ft int
.Fn archive_read_support_filter_all "struct archive *" .Fn archive_read_support_filter_all "struct archive *"
.Ft int .Ft int
.Fn archive_read_support_filter_by_code "struct archive *" "int"
.Ft int
.Fn archive_read_support_filter_bzip2 "struct archive *" .Fn archive_read_support_filter_bzip2 "struct archive *"
.Ft int .Ft int
.Fn archive_read_support_filter_compress "struct archive *" .Fn archive_read_support_filter_compress "struct archive *"
@ -116,6 +118,14 @@ Note that
is always enabled by default. is always enabled by default.
.It Fn archive_read_support_filter_all .It Fn archive_read_support_filter_all
Enables all available decompression filters. 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 .It Fn archive_read_support_filter_program
Data is fed through the specified external program before being dearchived. Data is fed through the specified external program before being dearchived.
Note that this disables automatic detection of the compression format, Note that this disables automatic detection of the compression format,

View File

@ -61,6 +61,9 @@ archive_read_set_format(struct archive *_a, int code)
case ARCHIVE_FORMAT_CPIO: case ARCHIVE_FORMAT_CPIO:
strcpy(str, "cpio"); strcpy(str, "cpio");
break; break;
case ARCHIVE_FORMAT_EMPTY:
strcpy(str, "empty");
break;
case ARCHIVE_FORMAT_ISO9660: case ARCHIVE_FORMAT_ISO9660:
strcpy(str, "iso9660"); strcpy(str, "iso9660");
break; break;
@ -76,9 +79,15 @@ archive_read_set_format(struct archive *_a, int code)
case ARCHIVE_FORMAT_RAR_V5: case ARCHIVE_FORMAT_RAR_V5:
strcpy(str, "rar5"); strcpy(str, "rar5");
break; break;
case ARCHIVE_FORMAT_RAW:
strcpy(str, "raw");
break;
case ARCHIVE_FORMAT_TAR: case ARCHIVE_FORMAT_TAR:
strcpy(str, "tar"); strcpy(str, "tar");
break; break;
case ARCHIVE_FORMAT_WARC:
strcpy(str, "warc");
break;
case ARCHIVE_FORMAT_XAR: case ARCHIVE_FORMAT_XAR:
strcpy(str, "xar"); strcpy(str, "xar");
break; break;

View File

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

View File

@ -26,6 +26,10 @@
#include "archive_platform.h" #include "archive_platform.h"
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "archive.h" #include "archive.h"
#include "archive_private.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: case ARCHIVE_FORMAT_CPIO:
return archive_read_support_format_cpio(a); return archive_read_support_format_cpio(a);
break; break;
case ARCHIVE_FORMAT_EMPTY:
return archive_read_support_format_empty(a);
break;
case ARCHIVE_FORMAT_ISO9660: case ARCHIVE_FORMAT_ISO9660:
return archive_read_support_format_iso9660(a); return archive_read_support_format_iso9660(a);
break; break;
@ -63,9 +70,15 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
case ARCHIVE_FORMAT_RAR_V5: case ARCHIVE_FORMAT_RAR_V5:
return archive_read_support_format_rar5(a); return archive_read_support_format_rar5(a);
break; break;
case ARCHIVE_FORMAT_RAW:
return archive_read_support_format_raw(a);
break;
case ARCHIVE_FORMAT_TAR: case ARCHIVE_FORMAT_TAR:
return archive_read_support_format_tar(a); return archive_read_support_format_tar(a);
break; break;
case ARCHIVE_FORMAT_WARC:
return archive_read_support_format_warc(a);
break;
case ARCHIVE_FORMAT_XAR: case ARCHIVE_FORMAT_XAR:
return archive_read_support_format_xar(a); return archive_read_support_format_xar(a);
break; break;
@ -73,5 +86,7 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
return archive_read_support_format_zip(a); return archive_read_support_format_zip(a);
break; break;
} }
archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
"Invalid format code specified");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }

View File

@ -1172,7 +1172,7 @@ cab_checksum_finish(struct archive_read *a)
cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated); cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
if (cfdata->sum_calculated != cfdata->sum) { if (cfdata->sum_calculated != cfdata->sum) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 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, cab->entry_cffolder->cfdata_index -1,
cfdata->sum, cfdata->sum_calculated, cfdata->sum, cfdata->sum_calculated,
cfdata->compressed_size); cfdata->compressed_size);

View File

@ -47,7 +47,7 @@ archive_read_support_format_empty(struct archive *_a)
r = __archive_read_register_format(a, r = __archive_read_register_format(a,
NULL, NULL,
NULL, "empty",
archive_read_format_empty_bid, archive_read_format_empty_bid,
NULL, NULL,
archive_read_format_empty_read_header, archive_read_format_empty_read_header,

View File

@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
#include "archive.h" #include "archive.h"
#include "archive_entry.h" #include "archive_entry.h"
#include "archive_entry_private.h"
#include "archive_private.h" #include "archive_private.h"
#include "archive_rb.h" #include "archive_rb.h"
#include "archive_read_private.h" #include "archive_read_private.h"
@ -1482,6 +1483,84 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
#undef MAX_PACK_ARGS #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. * Parse a single keyword and its value.
*/ */
@ -1580,8 +1659,10 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
} }
__LA_FALLTHROUGH; __LA_FALLTHROUGH;
case 'm': case 'm':
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) {
break; return parse_digest(a, entry, val,
ARCHIVE_ENTRY_DIGEST_MD5);
}
if (strcmp(key, "mode") == 0) { if (strcmp(key, "mode") == 0) {
if (val[0] >= '0' && val[0] <= '7') { if (val[0] >= '0' && val[0] <= '7') {
*parsed_kws |= MTREE_HAS_PERM; *parsed_kws |= MTREE_HAS_PERM;
@ -1617,21 +1698,32 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
return r; return r;
} }
if (strcmp(key, "rmd160") == 0 || if (strcmp(key, "rmd160") == 0 ||
strcmp(key, "rmd160digest") == 0) strcmp(key, "rmd160digest") == 0) {
break; return parse_digest(a, entry, val,
ARCHIVE_ENTRY_DIGEST_RMD160);
}
__LA_FALLTHROUGH; __LA_FALLTHROUGH;
case 's': case 's':
if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0) if (strcmp(key, "sha1") == 0 ||
break; strcmp(key, "sha1digest") == 0) {
return parse_digest(a, entry, val,
ARCHIVE_ENTRY_DIGEST_SHA1);
}
if (strcmp(key, "sha256") == 0 || if (strcmp(key, "sha256") == 0 ||
strcmp(key, "sha256digest") == 0) strcmp(key, "sha256digest") == 0) {
break; return parse_digest(a, entry, val,
ARCHIVE_ENTRY_DIGEST_SHA256);
}
if (strcmp(key, "sha384") == 0 || if (strcmp(key, "sha384") == 0 ||
strcmp(key, "sha384digest") == 0) strcmp(key, "sha384digest") == 0) {
break; return parse_digest(a, entry, val,
ARCHIVE_ENTRY_DIGEST_SHA384);
}
if (strcmp(key, "sha512") == 0 || if (strcmp(key, "sha512") == 0 ||
strcmp(key, "sha512digest") == 0) strcmp(key, "sha512digest") == 0) {
break; return parse_digest(a, entry, val,
ARCHIVE_ENTRY_DIGEST_SHA512);
}
if (strcmp(key, "size") == 0) { if (strcmp(key, "size") == 0) {
archive_entry_set_size(entry, mtree_atol(&val, 10)); archive_entry_set_size(entry, mtree_atol(&val, 10));
break; break;

View File

@ -151,6 +151,9 @@
#undef minimum #undef minimum
#define minimum(a, b) ((a)<(b)?(a):(b)) #define minimum(a, b) ((a)<(b)?(a):(b))
/* Stack overflow check */
#define MAX_COMPRESS_DEPTH 1024
/* Fields common to all headers */ /* Fields common to all headers */
struct rar_header 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 *, static int read_data_stored(struct archive_read *, const void **, size_t *,
int64_t *); int64_t *);
static int read_data_compressed(struct archive_read *, const void **, size_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 rar_br_preparation(struct archive_read *, struct rar_br *);
static int parse_codes(struct archive_read *); static int parse_codes(struct archive_read *);
static void free_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_NORMAL:
case COMPRESS_METHOD_GOOD: case COMPRESS_METHOD_GOOD:
case COMPRESS_METHOD_BEST: 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) { if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
rar->start_new_table = 1; rar->start_new_table = 1;
@ -1883,8 +1886,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
static int static int
read_data_compressed(struct archive_read *a, const void **buff, size_t *size, 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; struct rar *rar;
int64_t start, end, actualend; int64_t start, end, actualend;
size_t bs; size_t bs;
@ -1982,7 +1988,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
{ {
case 0: case 0:
rar->start_new_table = 1; rar->start_new_table = 1;
return read_data_compressed(a, buff, size, offset); return read_data_compressed(a, buff, size, offset, looper);
case 2: case 2:
rar->ppmd_eod = 1;/* End Of ppmd Data. */ rar->ppmd_eod = 1;/* End Of ppmd Data. */

View File

@ -3831,7 +3831,7 @@ static int verify_checksums(struct archive_read* a) {
DEBUG_CODE { DEBUG_CODE {
printf("Checksum error: CRC32 " printf("Checksum error: CRC32 "
"(was: %08x, expected: %08x)\n", "(was: %08" PRIx32 ", expected: %08" PRIx32 ")\n",
rar->file.calculated_crc32, rar->file.calculated_crc32,
rar->file.stored_crc32); rar->file.stored_crc32);
} }
@ -3845,7 +3845,7 @@ static int verify_checksums(struct archive_read* a) {
} else { } else {
DEBUG_CODE { DEBUG_CODE {
printf("Checksum OK: CRC32 " printf("Checksum OK: CRC32 "
"(%08x/%08x)\n", "(%08" PRIx32 "/%08" PRIx32 ")\n",
rar->file.stored_crc32, rar->file.stored_crc32,
rar->file.calculated_crc32); rar->file.calculated_crc32);
} }
@ -3906,6 +3906,9 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
int ret; int ret;
struct rar5* rar = get_context(a); struct rar5* rar = get_context(a);
if (size)
*size = 0;
if(rar->file.dir > 0) { if(rar->file.dir > 0) {
/* Don't process any data if this file entry was declared /* Don't process any data if this file entry was declared
* as a directory. This is needed, because entries marked as * as a directory. This is needed, because entries marked as

View File

@ -337,6 +337,14 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
mtime = rtime; mtime = rtime;
} }
break; 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: default:
fnam.len = 0U; fnam.len = 0U;
fnam.str = NULL; fnam.str = NULL;
@ -361,6 +369,14 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
break; break;
} }
/* FALLTHROUGH */ /* 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: default:
/* consume the content and start over */ /* consume the content and start over */
_warc_skip(a); _warc_skip(a);

View File

@ -899,6 +899,79 @@ process_extra(struct archive_read *a, struct archive_entry *entry,
return ARCHIVE_OK; 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. * 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"); "Truncated Zip file");
return ARCHIVE_FATAL; 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; sconv = zip->sconv;
if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME)) if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
sconv = zip->sconv_utf8; sconv = zip->sconv_utf8;
if (sconv == NULL) if (sconv == NULL)
sconv = zip->sconv_default; 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) { sconv) != 0) {
if (errno != ENOMEM && sconv == zip->sconv_utf8 && if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
(zip->entry->zip_flags & ZIP_UTF8_NAME)) (zip->entry->zip_flags & ZIP_UTF8_NAME))
archive_entry_copy_symlink_l(entry, p, archive_entry_copy_symlink_l(entry, p,
linkname_length, NULL); linkname_full_length, NULL);
if (errno == ENOMEM) { if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM, archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Symlink"); "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) { if(order < 2 || restore_method > 2) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid parameter set in PPMd8 stream (order=%d, " "Invalid parameter set in PPMd8 stream (order=%" PRId32 ", "
"restore=%d)", order, restore_method); "restore=%" PRId32 ")", order, restore_method);
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
} }
/* Allocate the memory needed to properly decompress the file. */ /* Allocate the memory needed to properly decompress the file. */
if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) { if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
archive_set_error(&a->archive, ENOMEM, 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); mem << 20);
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }

View File

@ -3881,6 +3881,11 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
} }
*p = NULL; *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) { if (aes->aes_set & AES_SET_MBS) {
sc = archive_string_conversion_to_charset(a, "UTF-8", 1); sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
if (sc == NULL) if (sc == NULL)
@ -3903,9 +3908,9 @@ int
archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes, archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
const char **p) const char **p)
{ {
struct archive_string_conv *sc;
int r, ret = 0; int r, ret = 0;
(void)a; /* UNUSED */
/* If we already have an MBS form, return that immediately. */ /* If we already have an MBS form, return that immediately. */
if (aes->aes_set & AES_SET_MBS) { if (aes->aes_set & AES_SET_MBS) {
*p = aes->aes_mbs.s; *p = aes->aes_mbs.s;
@ -3926,10 +3931,23 @@ archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
ret = -1; ret = -1;
} }
/* /* If there's a UTF-8 form, try converting with the native locale. */
* Only a UTF-8 form cannot avail because its conversion already if (aes->aes_set & AES_SET_UTF8) {
* failed at archive_mstring_update_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); return (ret);
} }
@ -3947,6 +3965,11 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
} }
*wp = NULL; *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. */ /* Try converting MBS to WCS using native locale. */
if (aes->aes_set & AES_SET_MBS) { if (aes->aes_set & AES_SET_MBS) {
archive_wstring_empty(&(aes->aes_wcs)); archive_wstring_empty(&(aes->aes_wcs));
@ -3962,11 +3985,12 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
} }
int 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) const char **p, size_t *length, struct archive_string_conv *sc)
{ {
int r, ret = 0; int r, ret = 0;
(void)r; /* UNUSED */
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
/* /*
* Internationalization programming on Windows must use Wide * Internationalization programming on Windows must use Wide
@ -3989,20 +4013,12 @@ archive_mstring_get_mbs_l(struct archive_mstring *aes,
} }
#endif #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 * with the native locale to be used for translating it to specified
* character-set. */ * character-set. */
if ((aes->aes_set & AES_SET_MBS) == 0 && if ((aes->aes_set & AES_SET_MBS) == 0) {
(aes->aes_set & AES_SET_WCS) != 0) { const char *pm; /* unused */
archive_string_empty(&(aes->aes_mbs)); archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
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 we already have an MBS form, use it to be translated to /* If we already have an MBS form, use it to be translated to
* specified character-set. */ * specified character-set. */

View File

@ -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_mbs(struct archive *, struct archive_mstring *, const char **);
int archive_mstring_get_utf8(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_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 *); size_t *, struct archive_string_conv *);
int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs); int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs, int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,

View File

@ -433,6 +433,11 @@ __archive_mktemp(const char *tmpdir)
if (temp_name.s[temp_name.length-1] != '/') if (temp_name.s[temp_name.length-1] != '/')
archive_strappend_char(&temp_name, '/'); 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"); archive_strcat(&temp_name, "libarchive_XXXXXX");
fd = mkstemp(temp_name.s); fd = mkstemp(temp_name.s);
if (fd < 0) if (fd < 0)

View File

@ -455,6 +455,25 @@ archive_write_client_write(struct archive_write_filter *f,
return (ARCHIVE_OK); 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 static int
archive_write_client_close(struct archive_write_filter *f) 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); (*a->client_closer)(&a->archive, a->client_data);
free(state->buffer); free(state->buffer);
free(state); 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. */ /* Clear the close handler myself not to be called again. */
f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
return (ret); return (ret);
@ -509,9 +522,9 @@ archive_write_client_close(struct archive_write_filter *f)
* Open the archive using the current settings. * Open the archive using the current settings.
*/ */
int 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_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 *a = (struct archive_write *)_a;
struct archive_write_filter *client_filter; 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_writer = writer;
a->client_opener = opener; a->client_opener = opener;
a->client_closer = closer; a->client_closer = closer;
a->client_freer = freer;
a->client_data = client_data; a->client_data = client_data;
client_filter = __archive_write_allocate_filter(_a); client_filter = __archive_write_allocate_filter(_a);
client_filter->open = archive_write_client_open; client_filter->open = archive_write_client_open;
client_filter->write = archive_write_client_write; client_filter->write = archive_write_client_write;
client_filter->close = archive_write_client_close; client_filter->close = archive_write_client_close;
client_filter->free = archive_write_client_free;
ret = __archive_write_filters_open(a); ret = __archive_write_filters_open(a);
if (ret < ARCHIVE_WARN) { if (ret < ARCHIVE_WARN) {
@ -544,6 +559,15 @@ archive_write_open(struct archive *_a, void *client_data,
return (ret); 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. * Close out the archive.
*/ */

View File

@ -382,8 +382,8 @@ archive_compressor_xz_options(struct archive_write_filter *f,
value[1] != '\0') value[1] != '\0')
return (ARCHIVE_WARN); return (ARCHIVE_WARN);
data->compression_level = value[0] - '0'; data->compression_level = value[0] - '0';
if (data->compression_level > 6) if (data->compression_level > 9)
data->compression_level = 6; data->compression_level = 9;
return (ARCHIVE_OK); return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) { } else if (strcmp(key, "threads") == 0) {
char *endptr; char *endptr;

View File

@ -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 archive_write_disk *a = (struct archive_write_disk *)_a;
struct fixup_entry *fe; struct fixup_entry *fe;
const char *linkname;
int ret, r; int ret, r;
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, 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) if (ret != ARCHIVE_OK)
return (ret); 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. * Query the umask so we get predictable mode settings.
* This gets done on every call to _write_header in case the * This gets done on every call to _write_header in case the
@ -4411,10 +4423,19 @@ set_xattrs(struct archive_write_disk *a)
int e; int e;
int namespace; int namespace;
namespace = EXTATTR_NAMESPACE_USER;
if (strncmp(name, "user.", 5) == 0) { if (strncmp(name, "user.", 5) == 0) {
/* "user." attributes go to user namespace */ /* "user." attributes go to user namespace */
name += 5; name += 5;
namespace = EXTATTR_NAMESPACE_USER; 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 { } else {
/* Other namespaces are unsupported */ /* Other namespaces are unsupported */
archive_strcat(&errlist, name); archive_strcat(&errlist, name);
@ -4425,8 +4446,29 @@ set_xattrs(struct archive_write_disk *a)
} }
if (a->fd >= 0) { 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, e = extattr_set_fd(a->fd, namespace, name,
value, size); value, size);
if (e == 0 && errno == 0) {
e = size;
}
} else { } else {
e = extattr_set_link( e = extattr_set_link(
archive_entry_pathname(entry), namespace, archive_entry_pathname(entry), namespace,

View File

@ -24,11 +24,12 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd February 2, 2012 .Dd November 12, 2020
.Dt ARCHIVE_WRITE_OPEN 3 .Dt ARCHIVE_WRITE_OPEN 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_write_open , .Nm archive_write_open ,
.Nm archive_write_open2 ,
.Nm archive_write_open_fd , .Nm archive_write_open_fd ,
.Nm archive_write_open_FILE , .Nm archive_write_open_FILE ,
.Nm archive_write_open_filename , .Nm archive_write_open_filename ,
@ -47,6 +48,15 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "archive_close_callback *" .Fa "archive_close_callback *"
.Fc .Fc
.Ft int .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" .Fn archive_write_open_fd "struct archive *" "int fd"
.Ft int .Ft int
.Fn archive_write_open_FILE "struct archive *" "FILE *file" .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 pointers to three callback functions which will be invoked by
the compression layer to write the constructed archive. the compression layer to write the constructed archive.
This does not alter the default archive padding. 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 .It Fn archive_write_open_fd
A convenience form of A convenience form of
.Fn archive_write_open .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 You can override this by manually invoking
.Fn archive_write_set_bytes_in_last_block .Fn archive_write_set_bytes_in_last_block
before calling before calling
.Fn archive_write_open . .Fn archive_write_open2 .
The The
.Fn archive_write_open_filename .Fn archive_write_open_filename
function is safe for use with tape drives or other function is safe for use with tape drives or other
block-oriented devices. block-oriented devices.
.It Fn archive_write_open_memory .It Fn archive_write_open_memory
A convenience form of A convenience form of
.Fn archive_write_open .Fn archive_write_open2
that accepts a pointer to a block of memory that will receive that accepts a pointer to a block of memory that will receive
the archive. the archive.
The final 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 callback functions that will be invoked to write data to the
resulting archive. resulting archive.
These functions are registered by calling These functions are registered by calling
.Fn archive_write_open : .Fn archive_write_open2 :
.Bl -item -offset indent .Bl -item -offset indent
.It .It
.Ft typedef int .Ft typedef int
@ -162,6 +177,8 @@ If the open fails, it should call
.Fn archive_set_error .Fn archive_set_error
to register an error code and message and return to register an error code and message and return
.Cm ARCHIVE_FATAL . .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 .Bl -item -offset indent
.It .It
.Ft typedef la_ssize_t .Ft typedef la_ssize_t
@ -192,7 +209,8 @@ to register an error code and message and return -1.
.El .El
.Pp .Pp
The close callback is invoked by archive_close when 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 The callback should return
.Cm ARCHIVE_OK .Cm ARCHIVE_OK
on success. on success.
@ -200,7 +218,14 @@ On failure, the callback should invoke
.Fn archive_set_error .Fn archive_set_error
to register an error code and message and to register an error code and message and
return 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 .Pp
Note that if the client-provided write callback function Note that if the client-provided write callback function
returns a non-zero value, that error will be propagated back to the caller returns a non-zero value, that error will be propagated back to the caller

View File

@ -54,7 +54,7 @@ struct write_fd_data {
int fd; int fd;
}; };
static int file_close(struct archive *, void *); static int file_free(struct archive *, void *);
static int file_open(struct archive *, void *); static int file_open(struct archive *, void *);
static ssize_t file_write(struct archive *, void *, const void *buff, size_t); 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) #if defined(__CYGWIN__) || defined(_WIN32)
setmode(mine->fd, O_BINARY); setmode(mine->fd, O_BINARY);
#endif #endif
return (archive_write_open(a, mine, return (archive_write_open2(a, mine,
file_open, file_write, file_close)); file_open, file_write, NULL, file_free));
} }
static int static int
@ -134,11 +134,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
} }
static int 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; struct write_fd_data *mine = (struct write_fd_data *)client_data;
(void)a; /* UNUSED */ (void)a; /* UNUSED */
if (mine == NULL)
return (ARCHIVE_OK);
free(mine); free(mine);
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }

View File

@ -51,7 +51,7 @@ struct write_FILE_data {
FILE *f; FILE *f;
}; };
static int file_close(struct archive *, void *); static int file_free(struct archive *, void *);
static int file_open(struct archive *, void *); static int file_open(struct archive *, void *);
static ssize_t file_write(struct archive *, void *, const void *buff, size_t); 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); return (ARCHIVE_FATAL);
} }
mine->f = f; mine->f = f;
return (archive_write_open(a, mine, return (archive_write_open2(a, mine, file_open, file_write,
file_open, file_write, file_close)); NULL, file_free));
} }
static int static int
@ -99,11 +99,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
} }
static int 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; struct write_FILE_data *mine = client_data;
(void)a; /* UNUSED */ (void)a; /* UNUSED */
if (mine == NULL)
return (ARCHIVE_OK);
free(mine); free(mine);
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }

View File

@ -62,6 +62,7 @@ struct write_file_data {
}; };
static int file_close(struct archive *, void *); static int file_close(struct archive *, void *);
static int file_free(struct archive *, void *);
static int file_open(struct archive *, void *); static int file_open(struct archive *, void *);
static ssize_t file_write(struct archive *, void *, const void *buff, size_t); static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
static int open_filename(struct archive *, int, const void *); 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); return (ARCHIVE_FAILED);
} }
mine->fd = -1; mine->fd = -1;
return (archive_write_open(a, mine, return (archive_write_open2(a, mine,
file_open, file_write, file_close)); file_open, file_write, file_close, file_free));
} }
static int static int
@ -244,9 +245,25 @@ file_close(struct archive *a, void *client_data)
(void)a; /* UNUSED */ (void)a; /* UNUSED */
if (mine == NULL)
return (ARCHIVE_FATAL);
if (mine->fd >= 0) if (mine->fd >= 0)
close(mine->fd); 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); archive_mstring_clean(&mine->filename);
free(mine); free(mine);
return (ARCHIVE_OK); return (ARCHIVE_OK);

View File

@ -39,7 +39,7 @@ struct write_memory_data {
unsigned char * buff; 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 int memory_write_open(struct archive *, void *);
static ssize_t memory_write(struct archive *, void *, const void *buff, size_t); 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->buff = buff;
mine->size = buffSize; mine->size = buffSize;
mine->client_size = used; mine->client_size = used;
return (archive_write_open(a, mine, return (archive_write_open2(a, mine,
memory_write_open, memory_write, memory_write_close)); memory_write_open, memory_write, NULL, memory_write_free));
} }
static int static int
@ -103,11 +103,13 @@ memory_write(struct archive *a, void *client_data, const void *buff, size_t leng
} }
static int 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; struct write_memory_data *mine;
(void)a; /* UNUSED */ (void)a; /* UNUSED */
mine = client_data; mine = client_data;
if (mine == NULL)
return (ARCHIVE_OK);
free(mine); free(mine);
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }

View File

@ -89,6 +89,7 @@ struct archive_write {
archive_open_callback *client_opener; archive_open_callback *client_opener;
archive_write_callback *client_writer; archive_write_callback *client_writer;
archive_close_callback *client_closer; archive_close_callback *client_closer;
archive_free_callback *client_freer;
void *client_data; void *client_data;
/* /*

View File

@ -1927,8 +1927,8 @@ compression_init_encoder_lzma(struct archive *a,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
lzmafilters = (lzma_filter *)(strm+1); lzmafilters = (lzma_filter *)(strm+1);
if (level > 6) if (level > 9)
level = 6; level = 9;
if (lzma_lzma_preset(&lzma_opt, level)) { if (lzma_lzma_preset(&lzma_opt, level)) {
free(strm); free(strm);
lastrm->real_stream = NULL; lastrm->real_stream = NULL;

View File

@ -250,7 +250,7 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
const char *path; const char *path;
size_t len; 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"); archive_set_error(&a->archive, -1, "Filetype required");
return (ARCHIVE_FAILED); 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); format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
if (archive_entry_filetype(entry) == AE_IFBLK if (archive_entry_filetype(entry) == AE_IFBLK
|| archive_entry_filetype(entry) == AE_IFCHR) || 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 else
format_octal(0, h + c_rdev_offset, c_rdev_size); format_octal(0, h + c_rdev_offset, c_rdev_size);
format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size); format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);

View File

@ -190,7 +190,7 @@ archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
const char *path; const char *path;
size_t len; 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"); archive_set_error(&a->archive, -1, "Filetype required");
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
} }

View File

@ -2178,7 +2178,8 @@ get_system_identitier(char *system_id, size_t size)
strncpy(system_id, "Windows", size-1); strncpy(system_id, "Windows", size-1);
system_id[size-1] = '\0'; system_id[size-1] = '\0';
#else #else
#error no way to get the system identifier on your platform. strncpy(system_id, "Unknown", size-1);
system_id[size-1] = '\0';
#endif #endif
} }

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171
#include "archive.h" #include "archive.h"
#include "archive_digest_private.h" #include "archive_digest_private.h"
#include "archive_entry.h" #include "archive_entry.h"
#include "archive_entry_private.h"
#include "archive_private.h" #include "archive_private.h"
#include "archive_rb.h" #include "archive_rb.h"
#include "archive_string.h" #include "archive_string.h"
@ -82,24 +83,7 @@ struct dir_info {
struct reg_info { struct reg_info {
int compute_sum; int compute_sum;
uint32_t crc; uint32_t crc;
#ifdef ARCHIVE_HAS_MD5 struct ae_digest digest;
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 mtree_entry { struct mtree_entry {
@ -1571,27 +1555,27 @@ sum_final(struct mtree_writer *mtree, struct reg_info *reg)
} }
#ifdef ARCHIVE_HAS_MD5 #ifdef ARCHIVE_HAS_MD5
if (mtree->compute_sum & F_MD5) if (mtree->compute_sum & F_MD5)
archive_md5_final(&mtree->md5ctx, reg->buf_md5); archive_md5_final(&mtree->md5ctx, reg->digest.md5);
#endif #endif
#ifdef ARCHIVE_HAS_RMD160 #ifdef ARCHIVE_HAS_RMD160
if (mtree->compute_sum & F_RMD160) if (mtree->compute_sum & F_RMD160)
archive_rmd160_final(&mtree->rmd160ctx, reg->buf_rmd160); archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
#endif #endif
#ifdef ARCHIVE_HAS_SHA1 #ifdef ARCHIVE_HAS_SHA1
if (mtree->compute_sum & F_SHA1) if (mtree->compute_sum & F_SHA1)
archive_sha1_final(&mtree->sha1ctx, reg->buf_sha1); archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
#endif #endif
#ifdef ARCHIVE_HAS_SHA256 #ifdef ARCHIVE_HAS_SHA256
if (mtree->compute_sum & F_SHA256) if (mtree->compute_sum & F_SHA256)
archive_sha256_final(&mtree->sha256ctx, reg->buf_sha256); archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
#endif #endif
#ifdef ARCHIVE_HAS_SHA384 #ifdef ARCHIVE_HAS_SHA384
if (mtree->compute_sum & F_SHA384) if (mtree->compute_sum & F_SHA384)
archive_sha384_final(&mtree->sha384ctx, reg->buf_sha384); archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
#endif #endif
#ifdef ARCHIVE_HAS_SHA512 #ifdef ARCHIVE_HAS_SHA512
if (mtree->compute_sum & F_SHA512) if (mtree->compute_sum & F_SHA512)
archive_sha512_final(&mtree->sha512ctx, reg->buf_sha512); archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
#endif #endif
/* Save what types of sum are computed. */ /* Save what types of sum are computed. */
reg->compute_sum = mtree->compute_sum; 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", archive_string_sprintf(str, " cksum=%ju",
(uintmax_t)reg->crc); (uintmax_t)reg->crc);
} }
#define append_digest(_s, _r, _t) \
strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
#ifdef ARCHIVE_HAS_MD5 #ifdef ARCHIVE_HAS_MD5
if (reg->compute_sum & F_MD5) { if (reg->compute_sum & F_MD5) {
archive_strcat(str, " md5digest="); archive_strcat(str, " md5digest=");
strappend_bin(str, reg->buf_md5, sizeof(reg->buf_md5)); append_digest(str, reg, md5);
} }
#endif #endif
#ifdef ARCHIVE_HAS_RMD160 #ifdef ARCHIVE_HAS_RMD160
if (reg->compute_sum & F_RMD160) { if (reg->compute_sum & F_RMD160) {
archive_strcat(str, " rmd160digest="); archive_strcat(str, " rmd160digest=");
strappend_bin(str, reg->buf_rmd160, sizeof(reg->buf_rmd160)); append_digest(str, reg, rmd160);
} }
#endif #endif
#ifdef ARCHIVE_HAS_SHA1 #ifdef ARCHIVE_HAS_SHA1
if (reg->compute_sum & F_SHA1) { if (reg->compute_sum & F_SHA1) {
archive_strcat(str, " sha1digest="); archive_strcat(str, " sha1digest=");
strappend_bin(str, reg->buf_sha1, sizeof(reg->buf_sha1)); append_digest(str, reg, sha1);
} }
#endif #endif
#ifdef ARCHIVE_HAS_SHA256 #ifdef ARCHIVE_HAS_SHA256
if (reg->compute_sum & F_SHA256) { if (reg->compute_sum & F_SHA256) {
archive_strcat(str, " sha256digest="); archive_strcat(str, " sha256digest=");
strappend_bin(str, reg->buf_sha256, sizeof(reg->buf_sha256)); append_digest(str, reg, sha256);
} }
#endif #endif
#ifdef ARCHIVE_HAS_SHA384 #ifdef ARCHIVE_HAS_SHA384
if (reg->compute_sum & F_SHA384) { if (reg->compute_sum & F_SHA384) {
archive_strcat(str, " sha384digest="); archive_strcat(str, " sha384digest=");
strappend_bin(str, reg->buf_sha384, sizeof(reg->buf_sha384)); append_digest(str, reg, sha384);
} }
#endif #endif
#ifdef ARCHIVE_HAS_SHA512 #ifdef ARCHIVE_HAS_SHA512
if (reg->compute_sum & F_SHA512) { if (reg->compute_sum & F_SHA512) {
archive_strcat(str, " sha512digest="); archive_strcat(str, " sha512digest=");
strappend_bin(str, reg->buf_sha512, sizeof(reg->buf_sha512)); append_digest(str, reg, sha512);
} }
#endif #endif
#undef append_digest
} }
static int static int

View File

@ -2931,8 +2931,8 @@ compression_init_encoder_xz(struct archive *a,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
lzmafilters = (lzma_filter *)(strm+1); lzmafilters = (lzma_filter *)(strm+1);
if (level > 6) if (level > 9)
level = 6; level = 9;
if (lzma_lzma_preset(&lzma_opt, level)) { if (lzma_lzma_preset(&lzma_opt, level)) {
free(strm); free(strm);
lastrm->real_stream = NULL; lastrm->real_stream = NULL;

View File

@ -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_flags |= ZIP_ENTRY_FLAG_ENCRYPTED;
zip->entry_encryption = zip->encryption_type; zip->entry_encryption = zip->encryption_type;
break; break;
case ENCRYPTION_NONE:
default: default:
break; break;
} }
@ -710,6 +711,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
+ AUTH_CODE_SIZE; + AUTH_CODE_SIZE;
version_needed = 20; version_needed = 20;
break; break;
case ENCRYPTION_NONE:
default: default:
break; break;
} }
@ -762,6 +764,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
if (version_needed < 20) if (version_needed < 20)
version_needed = 20; version_needed = 20;
break; break;
case ENCRYPTION_NONE:
default: default:
break; 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; zip->cctx_valid = zip->hctx_valid = 1;
} }
break; break;
case ENCRYPTION_NONE:
default: default:
break; break;
} }
@ -1117,6 +1121,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
break; break;
#endif #endif
case COMPRESSION_UNSPECIFIED:
default: default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Invalid ZIP compression type"); "Invalid ZIP compression type");

View File

@ -24,6 +24,7 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
#include <osreldate.h> #include <osreldate.h>

View File

@ -44,14 +44,9 @@ test_empty_file1(void)
} }
static void static void
test_empty_file2(void) test_empty_file2_check(struct archive* a)
{ {
struct archive* a = archive_read_new();
struct archive_entry* e; 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)); assertEqualInt(0, archive_errno(a));
assertEqualString(NULL, archive_error_string(a)); assertEqualString(NULL, archive_error_string(a));
@ -66,6 +61,25 @@ test_empty_file2(void)
archive_read_free(a); 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 static void
test_empty_tarfile(void) test_empty_tarfile(void)
{ {

View File

@ -35,6 +35,17 @@ typedef struct archive *constructor(void);
typedef int enabler(struct archive *); typedef int enabler(struct archive *);
typedef int destructor(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 static void
test_success(constructor new_, enabler enable_, destructor free_) 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_xar);
test_filter_or_format(archive_read_support_format_zip); 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_all);
test_filter_or_format(archive_read_support_filter_bzip2); test_filter_or_format(archive_read_support_filter_bzip2);
test_filter_or_format(archive_read_support_filter_compress); test_filter_or_format(archive_read_support_filter_compress);

View File

@ -445,7 +445,7 @@ test_archive_string_normalization_nfc(const char *testdata)
assertEqualInt(0, assertEqualInt(0,
archive_mstring_copy_wcs(&mstr, wc_nfc)); archive_mstring_copy_wcs(&mstr, wc_nfc));
assertEqualInt(0, archive_mstring_get_mbs_l( 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" failure("WCS NFC(%s) should be UTF-8 NFC:%d"
,nfc, line); ,nfc, line);
assertEqualUTF8String(utf8_nfc, mp); assertEqualUTF8String(utf8_nfc, mp);
@ -695,7 +695,7 @@ test_archive_string_normalization_mac_nfd(const char *testdata)
assertEqualInt(0, archive_mstring_copy_wcs( assertEqualInt(0, archive_mstring_copy_wcs(
&mstr, wc_nfd)); &mstr, wc_nfd));
assertEqualInt(0, archive_mstring_get_mbs_l( 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" failure("WCS NFD(%s) should be UTF-8 NFD:%d"
,nfd, line); ,nfd, line);
assertEqualUTF8String(utf8_nfd, mp); 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) DEFINE_TEST(test_archive_string_conversion)
{ {
static const char reffile[] = "test_archive_string_conversion.txt.Z"; 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_nfc(testdata);
test_archive_string_normalization_mac_nfd(testdata); test_archive_string_normalization_mac_nfd(testdata);
test_archive_string_canonicalization(); test_archive_string_canonicalization();
test_archive_string_set_get();
} }

View File

@ -177,31 +177,60 @@ DEFINE_TEST(test_entry)
/* gname */ /* gname */
archive_entry_set_gname(e, "group"); archive_entry_set_gname(e, "group");
assertEqualString(archive_entry_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"); wcscpy(wbuff, L"wgroup");
archive_entry_copy_gname_w(e, wbuff); archive_entry_copy_gname_w(e, wbuff);
assertEqualWString(archive_entry_gname_w(e), L"wgroup"); assertEqualWString(archive_entry_gname_w(e), L"wgroup");
memset(wbuff, 0, sizeof(wbuff)); memset(wbuff, 0, sizeof(wbuff));
assertEqualWString(archive_entry_gname_w(e), L"wgroup"); 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 */ /* hardlink */
archive_entry_set_hardlink(e, "hardlinkname"); archive_entry_set_hardlink(e, "hardlinkname");
assertEqualString(archive_entry_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"); strcpy(buff, "hardlinkname2");
archive_entry_copy_hardlink(e, buff); archive_entry_copy_hardlink(e, buff);
assertEqualString(archive_entry_hardlink(e), "hardlinkname2"); 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)); memset(buff, 0, sizeof(buff));
assertEqualString(archive_entry_hardlink(e), "hardlinkname2"); 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); archive_entry_copy_hardlink(e, NULL);
assertEqualString(archive_entry_hardlink(e), NULL); assertEqualString(archive_entry_hardlink(e), NULL);
assertEqualWString(archive_entry_hardlink_w(e), NULL); assertEqualWString(archive_entry_hardlink_w(e), NULL);
assertEqualString(archive_entry_hardlink_utf8(e), NULL);
wcscpy(wbuff, L"whardlink"); wcscpy(wbuff, L"whardlink");
archive_entry_copy_hardlink_w(e, wbuff); archive_entry_copy_hardlink_w(e, wbuff);
assertEqualWString(archive_entry_hardlink_w(e), L"whardlink"); 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)); memset(wbuff, 0, sizeof(wbuff));
assertEqualWString(archive_entry_hardlink_w(e), L"whardlink"); assertEqualWString(archive_entry_hardlink_w(e), L"whardlink");
archive_entry_copy_hardlink_w(e, NULL); archive_entry_copy_hardlink_w(e, NULL);
assertEqualString(archive_entry_hardlink(e), NULL); assertEqualString(archive_entry_hardlink(e), NULL);
assertEqualWString(archive_entry_hardlink_w(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 */ /* ino */
assert(!archive_entry_ino_is_set(e)); assert(!archive_entry_ino_is_set(e));
@ -270,18 +299,38 @@ DEFINE_TEST(test_entry)
/* pathname */ /* pathname */
archive_entry_set_pathname(e, "path"); archive_entry_set_pathname(e, "path");
assertEqualString(archive_entry_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"); archive_entry_set_pathname(e, "path");
assertEqualString(archive_entry_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"); strcpy(buff, "path2");
archive_entry_copy_pathname(e, buff); archive_entry_copy_pathname(e, buff);
assertEqualString(archive_entry_pathname(e), "path2"); 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)); memset(buff, 0, sizeof(buff));
assertEqualString(archive_entry_pathname(e), "path2"); 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"); wcscpy(wbuff, L"wpath");
archive_entry_copy_pathname_w(e, wbuff); archive_entry_copy_pathname_w(e, wbuff);
assertEqualWString(archive_entry_pathname_w(e), L"wpath"); 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)); memset(wbuff, 0, sizeof(wbuff));
assertEqualWString(archive_entry_pathname_w(e), L"wpath"); 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 */ /* rdev */
archive_entry_set_rdev(e, 532); archive_entry_set_rdev(e, 532);
@ -302,19 +351,37 @@ DEFINE_TEST(test_entry)
/* symlink */ /* symlink */
archive_entry_set_symlink(e, "symlinkname"); archive_entry_set_symlink(e, "symlinkname");
assertEqualString(archive_entry_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"); strcpy(buff, "symlinkname2");
archive_entry_copy_symlink(e, buff); archive_entry_copy_symlink(e, buff);
assertEqualString(archive_entry_symlink(e), "symlinkname2"); 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)); memset(buff, 0, sizeof(buff));
assertEqualString(archive_entry_symlink(e), "symlinkname2"); 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); archive_entry_copy_symlink_w(e, NULL);
assertEqualWString(archive_entry_symlink_w(e), NULL); assertEqualWString(archive_entry_symlink_w(e), NULL);
assertEqualString(archive_entry_symlink(e), NULL); assertEqualString(archive_entry_symlink(e), NULL);
assertEqualString(archive_entry_symlink_utf8(e), NULL);
archive_entry_copy_symlink_w(e, L"wsymlink"); archive_entry_copy_symlink_w(e, L"wsymlink");
assertEqualWString(archive_entry_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); archive_entry_copy_symlink(e, NULL);
assertEqualWString(archive_entry_symlink_w(e), NULL); assertEqualWString(archive_entry_symlink_w(e), NULL);
assertEqualString(archive_entry_symlink(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 */ /* uid */
archive_entry_set_uid(e, 83); archive_entry_set_uid(e, 83);
@ -323,11 +390,27 @@ DEFINE_TEST(test_entry)
/* uname */ /* uname */
archive_entry_set_uname(e, "user"); archive_entry_set_uname(e, "user");
assertEqualString(archive_entry_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"); wcscpy(wbuff, L"wuser");
archive_entry_copy_gname_w(e, wbuff); archive_entry_copy_uname_w(e, wbuff);
assertEqualWString(archive_entry_gname_w(e), L"wuser"); assertEqualWString(archive_entry_uname_w(e), L"wuser");
memset(wbuff, 0, sizeof(wbuff)); 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. */ /* Test fflags interface. */
archive_entry_set_fflags(e, 0x55, 0xAA); archive_entry_set_fflags(e, 0x55, 0xAA);

View File

@ -1833,6 +1833,8 @@ test_parent(void)
} }
assertChdir(".."); assertChdir("..");
assertChmod("lock", 0755);
assertChmod("lock/lock2", 0755);
/* Destroy the disk object. */ /* Destroy the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_free(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a));

View File

@ -196,8 +196,80 @@ test_read_format_mtree1(void)
assertEqualInt(archive_entry_is_encrypted(ae), 0); assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); 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)); 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_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a));
} }

View File

@ -15,6 +15,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 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 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 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 end

View File

@ -72,7 +72,7 @@ DEFINE_TEST(test_read_format_raw)
extract_reference_file(reffile2); extract_reference_file(reffile2);
assert((a = archive_read_new()) != NULL); assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 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_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, reffile2, 1)); archive_read_open_filename(a, reffile2, 1));
@ -100,8 +100,7 @@ DEFINE_TEST(test_read_format_raw)
extract_reference_file(reffile3); extract_reference_file(reffile3);
assert((a = archive_read_new()) != NULL); assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 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_set_format(a, ARCHIVE_FORMAT_RAW));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, reffile3, 1)); archive_read_open_filename(a, reffile3, 1));

View File

@ -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_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(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));
}

View File

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

View File

@ -201,11 +201,6 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
{ {
struct archive_entry *ae; struct archive_entry *ae;
struct archive *a; struct archive *a;
#if !defined(_WIN32) || defined(__CYGWIN__)
FILE * fp;
int fd;
fpos_t pos;
#endif
/* /*
* If we have "bunzip2 -q", try using that. * If we have "bunzip2 -q", try using that.
@ -215,14 +210,6 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
return; 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); assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
assertEqualIntA(a, ARCHIVE_OK, 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)); assertA(archive_read_next_header(a, &ae) < (ARCHIVE_WARN));
assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a)); assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(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
} }

View File

@ -40,6 +40,10 @@ DEFINE_TEST(test_write_disk_secure)
struct archive *a; struct archive *a;
struct archive_entry *ae; struct archive_entry *ae;
struct stat st; 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. */ /* Start with a known umask. */
assertUmask(UMASK); assertUmask(UMASK);
@ -251,10 +255,32 @@ DEFINE_TEST(test_write_disk_secure)
assert(0 == lstat("link_to_dir", &st)); assert(0 == lstat("link_to_dir", &st));
failure("link_to_dir: st.st_mode=%o", st.st_mode); failure("link_to_dir: st.st_mode=%o", st.st_mode);
assert(S_ISLNK(st.st_mode)); assert(S_ISLNK(st.st_mode));
#if HAVE_LCHMOD #if defined(HAVE_SYMLINK) && defined(HAVE_LCHMOD) && \
/* Systems that lack lchmod() can't set symlink perms, so skip this. */ defined(S_IRUSR) && defined(S_IWUSR) && defined(S_IXUSR)
failure("link_to_dir: st.st_mode=%o", st.st_mode); /* Verify if we are able to lchmod() */
assert((st.st_mode & 07777) == 0755); 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 #endif
assert(0 == lstat("dir/filea", &st)); assert(0 == lstat("dir/filea", &st));

View File

@ -141,6 +141,17 @@ test_format(int (*set_format)(struct archive *))
archive_entry_free(ae); archive_entry_free(ae);
assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); 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. */ /* Close out the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 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)); assertEqualInt(0, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); 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. */ /* Verify the end of the archive. */
assertEqualIntA(a, 1, archive_read_next_header(a, &ae)); assertEqualIntA(a, 1, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));

View File

@ -26,6 +26,19 @@
#include "test.h" #include "test.h"
__FBSDID("$FreeBSD$"); __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) DEFINE_TEST(test_write_format_warc)
{ {
char filedata[64]; char filedata[64];
@ -62,14 +75,15 @@ DEFINE_TEST(test_write_format_warc)
*/ */
assert((a = archive_read_new()) != NULL); assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_warc(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_warc(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a)); test_read(a, buff, used, filedata);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, 9, archive_read_data(a, filedata, 10)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_by_code(a, ARCHIVE_FORMAT_WARC));
assertEqualMem(filedata, "12345678", 9); test_read(a, buff, used, filedata);
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_set_format(a, ARCHIVE_FORMAT_WARC));
test_read(a, buff, used, filedata);
/* Create a new archive */ /* Create a new archive */
assert((a = archive_write_new()) != NULL); assert((a = archive_write_new()) != NULL);

View File

@ -169,6 +169,9 @@
/* chdir() and error if it fails */ /* chdir() and error if it fails */
#define assertChdir(path) \ #define assertChdir(path) \
assertion_chdir(__FILE__, __LINE__, 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 */ /* Assert two files have the same file flags */
#define assertEqualFflags(patha, pathb) \ #define assertEqualFflags(patha, pathb) \
assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0) assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0)
@ -282,6 +285,7 @@
void failure(const char *fmt, ...) __LA_PRINTFLIKE(1, 2); void failure(const char *fmt, ...) __LA_PRINTFLIKE(1, 2);
int assertion_assert(const char *, int, int, const char *, void *); int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *); 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 assertion_compare_fflags(const char *, int, const char *, const char *,
int); int);
int assertion_empty_file(const char *, int, const char *); int assertion_empty_file(const char *, int, const char *);

View File

@ -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. */ /* Verify two integers are equal. */
int int
assertion_equal_int(const char *file, int line, assertion_equal_int(const char *file, int line,