Update vendor/libarchive to 3.7.5

Security fixes:
 #2158 rpm: calculate huge header sizes correctly
 #2160 util: fix out of boundary access in mktemp functions
 #2168 uu: stop processing if lines are too long
 #2174 lzop: prevent integer overflow
 #2172 rar4: protect copy_from_lzss_window_to_unp() (CVE-2024-20696)
 #2175 unzip: unify EOF handling
 #2179 rar4: fix out of boundary access with large files
 #2203 rar4: fix OOB access with unicode filenames
 #2210 rar4: add boundary checks to rgb filter
 #2248 rar4: fix OOB in delta filter
 #2249 rar4: fix OOB in audio filter
 #2256 fix multiple vulnerabilities identified by SAST
 #2258 cpio: ignore out-of-range gid/uid/size/ino and harden AFIO parsing
 #2265 rar5: clear 'data ready' cache on window buffer reallocs
 #2269 rar4: fix CVE-2024-26256 (CVE-2024-26256)

Important bugfixes:
 #2150 xar: fix another infinite loop and expat error handling
 #2173 shar: check strdup return value
 #2161 lha: fix integer truncation on 32-bit systems
 #2245 7zip: fix issue when skipping first file in 7zip archive that
       is a multiple of 65536 bytes
 #2259 rar5: don't try to read rediculously long names
 #2290 ar: fix archive entries having no type

Obtained from:	libarchive
Vendor commit: 	12ecf8418ab3595d66cdea1abadcea8b6a9d288b
CVE:		CVE-2024-20696, CVE-2024-26256
This commit is contained in:
Martin Matuska 2024-09-14 11:40:31 +02:00
parent ed3e988642
commit 2022efa030
117 changed files with 4232 additions and 1296 deletions

View file

@ -12,7 +12,7 @@ FreeBSD_task:
freebsd_instance:
image_family: freebsd-14-0
freebsd_instance:
image_family: freebsd-13-2
image_family: freebsd-13-3
prepare_script:
- ./build/ci/cirrus_ci/ci.sh prepare
configure_script:

View file

@ -12,7 +12,7 @@ jobs:
matrix:
bs: [autotools, cmake]
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Install dependencies
run: ./build/ci/github_actions/macos.sh prepare
- name: Autogen
@ -57,7 +57,7 @@ jobs:
bs: [autotools, cmake]
crypto: [mbedtls, nettle, openssl]
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Update apt cache
run: sudo apt-get update
- name: Install dependencies
@ -98,7 +98,7 @@ jobs:
Ubuntu-distcheck:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Update package definitions
run: sudo apt-get update
- name: Install dependencies
@ -125,7 +125,7 @@ jobs:
matrix:
be: [mingw-gcc, msvc]
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Install mingw
if: ${{ matrix.be=='mingw-gcc' }}
run: choco install mingw

View file

@ -26,18 +26,18 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Initialize CodeQL
uses: github/codeql-action/init@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
uses: github/codeql-action/init@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
uses: github/codeql-action/autobuild@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
with:
category: "/language:${{ matrix.language }}"

View file

@ -29,12 +29,12 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with:
results_file: results.sarif
results_format: sarif
@ -60,6 +60,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
uses: github/codeql-action/upload-sarif@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
with:
sarif_file: results.sarif

2
.gitignore vendored
View file

@ -63,8 +63,10 @@ CMakeCache.txt
CMakeFiles/
DartConfiguration.tcl
cmake.tmp/
cmake-*/
.vs/
.vscode/
.idea/
doc/html/*.html
doc/man/*.1

View file

@ -1,5 +1,9 @@
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
if(APPLE AND CMAKE_VERSION VERSION_LESS "3.17.0")
message(WARNING "CMake>=3.17.0 required to make the generated shared library have the same Mach-O headers as autotools")
endif()
if(POLICY CMP0065)
cmake_policy(SET CMP0065 NEW) #3.4 don't use `-rdynamic` with executables
endif()
@ -83,9 +87,21 @@ SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
# libarchive 3.1 == interface version 13
math(EXPR INTERFACE_VERSION "13 + ${_minor}")
# Set SOVERSION == Interface version
# ?? Should there be more here ??
SET(SOVERSION "${INTERFACE_VERSION}")
# Set SOVERSION so it matches libtool's conventions
# libtool accepts a string "current:revision:age"; in libarchive, that's set to
# - current: ${INTERFACE_VERSION} = 13 + ${_minor}
# - revision: ${_revision}
# - age: ${_minor}
# Since libtool computes SOVERSION as "current - age", it's just '13' again
math(EXPR SOVERSION "${INTERFACE_VERSION} - ${_minor}")
set(SOVERSION_FULL "${SOVERSION}.${_trimmed_minor}.${_trimmed_revision}")
# Override CMake's default shared library versioning scheme, which uses SOVERSION and VERSION,
# to match libtool's conventions (see https://github.com/mesonbuild/meson/issues/1451)
# - compatibility version: current + 1 = ${INTERFACE_VERSION} + 1
# - current version: ${current + 1}.${revision}
math(EXPR MACHO_COMPATIBILITY_VERSION "${INTERFACE_VERSION} + 1")
set(MACHO_CURRENT_VERSION "${MACHO_COMPATIBILITY_VERSION}.${_revision}")
# Enable CMAKE_PUSH_CHECK_STATE() and CMAKE_POP_CHECK_STATE() macros
# saving and restoring the state of the variables.
@ -107,7 +123,7 @@ endif ()
# aggressive about diagnosing build problems; this can get
# relaxed somewhat in final shipping versions.
IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
CMAKE_C_COMPILER_ID MATCHES "^Clang$")
CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
#################################################################
# Set compile flags for all build types.
@ -144,7 +160,7 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
ENDIF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
CMAKE_C_COMPILER_ID MATCHES "^Clang$")
CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
SET(CMAKE_C_COMPILER "xlc_r")
SET(CMAKE_REQUIRED_FLAGS "-qflag=e:e -qformat=sec")
@ -443,7 +459,10 @@ SET(ADDITIONAL_LIBS "")
# Find ZLIB
#
IF(ENABLE_ZLIB)
FIND_PACKAGE(ZLIB)
# Require zlib >= 1.2.1, see: https://github.com/libarchive/libarchive/issues/615
# zlib 1.2.0 should also work, but it is difficult to test for. Let's require
# zlib >= 1.2.1 for consistency with the autoconf build.
FIND_PACKAGE(ZLIB 1.2.1)
ELSE()
SET(ZLIB_FOUND FALSE) # Override cached value
ENDIF()
@ -743,7 +762,6 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H)
LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
@ -2174,6 +2192,11 @@ IF(APPLE)
ADD_DEFINITIONS(-Wno-deprecated-declarations)
ENDIF(APPLE)
OPTION(DONT_FAIL_ON_CRC_ERROR "Ignore CRC errors during parsing (For fuzzing)" OFF)
IF(DONT_FAIL_ON_CRC_ERROR)
ADD_DEFINITIONS(-DDONT_FAIL_ON_CRC_ERROR=1)
ENDIF(DONT_FAIL_ON_CRC_ERROR)
IF(ENABLE_TEST)
ADD_CUSTOM_TARGET(run_all_tests)
ENDIF(ENABLE_TEST)

View file

@ -371,6 +371,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_acl_platform_posix1e.c \
libarchive/test/test_acl_posix1e.c \
libarchive/test/test_acl_text.c \
libarchive/test/test_ar_mode.c \
libarchive/test/test_archive_api_feature.c \
libarchive/test/test_archive_clear_error.c \
libarchive/test/test_archive_cmdline.c \
@ -380,6 +381,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_archive_match_path.c \
libarchive/test/test_archive_match_time.c \
libarchive/test/test_archive_pathmatch.c \
libarchive/test/test_archive_read.c \
libarchive/test/test_archive_read_add_passphrase.c \
libarchive/test/test_archive_read_close_twice.c \
libarchive/test/test_archive_read_close_twice_open_fd.c \
@ -486,6 +488,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_gtar_lzma.c \
libarchive/test/test_read_format_gtar_sparse.c \
libarchive/test/test_read_format_gtar_sparse_skip_entry.c \
libarchive/test/test_read_format_huge_rpm.c \
libarchive/test/test_read_format_iso_Z.c \
libarchive/test/test_read_format_iso_multi_extent.c \
libarchive/test/test_read_format_iso_xorriso.c \
@ -520,6 +523,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_tar_empty_with_gnulabel.c \
libarchive/test/test_read_format_tar_filename.c \
libarchive/test/test_read_format_tar_invalid_pax_size.c \
libarchive/test/test_read_format_tar_pax_large_attr.c \
libarchive/test/test_read_format_tbz.c \
libarchive/test/test_read_format_tgz.c \
libarchive/test/test_read_format_tlz.c \
@ -643,6 +647,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_write_format_zip_file_zip64.c \
libarchive/test/test_write_format_zip_large.c \
libarchive/test/test_write_format_zip_stream.c \
libarchive/test/test_write_format_zip_windows_path.c \
libarchive/test/test_write_format_zip_zip64.c \
libarchive/test/test_write_open_memory.c \
libarchive/test/test_write_read_format_zip.c \
@ -786,6 +791,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_7zip_encryption.7z.uu \
libarchive/test/test_read_format_7zip_encryption_header.7z.uu \
libarchive/test/test_read_format_7zip_encryption_partially.7z.uu \
libarchive/test/test_read_format_7zip_extract_second.7z.uu \
libarchive/test/test_read_format_7zip_lzma1.7z.uu \
libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \
libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \
@ -827,8 +833,10 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tar.uu \
libarchive/test/test_read_format_gtar_sparse_1_17_posix10_modified.tar.uu \
libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu \
libarchive/test/test_read_format_huge_rpm.rpm.uu \
libarchive/test/test_read_format_iso.iso.Z.uu \
libarchive/test/test_read_format_iso_2.iso.Z.uu \
libarchive/test/test_read_format_iso_3.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu \
@ -919,6 +927,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \
libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \
libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \
libarchive/test/test_read_format_rar5_data_ready_pointer_leak.rar.uu \
libarchive/test/test_read_format_raw.bufr.uu \
libarchive/test/test_read_format_raw.data.gz.uu \
libarchive/test/test_read_format_raw.data.Z.uu \
@ -929,11 +938,13 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_tar_empty_pax.tar.Z.uu \
libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu \
libarchive/test/test_read_format_tar_pax_large_attr.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_warc.warc.uu \
libarchive/test/test_read_format_xar_doublelink.xar.uu \
libarchive/test/test_read_format_xar_duplicate_filename_node.xar.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_7z_deflate.zip.uu \

2
NEWS
View file

@ -1,3 +1,5 @@
Sep 13, 2024: libarchive 3.7.5 released
Apr 26, 2024: libarchive 3.7.4 released
Apr 08, 2024: libarchive 3.7.3 released

View file

@ -1,15 +1,13 @@
#!/bin/sh
if [ "$1" = "prepare" ]
then
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 upgrade > /dev/null
set -x -e
for pkg in \
#Uncommenting these adds a full minute to the CI time
#brew update > /dev/null
#brew upgrade > /dev/null
# This does an upgrade if the package is already installed
brew install \
autoconf \
automake \
libtool \
@ -20,7 +18,4 @@ then
zstd \
libxml2 \
openssl
do
brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg
done
fi

View file

@ -1132,9 +1132,6 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <sys/poll.h> header file. */
#cmakedefine HAVE_SYS_POLL_H 1
/* Define to 1 if you have the <sys/queue.h> header file. */
#cmakedefine HAVE_SYS_QUEUE_H 1
/* Define to 1 if you have the <sys/richacl.h> header file. */
#cmakedefine HAVE_SYS_RICHACL_H 1

View file

@ -1 +1 @@
3007004
3007005

View file

@ -39,7 +39,7 @@ expands files to standard output.
.Nm
typically takes a filename as an argument or reads standard input when used in a
pipe.
In both cases decompressed data it written to standard output.
In both cases decompressed data is written to standard output.
.Sh EXAMPLES
To decompress a file:
.Pp

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 These first two version numbers are updated automatically on each release.
m4_define([LIBARCHIVE_VERSION_S],[3.7.4])
m4_define([LIBARCHIVE_VERSION_N],[3007004])
m4_define([LIBARCHIVE_VERSION_S],[3.7.5])
m4_define([LIBARCHIVE_VERSION_N],[3007005])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
@ -113,8 +113,8 @@ AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CPP
AC_USE_SYSTEM_EXTENSIONS
AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
LT_INIT([win32-dll])
AC_CHECK_TOOL([STRIP],[strip])
AC_PROG_MKDIR_P
@ -362,7 +362,7 @@ AC_CHECK_HEADERS([locale.h membership.h paths.h poll.h pthread.h pwd.h])
AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h])
AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/ea.h sys/extattr.h])
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h sys/queue.h])
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/richacl.h])
AC_CHECK_HEADERS([sys/select.h sys/statfs.h sys/statvfs.h sys/sysmacros.h])
AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h sys/xattr.h])
@ -380,8 +380,23 @@ AC_ARG_WITH([zlib],
AS_HELP_STRING([--without-zlib], [Don't build support for gzip through zlib]))
if test "x$with_zlib" != "xno"; then
AC_CHECK_HEADERS([zlib.h])
AC_CHECK_LIB(z,inflate)
old_LIBS="$LIBS"
LIBS="$LIBS -lz"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <zlib.h>
#if !defined(ZLIB_VERNUM)
// zlib 1.2.0 should work too, but it's difficult to test for.
// zlib 1.2.1 onwards have ZLIB_VERNUM, which is easy to check.
#error zlib >= 1.2.1 is required.
#endif
// Check that there's an inflate function.
int main(int argc, char **argv) { inflate(NULL, 0); return 0; }
]])],
[AC_DEFINE([HAVE_ZLIB_H], [1], [Define to 1 if you have zlib >= 1.2.1])
AC_MSG_RESULT([found a suitable version of zlib (>= 1.2.1)])
],
[AC_MSG_RESULT([could not find a suitable version of zlib (>= 1.2.1)])
LIBS="$old_LIBS"])
fi
AC_ARG_WITH([bz2lib],
@ -777,7 +792,6 @@ AX_COMPILE_CHECK_SIZEOF(long)
AC_CHECK_HEADERS_ONCE([sys/time.h])
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_HEADER_MAJOR
AC_FUNC_FSEEKO
AC_FUNC_MEMCMP

View file

@ -308,17 +308,22 @@ again:
* Returns NULL if no error, otherwise returns error string for display.
*
*/
const char *
owner_parse(const char *spec, int *uid, int *gid)
int
owner_parse(const char *spec, struct cpio_owner *owner, const char **errmsg)
{
static char errbuff[128];
const char *u, *ue, *g;
*uid = -1;
*gid = -1;
owner->uid = -1;
owner->gid = -1;
if (spec[0] == '\0')
return ("Invalid empty user/group spec");
owner->uname = NULL;
owner->gname = NULL;
if (spec[0] == '\0') {
*errmsg = "Invalid empty user/group spec";
return (-1);
}
/*
* Split spec into [user][:.][group]
@ -347,23 +352,29 @@ owner_parse(const char *spec, int *uid, int *gid)
user = (char *)malloc(ue - u + 1);
if (user == NULL)
return ("Couldn't allocate memory");
goto alloc_error;
memcpy(user, u, ue - u);
user[ue - u] = '\0';
if ((pwent = getpwnam(user)) != NULL) {
*uid = pwent->pw_uid;
owner->uid = pwent->pw_uid;
owner->uname = strdup(pwent->pw_name);
if (owner->uname == NULL) {
free(user);
goto alloc_error;
}
if (*ue != '\0')
*gid = pwent->pw_gid;
owner->gid = pwent->pw_gid;
} else {
char *end;
errno = 0;
*uid = (int)strtoul(user, &end, 10);
owner->uid = (int)strtoul(user, &end, 10);
if (errno || *end != '\0') {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup user ``%s''", user);
errbuff[sizeof(errbuff) - 1] = '\0';
free(user);
return (errbuff);
*errmsg = errbuff;
return (-1);
}
}
free(user);
@ -372,18 +383,28 @@ owner_parse(const char *spec, int *uid, int *gid)
if (*g != '\0') {
struct group *grp;
if ((grp = getgrnam(g)) != NULL) {
*gid = grp->gr_gid;
owner->gid = grp->gr_gid;
owner->gname = strdup(grp->gr_name);
if (owner->gname == NULL) {
free(owner->uname);
owner->uname = NULL;
goto alloc_error;
}
} else {
char *end;
errno = 0;
*gid = (int)strtoul(g, &end, 10);
owner->gid = (int)strtoul(g, &end, 10);
if (errno || *end != '\0') {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup group ``%s''", g);
errbuff[sizeof(errbuff) - 1] = '\0';
return (errbuff);
*errmsg = errbuff;
return (-1);
}
}
}
return (NULL);
return (0);
alloc_error:
*errmsg = "Couldn't allocate memory";
return (-1);
}

View file

@ -132,9 +132,9 @@ main(int argc, char *argv[])
static char buff[16384];
struct cpio _cpio; /* Allocated on stack. */
struct cpio *cpio;
struct cpio_owner owner;
const char *errmsg;
char *tptr;
int uid, gid;
int opt, t;
cpio = &_cpio;
@ -142,6 +142,7 @@ main(int argc, char *argv[])
cpio->buff = buff;
cpio->buff_size = sizeof(buff);
#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
{ /* Ignore SIGPIPE signals. */
struct sigaction sa;
@ -161,7 +162,9 @@ main(int argc, char *argv[])
#endif
cpio->uid_override = -1;
cpio->uname_override = NULL;
cpio->gid_override = -1;
cpio->gname_override = NULL;
cpio->argv = argv;
cpio->argc = argc;
cpio->mode = '\0';
@ -320,21 +323,21 @@ main(int argc, char *argv[])
cpio->quiet = 1;
break;
case 'R': /* GNU cpio, also --owner */
/* TODO: owner_parse should return uname/gname
* also; use that to set [ug]name_override. */
errmsg = owner_parse(cpio->argument, &uid, &gid);
if (errmsg) {
errmsg = NULL;
if (owner_parse(cpio->argument, &owner, &errmsg) != 0) {
if (!errmsg)
errmsg = "Error parsing owner";
lafe_warnc(-1, "%s", errmsg);
usage();
}
if (uid != -1) {
cpio->uid_override = uid;
cpio->uname_override = NULL;
}
if (gid != -1) {
cpio->gid_override = gid;
cpio->gname_override = NULL;
}
if (owner.uid != -1)
cpio->uid_override = owner.uid;
if (owner.uname != NULL)
cpio->uname_override = owner.uname;
if (owner.gid != -1)
cpio->gid_override = owner.gid;
if (owner.gname != NULL)
cpio->gname_override = owner.gname;
break;
case 'r': /* POSIX 1997 */
cpio->option_rename = 1;
@ -439,11 +442,14 @@ main(int argc, char *argv[])
}
archive_match_free(cpio->matching);
free_cache(cpio->gname_cache);
free_cache(cpio->uname_cache);
free(cpio->uname_override);
free_cache(cpio->gname_cache);
free(cpio->gname_override);
archive_read_close(cpio->archive_read_disk);
archive_read_free(cpio->archive_read_disk);
free(cpio->destdir);
passphrase_free(cpio->ppbuff);
return (cpio->return_value);
}
@ -728,14 +734,14 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
return (r);
}
if (cpio->uid_override >= 0) {
if (cpio->uid_override >= 0)
archive_entry_set_uid(entry, cpio->uid_override);
if (cpio->gname_override != NULL)
archive_entry_set_uname(entry, cpio->uname_override);
}
if (cpio->gid_override >= 0) {
if (cpio->gid_override >= 0)
archive_entry_set_gid(entry, cpio->gid_override);
if (cpio->gname_override != NULL)
archive_entry_set_gname(entry, cpio->gname_override);
}
/*
* Generate a destination path for this entry.
@ -1015,8 +1021,12 @@ mode_in(struct cpio *cpio)
fprintf(stderr, ".");
if (cpio->uid_override >= 0)
archive_entry_set_uid(entry, cpio->uid_override);
if (cpio->uname_override != NULL)
archive_entry_set_uname(entry, cpio->uname_override);
if (cpio->gid_override >= 0)
archive_entry_set_gid(entry, cpio->gid_override);
if (cpio->gname_override != NULL)
archive_entry_set_gname(entry, cpio->gname_override);
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK) {
fprintf(stderr, "%s: %s\n",

View file

@ -94,8 +94,14 @@ struct cpio {
char *ppbuff;
};
const char *owner_parse(const char *, int *, int *);
struct cpio_owner {
int uid;
int gid;
char *uname;
char *gname;
};
int owner_parse(const char *, struct cpio_owner *, const char **);
/* Fake short equivalents for long options that otherwise lack them. */
enum {

View file

@ -119,9 +119,9 @@ DEFINE_TEST(test_option_c)
assert(is_octal(e, 76)); /* Entire header is octal digits. */
assertEqualMem(e + 0, "070707", 6); /* Magic */
assert(is_octal(e + 6, 6)); /* dev */
dev = from_octal(e + 6, 6);
dev = (int)from_octal(e + 6, 6);
assert(is_octal(e + 12, 6)); /* ino */
ino = from_octal(e + 12, 6);
ino = (int)from_octal(e + 12, 6);
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Group members bits and others bits do not work. */
assertEqualMem(e + 18, "100666", 6); /* Mode */
@ -129,10 +129,10 @@ DEFINE_TEST(test_option_c)
assertEqualMem(e + 18, "100644", 6); /* Mode */
#endif
if (uid < 0)
uid = from_octal(e + 24, 6);
uid = (int)from_octal(e + 24, 6);
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
assert(is_octal(e + 30, 6)); /* gid */
gid = from_octal(e + 30, 6);
gid = (int)from_octal(e + 30, 6);
assertEqualMem(e + 36, "000001", 6); /* nlink */
failure("file entries should not have rdev set (dev field was 0%o)",
dev);

View file

@ -33,7 +33,7 @@ DEFINE_TEST(test_option_t)
char *p;
int r;
time_t mtime;
char date[32];
char date[48];
char date2[32];
struct tm *tmptr;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
@ -89,6 +89,7 @@ DEFINE_TEST(test_option_t)
mtime = 1;
#ifdef HAVE_LOCALE_H
setlocale(LC_ALL, "");
setlocale(LC_TIME, "");
#endif
#if defined(HAVE_LOCALTIME_S)
tmptr = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
@ -99,10 +100,10 @@ DEFINE_TEST(test_option_t)
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
strftime(date2, sizeof(date2)-1, "%b %d %Y", tmptr);
_snprintf(date, sizeof(date)-1, "%12.12s file", date2);
_snprintf(date, sizeof(date)-1, "%12s file", date2);
#else
strftime(date2, sizeof(date2)-1, "%b %e %Y", tmptr);
snprintf(date, sizeof(date)-1, "%12.12s file", date2);
snprintf(date, sizeof(date)-1, "%12s file", date2);
#endif
assertEqualMem(p + 42, date, strlen(date));
free(p);

View file

@ -55,6 +55,14 @@ int_in_list(int i, const int *l, size_t n)
failure("%d", i);
return (0);
}
static void
free_cpio_owner(struct cpio_owner *owner) {
owner->uid = -1;
owner->gid = -1;
free(owner->uname);
free(owner->gname);
}
#endif
DEFINE_TEST(test_owner_parse)
@ -62,49 +70,58 @@ DEFINE_TEST(test_owner_parse)
#if !defined(ROOT)
skipping("No uid/gid configuration for this OS");
#else
int uid, gid;
struct cpio_owner owner;
const char *errstr;
assert(NULL == owner_parse(ROOT, &uid, &gid));
assert(int_in_list(uid, root_uids,
assert(0 == owner_parse(ROOT, &owner, &errstr));
assert(int_in_list(owner.uid, root_uids,
sizeof(root_uids)/sizeof(root_uids[0])));
assertEqualInt(-1, gid);
assertEqualInt(-1, owner.gid);
free_cpio_owner(&owner);
assert(NULL == owner_parse(ROOT ":", &uid, &gid));
assert(int_in_list(uid, root_uids,
assert(0 == owner_parse(ROOT ":", &owner, &errstr));
assert(int_in_list(owner.uid, root_uids,
sizeof(root_uids)/sizeof(root_uids[0])));
assert(int_in_list(gid, root_gids,
assert(int_in_list(owner.gid, root_gids,
sizeof(root_gids)/sizeof(root_gids[0])));
free_cpio_owner(&owner);
assert(NULL == owner_parse(ROOT ".", &uid, &gid));
assert(int_in_list(uid, root_uids,
assert(0 == owner_parse(ROOT ".", &owner, &errstr));
assert(int_in_list(owner.uid, root_uids,
sizeof(root_uids)/sizeof(root_uids[0])));
assert(int_in_list(gid, root_gids,
assert(int_in_list(owner.gid, root_gids,
sizeof(root_gids)/sizeof(root_gids[0])));
free_cpio_owner(&owner);
assert(NULL == owner_parse("111", &uid, &gid));
assertEqualInt(111, uid);
assertEqualInt(-1, gid);
assert(0 == owner_parse("111", &owner, &errstr));
assertEqualInt(111, owner.uid);
assertEqualInt(-1, owner.gid);
free_cpio_owner(&owner);
assert(NULL == owner_parse("112:", &uid, &gid));
assertEqualInt(112, uid);
assert(0 == owner_parse("112:", &owner, &errstr));
assertEqualInt(112, owner.uid);
/* Can't assert gid, since we don't know gid for user #112. */
free_cpio_owner(&owner);
assert(NULL == owner_parse("113.", &uid, &gid));
assertEqualInt(113, uid);
assert(0 == owner_parse("113.", &owner, &errstr));
assertEqualInt(113, owner.uid);
/* Can't assert gid, since we don't know gid for user #113. */
free_cpio_owner(&owner);
assert(NULL == owner_parse(":114", &uid, &gid));
assertEqualInt(-1, uid);
assertEqualInt(114, gid);
assert(0 == owner_parse(":114", &owner, &errstr));
assertEqualInt(-1, owner.uid);
assertEqualInt(114, owner.gid);
free_cpio_owner(&owner);
assert(NULL == owner_parse(".115", &uid, &gid));
assertEqualInt(-1, uid);
assertEqualInt(115, gid);
assert(0 == owner_parse(".115", &owner, &errstr));
assertEqualInt(-1, owner.uid);
assertEqualInt(115, owner.gid);
free_cpio_owner(&owner);
assert(NULL == owner_parse("116:117", &uid, &gid));
assertEqualInt(116, uid);
assertEqualInt(117, gid);
assert(0 == owner_parse("116:117", &owner, &errstr));
assertEqualInt(116, owner.uid);
assertEqualInt(117, owner.gid);
free_cpio_owner(&owner);
/*
* TODO: Lookup current user/group name, build strings and
@ -112,9 +129,20 @@ DEFINE_TEST(test_owner_parse)
* users.
*/
assert(NULL != owner_parse(":nonexistentgroup", &uid, &gid));
assert(NULL != owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
assert(NULL !=
owner_parse("nonexistentuser:nonexistentgroup", &uid, &gid));
errstr = NULL;
assert(0 != owner_parse(":nonexistentgroup", &owner, &errstr));
assertEqualString(errstr, "Couldn't lookup group ``nonexistentgroup''");
free_cpio_owner(&owner);
errstr = NULL;
assert(0 != owner_parse(ROOT ":nonexistentgroup", &owner, &errstr));
assertEqualString(errstr, "Couldn't lookup group ``nonexistentgroup''");
free_cpio_owner(&owner);
errstr = NULL;
assert(0 != owner_parse("nonexistentuser:nonexistentgroup", &owner,
&errstr));
assertEqualString(errstr, "Couldn't lookup user ``nonexistentuser''");
free_cpio_owner(&owner);
#endif
}

View file

@ -247,7 +247,11 @@ IF(BUILD_SHARED_LIBS)
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
SET_TARGET_PROPERTIES(archive PROPERTIES
VERSION ${SOVERSION_FULL}
SOVERSION ${SOVERSION}
MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
MACHO_CURRENT_VERSION ${MACHO_CURRENT_VERSION})
ENDIF(BUILD_SHARED_LIBS)
# archive_static is a static library

View file

@ -34,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3007004
#define ARCHIVE_VERSION_NUMBER 3007005
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.7.4"
#define ARCHIVE_VERSION_ONLY_STRING "3.7.5"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);

View file

@ -76,7 +76,7 @@ static int is_nfs4_flags(const char *start, const char *end,
int *result);
static int is_nfs4_perms(const char *start, const char *end,
int *result);
static void next_field(const char **p, const char **start,
static void next_field(const char **p, size_t *l, const char **start,
const char **end, char *sep);
static void append_entry(char **p, const char *prefix, int type,
int tag, int flags, const char *name, int perm, int id);
@ -1619,6 +1619,13 @@ next_field_w(const wchar_t **wp, const wchar_t **start,
int
archive_acl_from_text_l(struct archive_acl *acl, const char *text,
int want_type, struct archive_string_conv *sc)
{
return archive_acl_from_text_nl(acl, text, strlen(text), want_type, sc);
}
int
archive_acl_from_text_nl(struct archive_acl *acl, const char *text,
size_t length, int want_type, struct archive_string_conv *sc)
{
struct {
const char *start;
@ -1649,7 +1656,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
ret = ARCHIVE_OK;
types = 0;
while (text != NULL && *text != '\0') {
while (text != NULL && length > 0 && *text != '\0') {
/*
* Parse the fields out of the next entry,
* advance 'text' to start of next entry.
@ -1657,7 +1664,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
fields = 0;
do {
const char *start, *end;
next_field(&text, &start, &end, &sep);
next_field(&text, &length, &start, &end, &sep);
if (fields < numfields) {
field[fields].start = start;
field[fields].end = end;
@ -2047,7 +2054,7 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
}
/*
* Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
* Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *p is updated
* to point to just after the separator. *start points to the first
* character of the matched text and *end just after the last
* character of the matched identifier. In particular *end - *start
@ -2055,42 +2062,42 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
* whitespace.
*/
static void
next_field(const char **p, const char **start,
next_field(const char **p, size_t *l, const char **start,
const char **end, char *sep)
{
/* Skip leading whitespace to find start of field. */
while (**p == ' ' || **p == '\t' || **p == '\n') {
while (*l > 0 && (**p == ' ' || **p == '\t' || **p == '\n')) {
(*p)++;
(*l)--;
}
*start = *p;
/* Scan for the separator. */
while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
**p != '#') {
/* Locate end of field, trim trailing whitespace if necessary */
while (*l > 0 && **p != ' ' && **p != '\t' && **p != '\n' && **p != ',' && **p != ':' && **p != '#') {
(*p)++;
(*l)--;
}
*end = *p;
/* Scan for the separator. */
while (*l > 0 && **p != ',' && **p != ':' && **p != '\n' && **p != '#') {
(*p)++;
(*l)--;
}
*sep = **p;
/* Locate end of field, trim trailing whitespace if necessary */
if (*p == *start) {
*end = *p;
} else {
*end = *p - 1;
while (**end == ' ' || **end == '\t' || **end == '\n') {
(*end)--;
}
(*end)++;
}
/* Handle in-field comments */
if (*sep == '#') {
while (**p != '\0' && **p != ',' && **p != '\n') {
while (*l > 0 && **p != ',' && **p != '\n') {
(*p)++;
(*l)--;
}
*sep = **p;
}
/* Adjust scanner location. */
if (**p != '\0')
/* Skip separator. */
if (*l > 0) {
(*p)++;
(*l)--;
}
}

View file

@ -77,5 +77,7 @@ int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */,
int /* type */);
int archive_acl_from_text_l(struct archive_acl *, const char * /* text */,
int /* type */, struct archive_string_conv *);
int archive_acl_from_text_nl(struct archive_acl *, const char * /* text */,
size_t /* size of text */, int /* type */, struct archive_string_conv *);
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

View file

@ -30,6 +30,8 @@
#error This header is only to be used internally to libarchive.
#endif
#include <stddef.h>
/*
* When zlib is unavailable, we should still be able to validate
* uncompressed zip archives. That requires us to be able to compute
@ -46,6 +48,9 @@ crc32(unsigned long crc, const void *_p, size_t len)
static volatile int crc_tbl_inited = 0;
static unsigned long crc_tbl[256];
if (_p == NULL)
return (0);
if (!crc_tbl_inited) {
for (b = 0; b < 256; ++b) {
crc2 = b;

View file

@ -118,7 +118,7 @@
static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
static const wchar_t *ae_wcstofflags(const wchar_t *stringp,
unsigned long *setp, unsigned long *clrp);
static const char *ae_strtofflags(const char *stringp,
static const char *ae_strtofflags(const char *stringp, size_t length,
unsigned long *setp, unsigned long *clrp);
#ifndef HAVE_WCSCPY
@ -157,10 +157,9 @@ archive_entry_clear(struct archive_entry *entry)
return (NULL);
archive_mstring_clean(&entry->ae_fflags_text);
archive_mstring_clean(&entry->ae_gname);
archive_mstring_clean(&entry->ae_hardlink);
archive_mstring_clean(&entry->ae_linkname);
archive_mstring_clean(&entry->ae_pathname);
archive_mstring_clean(&entry->ae_sourcepath);
archive_mstring_clean(&entry->ae_symlink);
archive_mstring_clean(&entry->ae_uname);
archive_entry_copy_mac_metadata(entry, NULL, 0);
archive_acl_clear(&entry->acl);
@ -195,10 +194,9 @@ archive_entry_clone(struct archive_entry *entry)
* character sets are different? XXX */
archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
archive_mstring_copy(&entry2->ae_linkname, &entry->ae_linkname);
archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
entry2->ae_set = entry->ae_set;
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
@ -477,6 +475,15 @@ _archive_entry_gname_l(struct archive_entry *entry,
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
}
void
archive_entry_set_link_to_hardlink(struct archive_entry *entry)
{
if ((entry->ae_set & AE_SET_SYMLINK) != 0) {
entry->ae_set &= ~AE_SET_SYMLINK;
}
entry->ae_set |= AE_SET_HARDLINK;
}
const char *
archive_entry_hardlink(struct archive_entry *entry)
{
@ -484,7 +491,7 @@ archive_entry_hardlink(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_mbs(
entry->archive, &entry->ae_hardlink, &p) == 0)
entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@ -498,7 +505,7 @@ archive_entry_hardlink_utf8(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_utf8(
entry->archive, &entry->ae_hardlink, &p) == 0)
entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@ -512,13 +519,19 @@ archive_entry_hardlink_w(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_wcs(
entry->archive, &entry->ae_hardlink, &p) == 0)
entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL);
}
int
archive_entry_hardlink_is_set(struct archive_entry *entry)
{
return (entry->ae_set & AE_SET_HARDLINK) != 0;
}
int
_archive_entry_hardlink_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc)
@ -528,7 +541,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
*len = 0;
return (0);
}
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
}
la_int64_t
@ -648,32 +661,50 @@ archive_entry_perm_is_set(struct archive_entry *entry)
return (entry->ae_set & AE_SET_PERM);
}
int
archive_entry_rdev_is_set(struct archive_entry *entry)
{
return (entry->ae_set & AE_SET_RDEV);
}
dev_t
archive_entry_rdev(struct archive_entry *entry)
{
if (entry->ae_stat.aest_rdev_is_broken_down)
return ae_makedev(entry->ae_stat.aest_rdevmajor,
entry->ae_stat.aest_rdevminor);
else
return (entry->ae_stat.aest_rdev);
if (archive_entry_rdev_is_set(entry)) {
if (entry->ae_stat.aest_rdev_is_broken_down)
return ae_makedev(entry->ae_stat.aest_rdevmajor,
entry->ae_stat.aest_rdevminor);
else
return (entry->ae_stat.aest_rdev);
} else {
return 0;
}
}
dev_t
archive_entry_rdevmajor(struct archive_entry *entry)
{
if (entry->ae_stat.aest_rdev_is_broken_down)
return (entry->ae_stat.aest_rdevmajor);
else
return major(entry->ae_stat.aest_rdev);
if (archive_entry_rdev_is_set(entry)) {
if (entry->ae_stat.aest_rdev_is_broken_down)
return (entry->ae_stat.aest_rdevmajor);
else
return major(entry->ae_stat.aest_rdev);
} else {
return 0;
}
}
dev_t
archive_entry_rdevminor(struct archive_entry *entry)
{
if (entry->ae_stat.aest_rdev_is_broken_down)
return (entry->ae_stat.aest_rdevminor);
else
return minor(entry->ae_stat.aest_rdev);
if (archive_entry_rdev_is_set(entry)) {
if (entry->ae_stat.aest_rdev_is_broken_down)
return (entry->ae_stat.aest_rdevminor);
else
return minor(entry->ae_stat.aest_rdev);
} else {
return 0;
}
}
la_int64_t
@ -717,13 +748,22 @@ archive_entry_symlink(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_mbs(
entry->archive, &entry->ae_symlink, &p) == 0)
entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL);
}
void
archive_entry_set_link_to_symlink(struct archive_entry *entry)
{
if ((entry->ae_set & AE_SET_HARDLINK) != 0) {
entry->ae_set &= ~AE_SET_HARDLINK;
}
entry->ae_set |= AE_SET_SYMLINK;
}
int
archive_entry_symlink_type(struct archive_entry *entry)
{
@ -737,7 +777,7 @@ archive_entry_symlink_utf8(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_utf8(
entry->archive, &entry->ae_symlink, &p) == 0)
entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@ -751,7 +791,7 @@ archive_entry_symlink_w(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_wcs(
entry->archive, &entry->ae_symlink, &p) == 0)
entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@ -767,7 +807,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
*len = 0;
return (0);
}
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
}
la_int64_t
@ -864,10 +904,17 @@ archive_entry_set_fflags(struct archive_entry *entry,
const char *
archive_entry_copy_fflags_text(struct archive_entry *entry,
const char *flags)
const char *flags)
{
archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
return (ae_strtofflags(flags,
return archive_entry_copy_fflags_text_len(entry, flags, strlen(flags));
}
const char *
archive_entry_copy_fflags_text_len(struct archive_entry *entry,
const char *flags, size_t flags_length)
{
archive_mstring_copy_mbs_len(&entry->ae_fflags_text, flags, flags_length);
return (ae_strtofflags(flags, flags_length,
&entry->ae_fflags_set, &entry->ae_fflags_clear));
}
@ -883,6 +930,9 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
void
archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
{
if (g < 0) {
g = 0;
}
entry->stat_valid = 0;
entry->ae_stat.aest_gid = g;
entry->ae_set |= AE_SET_GID;
@ -933,6 +983,9 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
void
archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
{
if (ino < 0) {
ino = 0;
}
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
entry->ae_stat.aest_ino = ino;
@ -941,6 +994,9 @@ archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
void
archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
{
if (ino < 0) {
ino = 0;
}
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
entry->ae_stat.aest_ino = ino;
@ -949,17 +1005,24 @@ archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
void
archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
{
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
if (target == NULL) {
entry->ae_set &= ~AE_SET_HARDLINK;
if (entry->ae_set & AE_SET_SYMLINK) {
return;
}
} else {
entry->ae_set |= AE_SET_HARDLINK;
}
entry->ae_set &= ~AE_SET_SYMLINK;
archive_mstring_copy_mbs(&entry->ae_linkname, target);
}
void
archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
{
archive_mstring_copy_utf8(&entry->ae_hardlink, target);
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
return;
archive_mstring_copy_utf8(&entry->ae_linkname, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@ -969,7 +1032,9 @@ archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
void
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
{
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
return;
archive_mstring_copy_mbs(&entry->ae_linkname, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@ -979,7 +1044,9 @@ archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
void
archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
{
archive_mstring_copy_wcs(&entry->ae_hardlink, target);
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
return;
archive_mstring_copy_wcs(&entry->ae_linkname, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@ -989,12 +1056,14 @@ archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target
int
archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target)
{
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
return (0);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
entry->ae_set &= ~AE_SET_HARDLINK;
if (archive_mstring_update_utf8(entry->archive,
&entry->ae_hardlink, target) == 0)
&entry->ae_linkname, target) == 0)
return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@ -1007,7 +1076,9 @@ _archive_entry_copy_hardlink_l(struct archive_entry *entry,
{
int r;
r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
return (0);
r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
target, len, sc);
if (target != NULL && r == 0)
entry->ae_set |= AE_SET_HARDLINK;
@ -1098,51 +1169,50 @@ archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
void
archive_entry_set_link(struct archive_entry *entry, const char *target)
{
if (entry->ae_set & AE_SET_SYMLINK)
archive_mstring_copy_mbs(&entry->ae_symlink, target);
else
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
archive_mstring_copy_mbs(&entry->ae_linkname, target);
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
entry->ae_set |= AE_SET_HARDLINK;
}
}
void
archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
{
if (entry->ae_set & AE_SET_SYMLINK)
archive_mstring_copy_utf8(&entry->ae_symlink, target);
else
archive_mstring_copy_utf8(&entry->ae_hardlink, target);
archive_mstring_copy_utf8(&entry->ae_linkname, target);
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
entry->ae_set |= AE_SET_HARDLINK;
}
}
/* Set symlink if symlink is already set, else set hardlink. */
void
archive_entry_copy_link(struct archive_entry *entry, const char *target)
{
if (entry->ae_set & AE_SET_SYMLINK)
archive_mstring_copy_mbs(&entry->ae_symlink, target);
else
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
archive_mstring_copy_mbs(&entry->ae_linkname, target);
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
entry->ae_set |= AE_SET_HARDLINK;
}
}
/* Set symlink if symlink is already set, else set hardlink. */
void
archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
{
if (entry->ae_set & AE_SET_SYMLINK)
archive_mstring_copy_wcs(&entry->ae_symlink, target);
else
archive_mstring_copy_wcs(&entry->ae_hardlink, target);
archive_mstring_copy_wcs(&entry->ae_linkname, target);
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
entry->ae_set |= AE_SET_HARDLINK;
}
}
int
archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
{
int r;
if (entry->ae_set & AE_SET_SYMLINK)
r = archive_mstring_update_utf8(entry->archive,
&entry->ae_symlink, target);
else
r = archive_mstring_update_utf8(entry->archive,
&entry->ae_hardlink, target);
r = archive_mstring_update_utf8(entry->archive,
&entry->ae_linkname, target);
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
entry->ae_set |= AE_SET_HARDLINK;
}
if (r == 0)
return (1);
if (errno == ENOMEM)
@ -1156,12 +1226,11 @@ _archive_entry_copy_link_l(struct archive_entry *entry,
{
int r;
if (entry->ae_set & AE_SET_SYMLINK)
r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
target, len, sc);
else
r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
target, len, sc);
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
entry->ae_set |= AE_SET_HARDLINK;
}
return (r);
}
@ -1255,6 +1324,9 @@ archive_entry_set_rdev(struct archive_entry *entry, dev_t m)
entry->stat_valid = 0;
entry->ae_stat.aest_rdev = m;
entry->ae_stat.aest_rdev_is_broken_down = 0;
entry->ae_stat.aest_rdevmajor = 0;
entry->ae_stat.aest_rdevminor = 0;
entry->ae_set |= AE_SET_RDEV;
}
void
@ -1262,7 +1334,9 @@ archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
{
entry->stat_valid = 0;
entry->ae_stat.aest_rdev_is_broken_down = 1;
entry->ae_stat.aest_rdev = 0;
entry->ae_stat.aest_rdevmajor = m;
entry->ae_set |= AE_SET_RDEV;
}
void
@ -1270,12 +1344,17 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
{
entry->stat_valid = 0;
entry->ae_stat.aest_rdev_is_broken_down = 1;
entry->ae_stat.aest_rdev = 0;
entry->ae_stat.aest_rdevminor = m;
entry->ae_set |= AE_SET_RDEV;
}
void
archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
{
if (s < 0) {
s = 0;
}
entry->stat_valid = 0;
entry->ae_stat.aest_size = s;
entry->ae_set |= AE_SET_SIZE;
@ -1303,11 +1382,14 @@ archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path
void
archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
{
archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
return;
archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
entry->ae_set &= ~AE_SET_HARDLINK;
if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
else
entry->ae_set |= AE_SET_SYMLINK;
}
void
@ -1319,42 +1401,54 @@ archive_entry_set_symlink_type(struct archive_entry *entry, int type)
void
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
{
archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
return;
archive_mstring_copy_utf8(&entry->ae_linkname, linkname);
entry->ae_set &= ~AE_SET_HARDLINK;
if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
else
entry->ae_set |= AE_SET_SYMLINK;
}
void
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
{
archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
return;
archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
entry->ae_set &= ~AE_SET_HARDLINK;
if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
else
entry->ae_set |= AE_SET_SYMLINK;
}
void
archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
{
archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
return;
archive_mstring_copy_wcs(&entry->ae_linkname, linkname);
entry->ae_set &= ~AE_SET_HARDLINK;
if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
else
entry->ae_set |= AE_SET_SYMLINK;
}
int
archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname)
{
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
return (0);
entry->ae_set &= ~AE_SET_HARDLINK;
if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
else
entry->ae_set |= AE_SET_SYMLINK;
if (archive_mstring_update_utf8(entry->archive,
&entry->ae_symlink, linkname) == 0)
&entry->ae_linkname, linkname) == 0)
return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@ -1367,18 +1461,24 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
{
int r;
r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
return (0);
entry->ae_set &= ~AE_SET_HARDLINK;
r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
linkname, len, sc);
if (linkname != NULL && r == 0)
entry->ae_set |= AE_SET_SYMLINK;
else
if (linkname == NULL || r != 0)
entry->ae_set &= ~AE_SET_SYMLINK;
else
entry->ae_set |= AE_SET_SYMLINK;
return (r);
}
void
archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
{
if (u < 0) {
u = 0;
}
entry->stat_valid = 0;
entry->ae_stat.aest_uid = u;
entry->ae_set |= AE_SET_UID;
@ -2031,7 +2131,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
* provided string.
*/
static const char *
ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
ae_strtofflags(const char *s, size_t l, unsigned long *setp, unsigned long *clrp)
{
const char *start, *end;
const struct flag *flag;
@ -2042,15 +2142,19 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
start = s;
failed = NULL;
/* Find start of first token. */
while (*start == '\t' || *start == ' ' || *start == ',')
while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
start++;
while (*start != '\0') {
l--;
}
while (l > 0) {
size_t length;
/* Locate end of token. */
end = start;
while (*end != '\0' && *end != '\t' &&
*end != ' ' && *end != ',')
while (l > 0 && *end != '\t' &&
*end != ' ' && *end != ',') {
end++;
l--;
}
length = end - start;
for (flag = fileflags; flag->name != NULL; flag++) {
size_t flag_length = strlen(flag->name);
@ -2074,8 +2178,10 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
/* Find start of next token. */
start = end;
while (*start == '\t' || *start == ' ' || *start == ',')
while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
start++;
l--;
}
}

View file

@ -28,7 +28,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3007004
#define ARCHIVE_VERSION_NUMBER 3007005
/*
* Note: archive_entry.h is for use outside of libarchive; the
@ -259,9 +259,11 @@ __LA_DECL int archive_entry_gid_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
__LA_DECL void archive_entry_set_link_to_hardlink(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
__LA_DECL int archive_entry_hardlink_is_set(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
@ -275,6 +277,7 @@ __LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
__LA_DECL int archive_entry_perm_is_set(struct archive_entry *);
__LA_DECL int archive_entry_rdev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
@ -283,6 +286,7 @@ __LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
__LA_DECL void archive_entry_set_link_to_symlink(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
@ -324,6 +328,8 @@ __LA_DECL void archive_entry_set_fflags(struct archive_entry *,
/* Note that all recognized tokens are processed, regardless. */
__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
__LA_DECL const char *archive_entry_copy_fflags_text_len(struct archive_entry *,
const char *, size_t);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);

View file

@ -201,16 +201,26 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
le = find_entry(res, *e);
if (le != NULL) {
archive_entry_unset_size(*e);
#if defined(_WIN32) && !defined(__CYGWIN__)
archive_entry_copy_hardlink_w(*e,
archive_entry_pathname_w(le->canonical));
#else
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
#endif
} else
insert_entry(res, *e);
return;
case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
le = find_entry(res, *e);
if (le != NULL) {
#if defined(_WIN32) && !defined(__CYGWIN__)
archive_entry_copy_hardlink_w(*e,
archive_entry_pathname_w(le->canonical));
#else
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
#endif
} else
insert_entry(res, *e);
return;
@ -229,8 +239,13 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
le->entry = t;
/* Make the old entry into a hardlink. */
archive_entry_unset_size(*e);
#if defined(_WIN32) && !defined(__CYGWIN__)
archive_entry_copy_hardlink_w(*e,
archive_entry_pathname_w(le->canonical));
#else
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
#endif
/* If we ran out of links, return the
* final entry as well. */
if (le->links == 0) {

View file

@ -150,6 +150,7 @@ character strings at the same time.
.Fn archive_entry_set_XXX
is an alias for
.Fn archive_entry_copy_XXX .
The strings are copied, and don't need to outlive the call.
.Ss File Flags
File flags are transparently converted between a bitmap
representation and a textual format.

View file

@ -149,6 +149,7 @@ struct archive_entry {
#define AE_SET_FILETYPE 1024
#define AE_SET_UID 2048
#define AE_SET_GID 4096
#define AE_SET_RDEV 8192
/*
* Use aes here so that we get transparent mbs<->wcs conversions.
@ -157,9 +158,8 @@ struct archive_entry {
unsigned long ae_fflags_set; /* Bitmap fflags */
unsigned long ae_fflags_clear;
struct archive_mstring ae_gname; /* Name of owning group */
struct archive_mstring ae_hardlink; /* Name of target for hardlink */
struct archive_mstring ae_linkname; /* Name of target for hardlink or symlink */
struct archive_mstring ae_pathname; /* Name of entry */
struct archive_mstring ae_symlink; /* symlink contents */
struct archive_mstring ae_uname; /* Name of owner */
/* Not used within libarchive; useful for some clients. */

View file

@ -671,7 +671,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0)));
}
do
while (numPs != 0)
{
/* Create Child */
CTX_PTR c1; /* = AllocContext(p); */
@ -692,8 +692,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
SetSuccessor(ps[--numPs], REF(c1));
c = c1;
}
while (numPs != 0);
return c;
}

View file

@ -27,8 +27,10 @@
#define ARCHIVE_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#if HAVE_ICONV_H
#include <iconv.h>

View file

@ -1382,7 +1382,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
if (filter->client_avail <= 0) {
if (filter->end_of_file) {
if (avail != NULL)
*avail = 0;
*avail = filter->avail;
return (NULL);
}
bytes_read = (filter->vtable->read)(filter,

View file

@ -111,7 +111,7 @@ archive_read_append_filter(struct archive *_a, int code)
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
bidder = a->bidders;
for (i = 0; i < number_bidders; i++, bidder++)
for (i = 1; i < number_bidders; i++, bidder++)
{
if (!bidder->name || !strcmp(bidder->name, str))
break;

View file

@ -520,6 +520,7 @@ setup_xattr(struct archive_read_disk *a,
if (size == -1) {
archive_set_error(&a->archive, errno,
"Couldn't read extended attribute");
free(value);
return (ARCHIVE_WARN);
}

View file

@ -1955,6 +1955,8 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
return (t->visit_type);
}
/* Top stack item needs a regular visit. */
t->current = t->stack;
t->findData = &t->_findData;
pattern = NULL;
} else if (!FindNextFileW(t->d, &t->_findData)) {

View file

@ -291,7 +291,8 @@ consume_header(struct archive_read_filter *self)
if (p == NULL)
goto truncated;
len = archive_be32dec(p);
__archive_read_filter_consume(self->upstream, len + 4 + 4);
__archive_read_filter_consume(self->upstream,
(int64_t)len + 4 + 4);
}
state->flags = flags;
state->in_stream = 1;

View file

@ -39,8 +39,8 @@
struct rpm {
int64_t total_in;
size_t hpos;
size_t hlen;
uint64_t hpos;
uint64_t hlen;
unsigned char header[16];
enum {
ST_LEAD, /* Skipping 'Lead' section. */
@ -53,7 +53,8 @@ struct rpm {
} state;
int first_header;
};
#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
#define RPM_MIN_HEAD_SIZE 16 /* Minimum size of 'Head'. */
static int rpm_bidder_bid(struct archive_read_filter_bidder *,
struct archive_read_filter *);
@ -63,6 +64,8 @@ static ssize_t rpm_filter_read(struct archive_read_filter *,
const void **);
static int rpm_filter_close(struct archive_read_filter *);
static inline size_t rpm_limit_bytes(uint64_t, size_t);
#if ARCHIVE_VERSION_NUMBER < 4000000
/* Deprecated; remove in libarchive 4.0 */
int
@ -155,15 +158,21 @@ rpm_bidder_init(struct archive_read_filter *self)
return (ARCHIVE_OK);
}
static inline size_t
rpm_limit_bytes(uint64_t bytes, size_t max)
{
return (bytes > max ? max : (size_t)bytes);
}
static ssize_t
rpm_filter_read(struct archive_read_filter *self, const void **buff)
{
struct rpm *rpm;
const unsigned char *b;
ssize_t avail_in, total;
size_t used, n;
uint32_t section;
uint32_t bytes;
ssize_t avail_in, total, used;
size_t n;
uint64_t section;
uint64_t bytes;
rpm = (struct rpm *)self->data;
*buff = NULL;
@ -197,15 +206,14 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
}
break;
case ST_HEADER:
n = 16 - rpm->hpos;
if (n > avail_in - used)
n = avail_in - used;
n = rpm_limit_bytes(RPM_MIN_HEAD_SIZE - rpm->hpos,
avail_in - used);
memcpy(rpm->header+rpm->hpos, b, n);
b += n;
used += n;
rpm->hpos += n;
if (rpm->hpos == 16) {
if (rpm->hpos == RPM_MIN_HEAD_SIZE) {
if (rpm->header[0] != 0x8e ||
rpm->header[1] != 0xad ||
rpm->header[2] != 0xe8 ||
@ -219,21 +227,20 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
}
rpm->state = ST_ARCHIVE;
*buff = rpm->header;
total = rpm->hpos;
total = RPM_MIN_HEAD_SIZE;
break;
}
/* Calculate 'Header' length. */
section = archive_be32dec(rpm->header+8);
bytes = archive_be32dec(rpm->header+12);
rpm->hlen = 16 + section * 16 + bytes;
rpm->hlen = rpm->hpos + section * 16 + bytes;
rpm->state = ST_HEADER_DATA;
rpm->first_header = 0;
}
break;
case ST_HEADER_DATA:
n = rpm->hlen - rpm->hpos;
if (n > avail_in - used)
n = avail_in - used;
n = rpm_limit_bytes(rpm->hlen - rpm->hpos,
avail_in - used);
b += n;
used += n;
rpm->hpos += n;
@ -241,7 +248,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
rpm->state = ST_PADDING;
break;
case ST_PADDING:
while (used < (size_t)avail_in) {
while (used < avail_in) {
if (*b != 0) {
/* Read next header. */
rpm->state = ST_HEADER;
@ -259,7 +266,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
used = avail_in;
break;
}
if (used == (size_t)avail_in) {
if (used == avail_in) {
rpm->total_in += used;
__archive_read_filter_consume(self->upstream, used);
b = NULL;

View file

@ -43,11 +43,13 @@
/* Maximum lookahead during bid phase */
#define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */
#define UUENCODE_MAX_LINE_LENGTH 34*1024 /* in bytes */
struct uudecode {
int64_t total;
unsigned char *in_buff;
#define IN_BUFF_SIZE (1024)
int in_cnt;
ssize_t in_cnt;
size_t in_allocated;
unsigned char *out_buff;
#define OUT_BUFF_SIZE (64 * 1024)
@ -484,6 +486,12 @@ read_more:
goto finish;
}
if (uudecode->in_cnt) {
if (uudecode->in_cnt > UUENCODE_MAX_LINE_LENGTH) {
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid format data");
return (ARCHIVE_FATAL);
}
/*
* If there is remaining data which is saved by
* previous calling, use it first.
@ -498,7 +506,7 @@ read_more:
uudecode->in_cnt = 0;
}
for (;used < avail_in; d += llen, used += llen) {
int64_t l, body;
ssize_t l, body;
b = d;
len = get_line(b, avail_in - used, &nl);
@ -533,7 +541,7 @@ read_more:
return (ARCHIVE_FATAL);
if (uudecode->in_buff != b)
memmove(uudecode->in_buff, b, len);
uudecode->in_cnt = (int)len;
uudecode->in_cnt = len;
if (total == 0) {
/* Do not return 0; it means end-of-file.
* We should try to read bytes more. */

View file

@ -877,10 +877,9 @@ archive_read_format_7zip_read_data(struct archive_read *a,
if (zip->end_of_entry)
return (ARCHIVE_EOF);
const uint64_t max_read_size = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
size_t bytes_to_read = max_read_size;
size_t bytes_to_read = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) {
bytes_to_read = zip->entry_bytes_remaining;
bytes_to_read = (size_t)zip->entry_bytes_remaining;
}
bytes = read_stream(a, buff, bytes_to_read, 0);
if (bytes < 0)
@ -1063,8 +1062,8 @@ ppmd_read(void *p)
*/
ssize_t bytes_avail = 0;
const uint8_t* data = __archive_read_ahead(a,
zip->ppstream.stream_in+1, &bytes_avail);
if(bytes_avail < zip->ppstream.stream_in+1) {
(size_t)zip->ppstream.stream_in+1, &bytes_avail);
if(data == NULL || bytes_avail < zip->ppstream.stream_in+1) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated 7z file data");
@ -1766,6 +1765,10 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
}
zip->stream_valid = 0;
}
#endif
#ifdef HAVE_ZSTD_H
if (zip->zstdstream_valid)
ZSTD_freeDStream(zip->zstd_dstream);
#endif
if (zip->ppmd7_valid) {
__archive_ppmd7_functions.Ppmd7_Free(
@ -2308,7 +2311,7 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
usizes = ss->unpackSizes;
for (i = 0; i < numFolders; i++) {
unsigned pack;
uint64_t sum;
uint64_t size, sum;
if (f[i].numUnpackStreams == 0)
continue;
@ -2318,10 +2321,15 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
if (parse_7zip_uint64(a, usizes) < 0)
return (-1);
if (*usizes > UINT64_MAX - sum)
return (-1);
sum += *usizes++;
}
}
*usizes++ = folder_uncompressed_size(&f[i]) - sum;
size = folder_uncompressed_size(&f[i]);
if (size < sum)
return (-1);
*usizes++ = size - sum;
}
if (type == kSize) {
@ -2415,6 +2423,8 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
packPos = si->pi.pos;
for (i = 0; i < si->pi.numPackStreams; i++) {
si->pi.positions[i] = packPos;
if (packPos > UINT64_MAX - si->pi.sizes[i])
return (-1);
packPos += si->pi.sizes[i];
if (packPos > zip->header_offset)
return (-1);
@ -2436,6 +2446,10 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
f = si->ci.folders;
for (i = 0; i < si->ci.numFolders; i++) {
f[i].packIndex = packIndex;
if (f[i].numPackedStreams > UINT32_MAX)
return (-1);
if (packIndex > UINT32_MAX - (uint32_t)f[i].numPackedStreams)
return (-1);
packIndex += (uint32_t)f[i].numPackedStreams;
if (packIndex > si->pi.numPackStreams)
return (-1);
@ -3000,7 +3014,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
/* CRC check. */
if (crc32(0, (const unsigned char *)p + 12, 20)
!= archive_le32dec(p + 8)) {
#ifdef DONT_FAIL_ON_CRC_ERROR
#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, -1, "Header CRC error");
return (ARCHIVE_FATAL);
#endif
@ -3142,7 +3156,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
/* Copy mode. */
*buff = __archive_read_ahead(a, minimum, &bytes_avail);
if (bytes_avail <= 0) {
if (*buff == NULL) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated 7-Zip file data");
@ -3448,7 +3462,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
/*
* Skip the bytes we already has skipped in skip_stream().
*/
while (skip_bytes) {
while (1) {
ssize_t skipped;
if (zip->uncompressed_buffer_bytes_remaining == 0) {
@ -3468,6 +3482,10 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
return (ARCHIVE_FATAL);
}
}
if (!skip_bytes)
break;
skipped = get_uncompressed_data(
a, buff, (size_t)skip_bytes, 0);
if (skipped < 0)

View file

@ -439,9 +439,9 @@ archive_read_format_ar_read_header(struct archive_read *a,
if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
/* Broken header. */
return (ARCHIVE_EOF);
unconsumed = 60;
ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
if (unconsumed)
@ -458,7 +458,6 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
uint64_t n;
/* Copy remaining header */
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_mtime(entry,
(time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
archive_entry_set_uid(entry,
@ -467,6 +466,7 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
(gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size));
archive_entry_set_mode(entry,
(mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size));
archive_entry_set_filetype(entry, AE_IFREG);
n = ar_atol10(h + AR_size_offset, AR_size_size);
ar->entry_offset = 0;

View file

@ -1682,7 +1682,7 @@ cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
cfdata->uncompressed_size - cab->xstrm.total_out;
d = __archive_read_ahead(a, 1, &bytes_avail);
if (bytes_avail <= 0) {
if (d == NULL) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated CAB file data");

View file

@ -834,6 +834,7 @@ static int
header_afiol(struct archive_read *a, struct cpio *cpio,
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
int64_t t;
const void *h;
const char *header;
@ -850,7 +851,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
archive_entry_set_dev(entry,
(dev_t)atol16(header + afiol_dev_offset, afiol_dev_size));
archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
t = atol16(header + afiol_ino_offset, afiol_ino_size);
if (t < 0) {
archive_set_error(&a->archive, 0, "Nonsensical ino value");
return (ARCHIVE_FATAL);
}
archive_entry_set_ino(entry, t);
archive_entry_set_mode(entry,
(mode_t)atol8(header + afiol_mode_offset, afiol_mode_size));
archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
@ -863,8 +869,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
*namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size);
*name_pad = 0; /* No padding of filename. */
cpio->entry_bytes_remaining =
atol16(header + afiol_filesize_offset, afiol_filesize_size);
t = atol16(header + afiol_filesize_offset, afiol_filesize_size);
if (t < 0) {
archive_set_error(&a->archive, 0, "Nonsensical file size");
return (ARCHIVE_FATAL);
}
cpio->entry_bytes_remaining = t;
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = 0;
__archive_read_consume(a, afiol_header_size);
@ -1002,7 +1012,7 @@ be4(const unsigned char *p)
static int64_t
atol8(const char *p, unsigned char_cnt)
{
int64_t l;
uint64_t l;
int digit;
l = 0;
@ -1010,18 +1020,18 @@ atol8(const char *p, unsigned char_cnt)
if (*p >= '0' && *p <= '7')
digit = *p - '0';
else
return (l);
return ((int64_t)l);
p++;
l <<= 3;
l |= digit;
}
return (l);
return ((int64_t)l);
}
static int64_t
atol16(const char *p, unsigned char_cnt)
{
int64_t l;
uint64_t l;
int digit;
l = 0;
@ -1033,12 +1043,12 @@ atol16(const char *p, unsigned char_cnt)
else if (*p >= '0' && *p <= '9')
digit = *p - '0';
else
return (l);
return ((int64_t)l);
p++;
l <<= 4;
l |= digit;
}
return (l);
return ((int64_t)l);
}
static int

View file

@ -402,6 +402,9 @@ static int isJolietSVD(struct iso9660 *, const unsigned char *);
static int isSVD(struct iso9660 *, const unsigned char *);
static int isEVD(struct iso9660 *, const unsigned char *);
static int isPVD(struct iso9660 *, const unsigned char *);
static int isRootDirectoryRecord(const unsigned char *);
static int isValid723Integer(const unsigned char *);
static int isValid733Integer(const unsigned char *);
static int next_cache_entry(struct archive_read *, struct iso9660 *,
struct file_info **);
static int next_entry_seek(struct archive_read *, struct iso9660 *,
@ -773,8 +776,9 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
/* Read Root Directory Record in Volume Descriptor. */
p = h + SVD_root_directory_record_offset;
if (p[DR_length_offset] != 34)
if (!isRootDirectoryRecord(p)) {
return (0);
}
return (48);
}
@ -851,8 +855,9 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
/* Read Root Directory Record in Volume Descriptor. */
p = h + PVD_root_directory_record_offset;
if (p[DR_length_offset] != 34)
if (!isRootDirectoryRecord(p)) {
return (0);
}
return (48);
}
@ -882,21 +887,43 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
return (0);
/* Volume space size must be encoded according to 7.3.3 */
if (!isValid733Integer(h + PVD_volume_space_size_offset)) {
return (0);
}
volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
if (volume_block <= SYSTEM_AREA_BLOCK+4)
return (0);
/* Reserved field must be 0. */
if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
return (0);
/* Volume set size must be encoded according to 7.2.3 */
if (!isValid723Integer(h + PVD_volume_set_size_offset)) {
return (0);
}
/* Volume sequence number must be encoded according to 7.2.3 */
if (!isValid723Integer(h + PVD_volume_sequence_number_offset)) {
return (0);
}
/* Logical block size must be > 0. */
/* I've looked at Ecma 119 and can't find any stronger
* restriction on this field. */
if (!isValid723Integer(h + PVD_logical_block_size_offset)) {
return (0);
}
logical_block_size =
archive_le16dec(h + PVD_logical_block_size_offset);
if (logical_block_size <= 0)
return (0);
volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
if (volume_block <= SYSTEM_AREA_BLOCK+4)
/* Path Table size must be encoded according to 7.3.3 */
if (!isValid733Integer(h + PVD_path_table_size_offset)) {
return (0);
}
/* File structure version must be 1 for ISO9660/ECMA119. */
if (h[PVD_file_structure_version_offset] != 1)
@ -935,8 +962,9 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
/* Read Root Directory Record in Volume Descriptor. */
p = h + PVD_root_directory_record_offset;
if (p[DR_length_offset] != 34)
if (!isRootDirectoryRecord(p)) {
return (0);
}
if (!iso9660->primary.location) {
iso9660->logical_block_size = logical_block_size;
@ -951,6 +979,51 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
return (48);
}
static int
isRootDirectoryRecord(const unsigned char *p) {
int flags;
/* ECMA119/ISO9660 requires that the root directory record be _exactly_ 34 bytes.
* However, we've seen images that have root directory records up to 68 bytes. */
if (p[DR_length_offset] < 34 || p[DR_length_offset] > 68) {
return (0);
}
/* The root directory location must be a 7.3.3 32-bit integer. */
if (!isValid733Integer(p + DR_extent_offset)) {
return (0);
}
/* The root directory size must be a 7.3.3 integer. */
if (!isValid733Integer(p + DR_size_offset)) {
return (0);
}
/* According to the standard, certain bits must be one or zero:
* Bit 1: must be 1 (this is a directory)
* Bit 2: must be 0 (not an associated file)
* Bit 3: must be 0 (doesn't use extended attribute record)
* Bit 7: must be 0 (final directory record for this file)
*/
flags = p[DR_flags_offset];
if ((flags & 0x8E) != 0x02) {
return (0);
}
/* Volume sequence number must be a 7.2.3 integer. */
if (!isValid723Integer(p + DR_volume_sequence_number_offset)) {
return (0);
}
/* Root directory name is a single zero byte... */
if (p[DR_name_len_offset] != 1 || p[DR_name_offset] != 0) {
return (0);
}
/* Nothing looked wrong, so let's accept it. */
return (1);
}
static int
read_children(struct archive_read *a, struct file_info *parent)
{
@ -1212,7 +1285,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
}
}
if (iso9660->utf16be_previous_path == NULL) {
iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
iso9660->utf16be_previous_path = calloc(1, UTF16_NAME_MAX);
if (iso9660->utf16be_previous_path == NULL) {
archive_set_error(&a->archive, ENOMEM,
"No memory");
@ -3033,7 +3106,7 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
return (ARCHIVE_FATAL);
}
new_pending_files = (struct file_info **)
malloc(new_size * sizeof(new_pending_files[0]));
calloc(new_size, sizeof(new_pending_files[0]));
if (new_pending_files == NULL) {
archive_set_error(&a->archive,
ENOMEM, "Out of memory");
@ -3127,6 +3200,32 @@ toi(const void *p, int n)
return (0);
}
/*
* ECMA119/ISO9660 stores multi-byte integers in one of
* three different formats:
* * Little-endian (specified in section 7.2.1 and 7.3.1)
* * Big-endian (specified in section 7.2.2 and 7.3.2)
* * Both (specified in section 7.2.3 and 7.3.3)
*
* For values that follow section 7.2.3 (16-bit) or 7.3.3 (32-bit), we
* can check that the little-endian and big-endian forms agree with
* each other. This helps us avoid trying to decode files that are
* not really ISO images.
*/
static int
isValid723Integer(const unsigned char *p) {
return (p[0] == p[3] && p[1] == p[2]);
}
static int
isValid733Integer(const unsigned char *p)
{
return (p[0] == p[7]
&& p[1] == p[6]
&& p[2] == p[5]
&& p[3] == p[4]);
}
static time_t
isodate7(const unsigned char *v)
{
@ -3164,7 +3263,7 @@ isodate17(const unsigned char *v)
tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
+ (v[2] - '0') * 10 + (v[3] - '0')
- 1900;
tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0') - 1;
tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');

View file

@ -227,7 +227,7 @@ static int lha_read_file_header_1(struct archive_read *, struct lha *);
static int lha_read_file_header_2(struct archive_read *, struct lha *);
static int lha_read_file_header_3(struct archive_read *, struct lha *);
static int lha_read_file_extended_header(struct archive_read *,
struct lha *, uint16_t *, int, size_t, size_t *);
struct lha *, uint16_t *, int, uint64_t, size_t *);
static size_t lha_check_header_format(const void *);
static int lha_skip_sfx(struct archive_read *);
static time_t lha_dos_time(const unsigned char *);
@ -945,7 +945,7 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
/* Read extended headers */
err2 = lha_read_file_extended_header(a, lha, NULL, 2,
(size_t)(lha->compsize + 2), &extdsize);
(uint64_t)(lha->compsize + 2), &extdsize);
if (err2 < ARCHIVE_WARN)
return (err2);
if (err2 < err)
@ -1138,7 +1138,7 @@ invalid:
*/
static int
lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
uint16_t *crc, int sizefield_length, uint64_t limitsize, size_t *total_size)
{
const void *h;
const unsigned char *extdheader;
@ -1187,8 +1187,7 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
}
/* Sanity check to the extended header size. */
if (((uint64_t)*total_size + extdsize) >
(uint64_t)limitsize ||
if (((uint64_t)*total_size + extdsize) > limitsize ||
extdsize <= (size_t)sizefield_length)
goto invalid;

View file

@ -432,7 +432,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
struct huffman_table_entry *, int, int);
static int expand(struct archive_read *, int64_t *);
static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
int64_t, int);
int64_t, size_t);
static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
static int parse_filter(struct archive_read *, const uint8_t *, uint16_t,
uint8_t);
@ -1373,6 +1373,8 @@ read_header(struct archive_read *a, struct archive_entry *entry,
struct archive_string_conv *sconv, *fn_sconv;
unsigned long crc32_val;
int ret = (ARCHIVE_OK), ret2;
char *newptr;
size_t newsize;
rar = (struct rar *)(a->format->data);
@ -1469,6 +1471,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
if (rar->file_flags & FHD_LARGE)
{
if (p + 8 > endp) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid header size");
return (ARCHIVE_FATAL);
}
memcpy(packed_size, file_header.pack_size, 4);
memcpy(packed_size + 4, p, 4); /* High pack size */
p += 4;
@ -1514,8 +1521,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
if (rar->filename_allocated < filename_size * 2 + 2) {
char *newptr;
size_t newsize = filename_size * 2 + 2;
newsize = filename_size * 2 + 2;
newptr = realloc(rar->filename, newsize);
if (newptr == NULL) {
archive_set_error(&a->archive, ENOMEM,
@ -1539,7 +1545,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
fn_end = filename_size * 2;
filename_size = 0;
offset = (unsigned)strlen(filename) + 1;
highbyte = *(p + offset++);
highbyte = offset >= end ? 0 : *(p + offset++);
flagbits = 0;
flagbyte = 0;
while (offset < end && filename_size < fn_end)
@ -1554,14 +1560,22 @@ read_header(struct archive_read *a, struct archive_entry *entry,
switch((flagbyte >> flagbits) & 3)
{
case 0:
if (offset >= end)
continue;
filename[filename_size++] = '\0';
filename[filename_size++] = *(p + offset++);
break;
case 1:
if (offset >= end)
continue;
filename[filename_size++] = highbyte;
filename[filename_size++] = *(p + offset++);
break;
case 2:
if (offset >= end - 1) {
offset = end;
continue;
}
filename[filename_size++] = *(p + offset + 1);
filename[filename_size++] = *(p + offset);
offset += 2;
@ -1569,9 +1583,15 @@ read_header(struct archive_read *a, struct archive_entry *entry,
case 3:
{
char extra, high;
uint8_t length = *(p + offset++);
uint8_t length;
if (offset >= end)
continue;
length = *(p + offset++);
if (length & 0x80) {
if (offset >= end)
continue;
extra = *(p + offset++);
high = (char)highbyte;
} else
@ -1652,13 +1672,16 @@ read_header(struct archive_read *a, struct archive_entry *entry,
rar->cursor++;
if (rar->cursor >= rar->nodes)
{
rar->nodes++;
if ((rar->dbo =
realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL)
struct data_block_offsets *newdbo;
newsize = sizeof(*rar->dbo) * (rar->nodes + 1);
if ((newdbo = realloc(rar->dbo, newsize)) == NULL)
{
archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
return (ARCHIVE_FATAL);
}
rar->dbo = newdbo;
rar->nodes++;
rar->dbo[rar->cursor].header_size = header_size;
rar->dbo[rar->cursor].start_offset = -1;
rar->dbo[rar->cursor].end_offset = -1;
@ -1678,9 +1701,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
rar->filename_save = (char*)realloc(rar->filename_save,
filename_size + 1);
memcpy(rar->filename_save, rar->filename, filename_size + 1);
newsize = filename_size + 1;
if ((newptr = realloc(rar->filename_save, newsize)) == NULL)
{
archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
return (ARCHIVE_FATAL);
}
rar->filename_save = newptr;
memcpy(rar->filename_save, rar->filename, newsize);
rar->filename_save_size = filename_size;
/* Set info for seeking */
@ -2060,7 +2088,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
bs = rar->unp_buffer_size - rar->unp_offset;
else
bs = (size_t)rar->bytes_uncopied;
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK)
return (ret);
rar->offset += bs;
@ -2213,7 +2241,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
bs = rar->unp_buffer_size - rar->unp_offset;
else
bs = (size_t)rar->bytes_uncopied;
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK)
return (ret);
rar->offset += bs;
@ -2579,8 +2607,7 @@ read_next_symbol(struct archive_read *a, struct huffman_code *code)
rar_br_consume(br, code->tablesize);
node = value;
while (!(code->tree[node].branches[0] ==
code->tree[node].branches[1]))
while (code->tree[node].branches[0] != code->tree[node].branches[1])
{
if (!rar_br_read_ahead(a, br, 1)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@ -2955,7 +2982,7 @@ expand(struct archive_read *a, int64_t *end)
if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
goto bad_data;
if (lensymbol > lengthb_min)
if (lensymbol >= lengthb_min)
goto bad_data;
len = lengthbases[lensymbol] + 2;
if (lengthbits[lensymbol] > 0) {
@ -2987,7 +3014,7 @@ expand(struct archive_read *a, int64_t *end)
}
else
{
if (symbol-271 > lengthb_min)
if (symbol-271 >= lengthb_min)
goto bad_data;
len = lengthbases[symbol-271]+3;
if(lengthbits[symbol-271] > 0) {
@ -2999,7 +3026,7 @@ expand(struct archive_read *a, int64_t *end)
if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
goto bad_data;
if (offssymbol > offsetb_min)
if (offssymbol >= offsetb_min)
goto bad_data;
offs = offsetbases[offssymbol]+1;
if(offsetbits[offssymbol] > 0)
@ -3094,11 +3121,16 @@ copy_from_lzss_window(struct archive_read *a, void *buffer,
static int
copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
int64_t startpos, int length)
int64_t startpos, size_t length)
{
int windowoffs, firstpart;
struct rar *rar = (struct rar *)(a->format->data);
if (length > rar->unp_buffer_size)
{
goto fatal;
}
if (!rar->unp_buffer)
{
if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
@ -3110,17 +3142,17 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
}
windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
if(windowoffs + length <= lzss_size(&rar->lzss)) {
if(windowoffs + length <= (size_t)lzss_size(&rar->lzss)) {
memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
length);
} else if (length <= lzss_size(&rar->lzss)) {
} else if (length <= (size_t)lzss_size(&rar->lzss)) {
firstpart = lzss_size(&rar->lzss) - windowoffs;
if (firstpart < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad RAR file data");
return (ARCHIVE_FATAL);
}
if (firstpart < length) {
if ((size_t)firstpart < length) {
memcpy(&rar->unp_buffer[rar->unp_offset],
&rar->lzss.window[windowoffs], firstpart);
memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
@ -3130,16 +3162,19 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
&rar->lzss.window[windowoffs], length);
}
} else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad RAR file data");
return (ARCHIVE_FATAL);
goto fatal;
}
rar->unp_offset += length;
rar->unp_offset += (unsigned int) length;
if (rar->unp_offset >= rar->unp_buffer_size)
*buffer = rar->unp_buffer;
else
*buffer = NULL;
return (ARCHIVE_OK);
fatal:
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad RAR file data");
return (ARCHIVE_FATAL);
}
static const void *
@ -3325,7 +3360,10 @@ create_filter(struct rar_program_code *prog, const uint8_t *globaldata, uint32_t
filter->globaldatalen = globaldatalen > PROGRAM_SYSTEM_GLOBAL_SIZE ? globaldatalen : PROGRAM_SYSTEM_GLOBAL_SIZE;
filter->globaldata = calloc(1, filter->globaldatalen);
if (!filter->globaldata)
{
free(filter);
return NULL;
}
if (globaldata)
memcpy(filter->globaldata, globaldata, globaldatalen);
if (registers)
@ -3352,7 +3390,7 @@ run_filters(struct archive_read *a)
if (filters == NULL || filter == NULL)
return (0);
start = filters->filterstart;
start = (size_t)filters->filterstart;
end = start + filter->blocklength;
filters->filterstart = INT64_MAX;
@ -3389,10 +3427,16 @@ run_filters(struct archive_read *a)
return 0;
}
if (filter->blocklength > VM_MEMORY_SIZE)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Bad RAR file data");
return 0;
}
ret = copy_from_lzss_window(a, filters->vm->memory, start, filter->blocklength);
if (ret != ARCHIVE_OK)
return 0;
if (!execute_filter(a, filter, filters->vm, rar->offset))
if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
return 0;
lastfilteraddress = filter->filteredblockaddress;
@ -3404,7 +3448,7 @@ run_filters(struct archive_read *a)
while ((filter = filters->stack) != NULL && (int64_t)filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength)
{
memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength);
if (!execute_filter(a, filter, filters->vm, rar->offset))
if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
return 0;
lastfilteraddress = filter->filteredblockaddress;
@ -3645,7 +3689,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
{
uint32_t currpos = (uint32_t)pos + i + 1;
int32_t address = (int32_t)vm_read_32(vm, i + 1);
if (address < 0 && currpos >= (uint32_t)-address)
if (address < 0 && currpos >= (~(uint32_t)address + 1))
vm_write_32(vm, i + 1, address + filesize);
else if (address >= 0 && (uint32_t)address < filesize)
vm_write_32(vm, i + 1, address - currpos);
@ -3668,7 +3712,7 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
uint8_t *src, *dst;
uint32_t i, j;
if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength)
if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength || blocklength < 3 || byteoffset > 2)
return 0;
src = &vm->memory[0];
@ -3678,6 +3722,13 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
uint8_t *prev = dst + i - stride;
for (j = i; j < blocklength; j += 3)
{
/*
* The src block should not overlap with the dst block.
* If so it would be better to consider this archive is broken.
*/
if (src >= dst)
return 0;
if (prev >= dst)
{
uint32_t delta1 = abs(prev[3] - prev[0]);

View file

@ -220,7 +220,7 @@ struct comp_state {
decompression. */
uint8_t* filtered_buf; /* Buffer used when applying filters. */
const uint8_t* block_buf; /* Buffer used when merging blocks. */
size_t window_mask; /* Convenience field; window_size - 1. */
ssize_t window_mask; /* Convenience field; window_size - 1. */
int64_t write_ptr; /* This amount of data has been unpacked
in the window buffer. */
int64_t last_write_ptr; /* This amount of data has been stored in
@ -361,6 +361,7 @@ static int verify_global_checksums(struct archive_read* a);
static int rar5_read_data_skip(struct archive_read *a);
static int push_data_ready(struct archive_read* a, struct rar5* rar,
const uint8_t* buf, size_t size, int64_t offset);
static void clear_data_ready_stack(struct rar5* rar);
/* CDE_xxx = Circular Double Ended (Queue) return values. */
enum CDE_RETURN_VALUES {
@ -505,7 +506,7 @@ static inline struct rar5* get_context(struct archive_read* a) {
}
/* Convenience functions used by filter implementations. */
static void circular_memcpy(uint8_t* dst, uint8_t* window, const uint64_t mask,
static void circular_memcpy(uint8_t* dst, uint8_t* window, const ssize_t mask,
int64_t start, int64_t end)
{
if((start & mask) > (end & mask)) {
@ -652,6 +653,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
int ret;
struct rar5* rar = get_context(a);
clear_data_ready_stack(rar);
free(rar->cstate.filtered_buf);
rar->cstate.filtered_buf = malloc(flt->block_length);
@ -709,7 +711,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
static void push_data(struct archive_read* a, struct rar5* rar,
const uint8_t* buf, int64_t idx_begin, int64_t idx_end)
{
const uint64_t wmask = rar->cstate.window_mask;
const ssize_t wmask = rar->cstate.window_mask;
const ssize_t solid_write_ptr = (rar->cstate.solid_offset +
rar->cstate.last_write_ptr) & wmask;
@ -1246,7 +1248,7 @@ static int process_main_locator_extra_block(struct archive_read* a,
}
static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
ssize_t* extra_data_size)
int64_t* extra_data_size)
{
size_t hash_type = 0;
size_t value_len;
@ -1296,7 +1298,7 @@ static uint64_t time_win_to_unix(uint64_t win_time) {
}
static int parse_htime_item(struct archive_read* a, char unix_time,
uint64_t* where, ssize_t* extra_data_size)
uint64_t* where, int64_t* extra_data_size)
{
if(unix_time) {
uint32_t time_val;
@ -1318,7 +1320,7 @@ static int parse_htime_item(struct archive_read* a, char unix_time,
}
static int parse_file_extra_version(struct archive_read* a,
struct archive_entry* e, ssize_t* extra_data_size)
struct archive_entry* e, int64_t* extra_data_size)
{
size_t flags = 0;
size_t version = 0;
@ -1372,7 +1374,7 @@ static int parse_file_extra_version(struct archive_read* a,
}
static int parse_file_extra_htime(struct archive_read* a,
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
struct archive_entry* e, struct rar5* rar, int64_t* extra_data_size)
{
char unix_time = 0;
size_t flags = 0;
@ -1425,7 +1427,7 @@ static int parse_file_extra_htime(struct archive_read* a,
}
static int parse_file_extra_redir(struct archive_read* a,
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
struct archive_entry* e, struct rar5* rar, int64_t* extra_data_size)
{
uint64_t value_size = 0;
size_t target_size = 0;
@ -1448,9 +1450,6 @@ static int parse_file_extra_redir(struct archive_read* a,
return ARCHIVE_EOF;
*extra_data_size -= target_size + 1;
if(!read_ahead(a, target_size, &p))
return ARCHIVE_EOF;
if(target_size > (MAX_NAME_IN_CHARS - 1)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Link target is too long");
@ -1463,6 +1462,9 @@ static int parse_file_extra_redir(struct archive_read* a,
return ARCHIVE_FATAL;
}
if(!read_ahead(a, target_size, &p))
return ARCHIVE_EOF;
memcpy(target_utf8_buf, p, target_size);
target_utf8_buf[target_size] = 0;
@ -1496,7 +1498,7 @@ static int parse_file_extra_redir(struct archive_read* a,
}
static int parse_file_extra_owner(struct archive_read* a,
struct archive_entry* e, ssize_t* extra_data_size)
struct archive_entry* e, int64_t* extra_data_size)
{
uint64_t flags = 0;
uint64_t value_size = 0;
@ -1576,15 +1578,15 @@ static int parse_file_extra_owner(struct archive_read* a,
}
static int process_head_file_extra(struct archive_read* a,
struct archive_entry* e, struct rar5* rar, ssize_t extra_data_size)
struct archive_entry* e, struct rar5* rar, int64_t extra_data_size)
{
size_t extra_field_size;
size_t extra_field_id = 0;
uint64_t extra_field_size;
uint64_t extra_field_id = 0;
int ret = ARCHIVE_FATAL;
size_t var_size;
uint64_t var_size;
while(extra_data_size > 0) {
if(!read_var_sized(a, &extra_field_size, &var_size))
if(!read_var(a, &extra_field_size, &var_size))
return ARCHIVE_EOF;
extra_data_size -= var_size;
@ -1592,7 +1594,7 @@ static int process_head_file_extra(struct archive_read* a,
return ARCHIVE_EOF;
}
if(!read_var_sized(a, &extra_field_id, &var_size))
if(!read_var(a, &extra_field_id, &var_size))
return ARCHIVE_EOF;
extra_data_size -= var_size;
@ -1642,7 +1644,7 @@ static int process_head_file_extra(struct archive_read* a,
static int process_head_file(struct archive_read* a, struct rar5* rar,
struct archive_entry* entry, size_t block_flags)
{
ssize_t extra_data_size = 0;
int64_t extra_data_size = 0;
size_t data_size = 0;
size_t file_flags = 0;
size_t file_attr = 0;
@ -1682,12 +1684,12 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
}
if(block_flags & HFL_EXTRA_DATA) {
size_t edata_size = 0;
if(!read_var_sized(a, &edata_size, NULL))
uint64_t edata_size = 0;
if(!read_var(a, &edata_size, NULL))
return ARCHIVE_EOF;
/* Intentional type cast from unsigned to signed. */
extra_data_size = (ssize_t) edata_size;
extra_data_size = (int64_t) edata_size;
}
if(block_flags & HFL_DATA) {
@ -1780,11 +1782,18 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
if(rar->cstate.window_size < (ssize_t) window_size &&
rar->cstate.window_buf)
{
/* The `data_ready` stack contains pointers to the `window_buf` or
* `filtered_buf` buffers. Since we're about to reallocate the first
* buffer, some of those pointers could become invalid. Therefore, we
* need to dispose of all entries from the stack before attempting the
* realloc. */
clear_data_ready_stack(rar);
/* If window_buf has been allocated before, reallocate it, so
* that its size will match new window_size. */
uint8_t* new_window_buf =
realloc(rar->cstate.window_buf, window_size);
realloc(rar->cstate.window_buf, (size_t) window_size);
if(!new_window_buf) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
@ -1876,9 +1885,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
if(!read_var_sized(a, &name_size, NULL))
return ARCHIVE_EOF;
if(!read_ahead(a, name_size, &p))
return ARCHIVE_EOF;
if(name_size > (MAX_NAME_IN_CHARS - 1)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Filename is too long");
@ -1893,6 +1899,9 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
return ARCHIVE_FATAL;
}
if(!read_ahead(a, name_size, &p))
return ARCHIVE_EOF;
memcpy(name_utf8_buf, p, name_size);
name_utf8_buf[name_size] = 0;
if(ARCHIVE_OK != consume(a, name_size)) {
@ -1980,7 +1989,7 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
struct archive_entry* entry, size_t block_flags)
{
int ret;
size_t extra_data_size = 0;
uint64_t extra_data_size = 0;
size_t extra_field_size = 0;
size_t extra_field_id = 0;
size_t archive_flags = 0;
@ -2002,7 +2011,7 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
(void) entry;
if(block_flags & HFL_EXTRA_DATA) {
if(!read_var_sized(a, &extra_data_size, NULL))
if(!read_var(a, &extra_data_size, NULL))
return ARCHIVE_EOF;
} else {
extra_data_size = 0;
@ -2229,10 +2238,12 @@ static int process_base_block(struct archive_read* a,
/* Verify the CRC32 of the header data. */
computed_crc = (uint32_t) crc32(0, p, (int) hdr_size);
if(computed_crc != hdr_crc) {
#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Header CRC error");
return ARCHIVE_FATAL;
#endif
}
/* If the checksum is OK, we proceed with parsing. */
@ -2453,6 +2464,8 @@ static void init_unpack(struct rar5* rar) {
rar->cstate.filtered_buf = NULL;
}
clear_data_ready_stack(rar);
rar->cstate.write_ptr = 0;
rar->cstate.last_write_ptr = 0;
@ -2983,7 +2996,7 @@ static int decode_code_length(struct archive_read* a, struct rar5* rar,
static int copy_string(struct archive_read* a, int len, int dist) {
struct rar5* rar = get_context(a);
const uint64_t cmask = rar->cstate.window_mask;
const ssize_t cmask = rar->cstate.window_mask;
const uint64_t write_ptr = rar->cstate.write_ptr +
rar->cstate.solid_offset;
int i;
@ -3627,6 +3640,10 @@ static int use_data(struct rar5* rar, const void** buf, size_t* size,
return ARCHIVE_RETRY;
}
static void clear_data_ready_stack(struct rar5* rar) {
memset(&rar->cstate.dready, 0, sizeof(rar->cstate.dready));
}
/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
* FIFO stack. Those values will be popped from this stack by the `use_data`
* function. */
@ -4185,6 +4202,7 @@ static int rar5_cleanup(struct archive_read *a) {
free(rar->cstate.window_buf);
free(rar->cstate.filtered_buf);
clear_data_ready_stack(rar);
free(rar->vol.push_buf);

File diff suppressed because it is too large Load diff

View file

@ -416,7 +416,7 @@ static void unknowntag_end(struct xar *, const char *);
static int xml_start(struct archive_read *,
const char *, struct xmlattr_list *);
static void xml_end(void *, const char *);
static void xml_data(void *, const char *, int);
static void xml_data(void *, const char *, size_t);
static int xml_parse_file_flags(struct xar *, const char *);
static int xml_parse_file_ext2(struct xar *, const char *);
#if defined(HAVE_LIBXML_XMLREADER_H)
@ -1242,7 +1242,7 @@ heap_add_entry(struct archive_read *a,
return (ARCHIVE_FATAL);
}
new_pending_files = (struct xar_file **)
malloc(new_size * sizeof(new_pending_files[0]));
calloc(new_size, sizeof(new_pending_files[0]));
if (new_pending_files == NULL) {
archive_set_error(&a->archive,
ENOMEM, "Out of memory");
@ -1616,9 +1616,9 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
switch (xar->rd_encoding) {
case GZIP:
xar->stream.next_in = (Bytef *)(uintptr_t)b;
xar->stream.avail_in = avail_in;
xar->stream.avail_in = (uInt)avail_in;
xar->stream.next_out = (unsigned char *)outbuff;
xar->stream.avail_out = avail_out;
xar->stream.avail_out = (uInt)avail_out;
r = inflate(&(xar->stream), 0);
switch (r) {
case Z_OK: /* Decompressor made some progress.*/
@ -1635,9 +1635,9 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
case BZIP2:
xar->bzstream.next_in = (char *)(uintptr_t)b;
xar->bzstream.avail_in = avail_in;
xar->bzstream.avail_in = (unsigned int)avail_in;
xar->bzstream.next_out = (char *)outbuff;
xar->bzstream.avail_out = avail_out;
xar->bzstream.avail_out = (unsigned int)avail_out;
r = BZ2_bzDecompress(&(xar->bzstream));
switch (r) {
case BZ_STREAM_END: /* Found end of stream. */
@ -2674,7 +2674,7 @@ is_string(const char *known, const char *data, size_t len)
}
static void
xml_data(void *userData, const char *s, int len)
xml_data(void *userData, const char *s, size_t len)
{
struct archive_read *a;
struct xar *xar;
@ -2707,6 +2707,9 @@ xml_data(void *userData, const char *s, int len)
switch (xar->xmlsts) {
case FILE_NAME:
if (xar->file->has & HAS_PATHNAME)
break;
if (xar->file->parent != NULL) {
archive_string_concat(&(xar->file->pathname),
&(xar->file->parent->pathname));
@ -3190,8 +3193,11 @@ xml2_read_toc(struct archive_read *a)
if (r == ARCHIVE_OK)
r = xml_start(a, name, &list);
xmlattr_cleanup(&list);
if (r != ARCHIVE_OK)
if (r != ARCHIVE_OK) {
xmlFreeTextReader(reader);
xmlCleanupParser();
return (r);
}
if (empty)
xml_end(a, name);
break;
@ -3280,7 +3286,7 @@ expat_data_cb(void *userData, const XML_Char *s, int len)
{
struct expat_userData *ud = (struct expat_userData *)userData;
xml_data(ud->archive, s, len);
xml_data(ud->archive, s, (size_t)len);
}
static int
@ -3316,14 +3322,16 @@ expat_read_toc(struct archive_read *a)
d = NULL;
r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
if (r != ARCHIVE_OK)
if (r != ARCHIVE_OK) {
XML_ParserFree(parser);
return (r);
}
xar->toc_remaining -= used;
xar->offset += used;
xar->toc_total += outbytes;
PRINT_TOC(d, outbytes);
xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
xr = XML_Parse(parser, d, (int)outbytes, xar->toc_remaining == 0);
__archive_read_consume(a, used);
if (xr == XML_STATUS_ERROR) {
XML_ParserFree(parser);

View file

@ -1924,7 +1924,7 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
zip->zipx_lzma_stream.next_in = compressed_buf;
zip->zipx_lzma_stream.avail_in = in_bytes;
zip->zipx_lzma_stream.total_in = 0;
@ -1966,14 +1966,14 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
break;
}
to_consume = zip->zipx_lzma_stream.total_in;
to_consume = (ssize_t)zip->zipx_lzma_stream.total_in;
__archive_read_consume(a, to_consume);
zip->entry_bytes_remaining -= to_consume;
zip->entry_compressed_bytes_read += to_consume;
zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
*size = zip->zipx_lzma_stream.total_out;
*size = (size_t)zip->zipx_lzma_stream.total_out;
*buff = zip->uncompressed_buffer;
return (ARCHIVE_OK);
@ -2014,7 +2014,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
}
/* Set decompressor parameters. */
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
zip->zipx_lzma_stream.next_in = compressed_buf;
zip->zipx_lzma_stream.avail_in = in_bytes;
@ -2024,7 +2024,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
/* These lzma_alone streams lack end of stream marker, so let's
* make sure the unpacker won't try to unpack more than it's
* supposed to. */
zipmin((int64_t) zip->uncompressed_buffer_size,
(size_t)zipmin((int64_t) zip->uncompressed_buffer_size,
zip->entry->uncompressed_size -
zip->entry_uncompressed_bytes_read);
zip->zipx_lzma_stream.total_out = 0;
@ -2061,7 +2061,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
to_consume = zip->zipx_lzma_stream.total_in;
to_consume = (ssize_t)zip->zipx_lzma_stream.total_in;
/* Update pointers. */
__archive_read_consume(a, to_consume);
@ -2082,7 +2082,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
}
/* Return values. */
*size = zip->zipx_lzma_stream.total_out;
*size = (size_t)zip->zipx_lzma_stream.total_out;
*buff = zip->uncompressed_buffer;
/* If we're here, then we're good! */
@ -2331,7 +2331,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
if(in_bytes < 1) {
/* libbz2 doesn't complain when caller feeds avail_in == 0.
* It will actually return success in this case, which is
@ -2394,7 +2394,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
zip->entry_uncompressed_bytes_read += total_out;
/* Give libarchive its due. */
*size = total_out;
*size = (size_t)total_out;
*buff = zip->uncompressed_buffer;
return ARCHIVE_OK;
@ -2478,7 +2478,7 @@ zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
if(in_bytes < 1) {
/* zstd doesn't complain when caller feeds avail_in == 0.
* It will actually return success in this case, which is
@ -2524,7 +2524,7 @@ zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
zip->entry_uncompressed_bytes_read += total_out;
/* Give libarchive its due. */
*size = total_out;
*size = (size_t)total_out;
*buff = zip->uncompressed_buffer;
return ARCHIVE_OK;
@ -3680,7 +3680,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset)
if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
return 0;
/* Central directory can't extend beyond start of EOCD record. */
if (cd_offset + cd_size > current_offset)
if ((int64_t)cd_offset + cd_size > current_offset)
return 0;
/* Save the central directory location for later use. */

View file

@ -3874,6 +3874,30 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
}
*p = NULL;
#if defined(_WIN32) && !defined(__CYGWIN__)
/*
* On Windows, first try converting from WCS because (1) there's no
* guarantee that the conversion to MBS will succeed, e.g. when using
* CP_ACP, and (2) that's more efficient than converting to MBS, just to
* convert back to WCS again before finally converting to UTF-8
*/
if ((aes->aes_set & AES_SET_WCS) != 0) {
sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
if (sc == NULL)
return (-1);/* Couldn't allocate memory for sc. */
archive_string_empty(&(aes->aes_utf8));
r = archive_string_append_from_wcs_in_codepage(&(aes->aes_utf8),
aes->aes_wcs.s, aes->aes_wcs.length, sc);
if (a == NULL)
free_sconv_object(sc);
if (r == 0) {
aes->aes_set |= AES_SET_UTF8;
*p = aes->aes_utf8.s;
return (0);/* success. */
} else
return (-1);/* failure. */
}
#endif
/* Try converting WCS to MBS first if MBS does not exist yet. */
if ((aes->aes_set & AES_SET_MBS) == 0) {
const char *pm; /* unused */
@ -3958,6 +3982,32 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
}
*wp = NULL;
#if defined(_WIN32) && !defined(__CYGWIN__)
/*
* On Windows, prefer converting from UTF-8 directly to WCS because:
* (1) there's no guarantee that the string can be represented in MBS (e.g.
* with CP_ACP), and (2) in order to convert from UTF-8 to MBS, we're going
* to need to convert from UTF-8 to WCS anyway and its wasteful to throw
* away that intermediate result
*/
if (aes->aes_set & AES_SET_UTF8) {
struct archive_string_conv *sc;
sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
if (sc != NULL) {
archive_wstring_empty((&aes->aes_wcs));
r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
aes->aes_utf8.s, aes->aes_utf8.length, sc);
if (a == NULL)
free_sconv_object(sc);
if (r == 0) {
aes->aes_set |= AES_SET_WCS;
*wp = aes->aes_wcs.s;
return (0);
}
}
}
#endif
/* Try converting UTF8 to MBS first if MBS does not exist yet. */
if ((aes->aes_set & AES_SET_MBS) == 0) {
const char *p; /* unused */
@ -4211,21 +4261,31 @@ archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */
/* Try converting UTF-8 to MBS, return false on failure. */
sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
if (sc == NULL)
return (-1);/* Couldn't allocate memory for sc. */
r = archive_strcpy_l(&(aes->aes_mbs), utf8, sc);
#if defined(_WIN32) && !defined(__CYGWIN__)
/* On failure, make an effort to convert UTF8 to WCS as the active code page
* may not be able to represent all characters in the string */
if (r != 0) {
if (archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
aes->aes_utf8.s, aes->aes_utf8.length, sc) == 0)
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS;
}
#endif
/* On Windows, there's no good way to convert from UTF8 -> MBS directly, so
* prefer to first convert to WCS as (1) it's wasteful to throw away the
* intermediate result, and (2) WCS will still be set even if we fail to
* convert to MBS (e.g. with ACP that can't represent the characters) */
r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
aes->aes_utf8.s, aes->aes_utf8.length, sc);
if (a == NULL)
free_sconv_object(sc);
if (r != 0)
return (-1); /* This will guarantee we can't convert to MBS */
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS; /* Both UTF8 and WCS set. */
/* Try converting WCS to MBS, return false on failure. */
if (archive_string_append_from_wcs(&(aes->aes_mbs), aes->aes_wcs.s,
aes->aes_wcs.length))
return (-1);
#else
/* Try converting UTF-8 to MBS, return false on failure. */
r = archive_strcpy_l(&(aes->aes_mbs), utf8, sc);
if (a == NULL)
free_sconv_object(sc);
@ -4237,8 +4297,10 @@ archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
if (archive_wstring_append_from_mbs(&(aes->aes_wcs), aes->aes_mbs.s,
aes->aes_mbs.length))
return (-1);
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
#endif
/* All conversions succeeded. */
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
return (0);
}

View file

@ -280,7 +280,8 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
strlen(tmpdir)) < 0)
goto exit_tmpfile;
if (temp_name.s[temp_name.length-1] != L'/')
if (temp_name.length == 0 ||
temp_name.s[temp_name.length-1] != L'/')
archive_wstrappend_wchar(&temp_name, L'/');
}
@ -454,7 +455,7 @@ get_tempdir(struct archive_string *temppath)
tmp = "/tmp";
#endif
archive_strcpy(temppath, tmp);
if (temppath->s[temppath->length-1] != '/')
if (temppath->length == 0 || temppath->s[temppath->length-1] != '/')
archive_strappend_char(temppath, '/');
return (ARCHIVE_OK);
}
@ -477,7 +478,8 @@ __archive_mktemp(const char *tmpdir)
goto exit_tmpfile;
} else {
archive_strcpy(&temp_name, tmpdir);
if (temp_name.s[temp_name.length-1] != '/')
if (temp_name.length == 0 ||
temp_name.s[temp_name.length-1] != '/')
archive_strappend_char(&temp_name, '/');
}
#ifdef O_TMPFILE
@ -538,7 +540,7 @@ __archive_mktempx(const char *tmpdir, char *template)
goto exit_tmpfile;
} else
archive_strcpy(&temp_name, tmpdir);
if (temp_name.s[temp_name.length-1] == '/') {
if (temp_name.length > 0 && temp_name.s[temp_name.length-1] == '/') {
temp_name.s[temp_name.length-1] = '\0';
temp_name.length --;
}

View file

@ -292,12 +292,17 @@ typedef int mbstate_t;
size_t wcrtomb(char *, wchar_t, mbstate_t *);
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
#if !WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) && NTDDI_VERSION < NTDDI_WIN10_VB
// not supported in UWP SDK before 20H1
#define GetVolumePathNameW(f, v, c) (0)
#elif defined(_MSC_VER) && _MSC_VER < 1300
WINBASEAPI BOOL WINAPI GetVolumePathNameW(
LPCWSTR lpszFileName,
LPWSTR lpszVolumePathName,
DWORD cchBufferLength
);
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
LARGE_INTEGER FileOffset;

View file

@ -132,12 +132,17 @@ archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
struct archive_write *a = (struct archive_write *)_a;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
if (bytes_per_block < 0) {
// Do nothing if the bytes_per_block is negative
return 0;
}
a->bytes_per_block = bytes_per_block;
return (ARCHIVE_OK);
}
/*
* Get the current block size. -1 if it has never been set.
* Get the current block size.
*/
int
archive_write_get_bytes_per_block(struct archive *_a)
@ -145,6 +150,10 @@ archive_write_get_bytes_per_block(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
if (a->bytes_per_block < 0) {
// Don't return a negative value
return 1;
}
return (a->bytes_per_block);
}

View file

@ -83,7 +83,7 @@ archive_write_add_filter_b64encode(struct archive *_a)
struct private_b64encode *state;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_add_filter_uu");
ARCHIVE_STATE_NEW, "archive_write_add_filter_b64encode");
state = (struct private_b64encode *)calloc(1, sizeof(*state));
if (state == NULL) {
@ -149,7 +149,7 @@ archive_filter_b64encode_open(struct archive_write_filter *f)
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
/* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)

View file

@ -168,7 +168,7 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
/* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)

View file

@ -158,7 +158,7 @@ archive_compressor_compress_open(struct archive_write_filter *f)
}
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
/* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)

View file

@ -310,7 +310,7 @@ archive_compressor_xz_open(struct archive_write_filter *f)
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
/* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)

View file

@ -4196,7 +4196,7 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
}
for (xattr_i = 0; xattr_i < xattr_size;
xattr_i += strlen(xattr_names + xattr_i) + 1) {
char *xattr_val_saved;
char *p;
ssize_t s;
int f;
@ -4207,15 +4207,14 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
ret = ARCHIVE_WARN;
goto exit_xattr;
}
xattr_val_saved = xattr_val;
xattr_val = realloc(xattr_val, s);
if (xattr_val == NULL) {
p = realloc(xattr_val, s);
if (p == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Failed to get metadata(xattr)");
ret = ARCHIVE_WARN;
free(xattr_val_saved);
goto exit_xattr;
}
xattr_val = p;
s = fgetxattr(tmpfd, xattr_names + xattr_i, xattr_val, s, 0, 0);
if (s == -1) {
archive_set_error(&a->archive, errno,
@ -4361,8 +4360,7 @@ set_mac_metadata(struct archive_write_disk *a, const char *pathname,
* silly dance of writing the data to disk just so that
* copyfile() can read it back in again. */
archive_string_init(&tmp);
archive_strcpy(&tmp, pathname);
archive_strcat(&tmp, ".XXXXXX");
archive_strcpy(&tmp, "tar.mmd.XXXXXX");
fd = mkstemp(tmp.s);
if (fd < 0) {

View file

@ -577,6 +577,9 @@ archive_write_binary_close(struct archive_write *a)
struct archive_entry *trailer;
trailer = archive_entry_new2(NULL);
if (trailer == NULL) {
return ARCHIVE_FATAL;
}
/* nlink = 1 here for GNU cpio compat. */
archive_entry_set_nlink(trailer, 1);
archive_entry_set_size(trailer, 0);

View file

@ -467,6 +467,9 @@ archive_write_odc_close(struct archive_write *a)
struct archive_entry *trailer;
trailer = archive_entry_new2(NULL);
if (trailer == NULL) {
return ARCHIVE_FATAL;
}
/* nlink = 1 here for GNU cpio compat. */
archive_entry_set_nlink(trailer, 1);
archive_entry_set_size(trailer, 0);

View file

@ -296,7 +296,7 @@ archive_write_gnutar_header(struct archive_write *a,
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
!(archive_entry_filetype(entry) == AE_IFREG))
archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
if (AE_IFDIR == archive_entry_filetype(entry)) {
@ -523,7 +523,7 @@ archive_write_gnutar_header(struct archive_write *a,
goto exit_write_header;
}
if (archive_entry_hardlink(entry) != NULL) {
if (archive_entry_hardlink_is_set(entry)) {
tartype = '1';
} else
switch (archive_entry_filetype(entry)) {

View file

@ -2237,7 +2237,7 @@ set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
int onepad;
if (s == NULL)
s = "";
s = "\0\0";
if (l & 0x01) {
onepad = 1;
l &= ~1;

View file

@ -608,7 +608,15 @@ archive_write_pax_header(struct archive_write *a,
const time_t ustar_max_mtime = get_ustar_max_mtime();
/* Sanity check. */
#if defined(_WIN32) && !defined(__CYGWIN__)
/* NOTE: If the caller supplied a pathname that fails WCS conversion (e.g.
* if it is invalid UTF-8), we are expected to return ARCHIVE_WARN later on
* in execution, hence the check for both pointers */
if ((archive_entry_pathname_w(entry_original) == NULL) &&
(archive_entry_pathname(entry_original) == NULL)) {
#else
if (archive_entry_pathname(entry_original) == NULL) {
#endif
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't record entry in tar file without pathname");
return (ARCHIVE_FAILED);
@ -1032,6 +1040,14 @@ archive_write_pax_header(struct archive_write *a,
archive_entry_set_symlink(entry_main,
"././@LongSymLink");
}
else {
/* Otherwise, has non-ASCII characters; update the paths to
* however they got decoded above */
if (hardlink != NULL)
archive_entry_set_hardlink(entry_main, linkpath);
else
archive_entry_set_symlink(entry_main, linkpath);
}
need_extension = 1;
}
}

View file

@ -209,6 +209,10 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
if (archive_entry_filetype(entry) != AE_IFDIR) {
/* Try to create the dir. */
p = strdup(name);
if (p == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
pp = strrchr(p, '/');
/* If there is a / character, try to create the dir. */
if (pp != NULL) {
@ -291,6 +295,10 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
free(shar->last_dir);
shar->last_dir = strdup(name);
if (shar->last_dir == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
/* Trim a trailing '/'. */
pp = strrchr(shar->last_dir, '/');
if (pp != NULL && pp[1] == '\0')

View file

@ -254,7 +254,11 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
sconv = ustar->opt_sconv;
/* Sanity check. */
#if defined(_WIN32) && !defined(__CYGWIN__)
if (archive_entry_pathname_w(entry) == NULL) {
#else
if (archive_entry_pathname(entry) == NULL) {
#endif
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't record entry in tar file without pathname");
return (ARCHIVE_FAILED);
@ -263,7 +267,7 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
!(archive_entry_filetype(entry) == AE_IFREG))
archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
if (AE_IFDIR == archive_entry_filetype(entry)) {

View file

@ -241,7 +241,7 @@ archive_write_v7tar_header(struct archive_write *a, struct archive_entry *entry)
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
!(archive_entry_filetype(entry) == AE_IFREG))
archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
if (AE_IFDIR == archive_entry_filetype(entry)) {

View file

@ -796,7 +796,7 @@ xar_finish_entry(struct archive_write *a)
if (w > 0)
xar->bytes_remaining -= w;
else
return (w);
return ((int)w);
}
file = xar->cur_file;
checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
@ -1163,7 +1163,7 @@ make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
/*
* Make a file name entry, "<name>".
*/
l = ll = archive_strlen(&(file->basename));
l = ll = (int)archive_strlen(&(file->basename));
tmp = malloc(l);
if (tmp == NULL) {
archive_set_error(&a->archive, ENOMEM,
@ -1189,7 +1189,7 @@ make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
return (ARCHIVE_FATAL);
}
r = xmlTextWriterWriteBase64(writer, file->basename.s,
0, archive_strlen(&(file->basename)));
0, (int)archive_strlen(&(file->basename)));
if (r < 0) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
@ -2231,10 +2231,10 @@ get_path_component(char *name, int n, const char *fn)
p = strchr(fn, '/');
if (p == NULL) {
if ((l = strlen(fn)) == 0)
if ((l = (int)strlen(fn)) == 0)
return (0);
} else
l = p - fn;
l = (int)(p - fn);
if (l > n -1)
return (-1);
memcpy(name, fn, l);
@ -2651,10 +2651,10 @@ compression_init_encoder_gzip(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->avail_in = (uInt)lastrm->avail_in;
strm->total_in = (uLong)lastrm->total_in;
strm->next_out = lastrm->next_out;
strm->avail_out = lastrm->avail_out;
strm->avail_out = (uInt)lastrm->avail_out;
strm->total_out = (uLong)lastrm->total_out;
if (deflateInit2(strm, level, Z_DEFLATED,
(withheader)?15:-15,
@ -2684,10 +2684,10 @@ compression_code_gzip(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->avail_in = (uInt)lastrm->avail_in;
strm->total_in = (uLong)lastrm->total_in;
strm->next_out = lastrm->next_out;
strm->avail_out = lastrm->avail_out;
strm->avail_out = (uInt)lastrm->avail_out;
strm->total_out = (uLong)lastrm->total_out;
r = deflate(strm,
(action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
@ -2748,11 +2748,11 @@ compression_init_encoder_bzip2(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->avail_in = (unsigned int)lastrm->avail_in;
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
strm->next_out = (char *)lastrm->next_out;
strm->avail_out = lastrm->avail_out;
strm->avail_out = (unsigned int)lastrm->avail_out;
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
@ -2781,11 +2781,11 @@ compression_code_bzip2(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->avail_in = (unsigned int)lastrm->avail_in;
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
strm->next_out = (char *)lastrm->next_out;
strm->avail_out = lastrm->avail_out;
strm->avail_out = (unsigned int)lastrm->avail_out;
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
r = BZ2_bzCompress(strm,

View file

@ -609,7 +609,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
const char *p;
size_t len;
if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
if (archive_entry_pathname_l(zip->entry, &p, &len, sconv) != 0) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Pathname");
@ -618,7 +618,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Can't translate Pathname '%s' to %s",
archive_entry_pathname(entry),
archive_entry_pathname(zip->entry),
archive_string_conversion_charset_name(sconv));
ret2 = ARCHIVE_WARN;
}
@ -631,7 +631,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
* for filename.
*/
if (type == AE_IFLNK) {
if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
if (archive_entry_symlink_l(zip->entry, &p, &len, sconv)) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory "
@ -906,7 +906,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
archive_le32enc(e, (uint32_t)archive_entry_ctime(entry));
e += 4;
}
archive_le16enc(ut + 2, e - ut - 4);
archive_le16enc(ut + 2, (uint16_t)(e - ut - 4));
}
/*

View file

@ -203,7 +203,6 @@
#define HAVE_SYS_MOUNT_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_POLL_H 1
#define HAVE_SYS_QUEUE_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_STATVFS_H 1
#define HAVE_SYS_STAT_H 1

View file

@ -15,6 +15,7 @@ IF(ENABLE_TEST)
test_acl_platform_posix1e.c
test_acl_posix1e.c
test_acl_text.c
test_ar_mode.c
test_archive_api_feature.c
test_archive_clear_error.c
test_archive_cmdline.c
@ -24,6 +25,7 @@ IF(ENABLE_TEST)
test_archive_match_path.c
test_archive_match_time.c
test_archive_pathmatch.c
test_archive_read.c
test_archive_read_add_passphrase.c
test_archive_read_close_twice.c
test_archive_read_close_twice_open_fd.c
@ -130,6 +132,7 @@ IF(ENABLE_TEST)
test_read_format_gtar_lzma.c
test_read_format_gtar_sparse.c
test_read_format_gtar_sparse_skip_entry.c
test_read_format_huge_rpm.c
test_read_format_iso_Z.c
test_read_format_iso_multi_extent.c
test_read_format_iso_xorriso.c
@ -164,6 +167,7 @@ IF(ENABLE_TEST)
test_read_format_tar_empty_pax.c
test_read_format_tar_filename.c
test_read_format_tar_invalid_pax_size.c
test_read_format_tar_pax_large_attr.c
test_read_format_tbz.c
test_read_format_tgz.c
test_read_format_tlz.c
@ -287,6 +291,7 @@ IF(ENABLE_TEST)
test_write_format_zip_file_zip64.c
test_write_format_zip_large.c
test_write_format_zip_stream.c
test_write_format_zip_windows_path.c
test_write_format_zip_zip64.c
test_write_open_memory.c
test_write_read_format_zip.c

View file

@ -0,0 +1,40 @@
/*-SPDX-License-Identifier: BSD-2-Clause
* Copyright (C) 2024 by наб <nabijaczleweli@nabijaczleweli.xyz>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
static const char data[] = "!<arch>\narchivemount.1/ 0 0 0 644 0 `\n";
DEFINE_TEST(test_ar_mode)
{
struct archive * ar = archive_read_new();
assertEqualInt(archive_read_support_format_all(ar), ARCHIVE_OK);
assertEqualInt(archive_read_open_memory(ar, data, sizeof(data) - 1), ARCHIVE_OK);
struct archive_entry * entry;
assertEqualIntA(ar, archive_read_next_header(ar, &entry), ARCHIVE_OK);
assertEqualIntA(ar, archive_entry_mode(entry), S_IFREG | 0644);
archive_read_free(ar);
}

View file

@ -316,15 +316,14 @@ test_newer_mtime_than_file_mbs(void)
static void
test_newer_ctime_than_file_mbs(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#else
struct archive *a;
struct archive_entry *ae;
struct archive *m;
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#endif
if (!assert((m = archive_match_new()) != NULL))
return;
if (!assert((ae = archive_entry_new()) != NULL)) {
@ -373,6 +372,7 @@ test_newer_ctime_than_file_mbs(void)
archive_read_free(a);
archive_entry_free(ae);
archive_match_free(m);
#endif
}
static void
@ -435,15 +435,14 @@ test_newer_mtime_than_file_wcs(void)
static void
test_newer_ctime_than_file_wcs(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#else
struct archive *a;
struct archive_entry *ae;
struct archive *m;
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#endif
if (!assert((m = archive_match_new()) != NULL))
return;
if (!assert((ae = archive_entry_new()) != NULL)) {
@ -493,6 +492,7 @@ test_newer_ctime_than_file_wcs(void)
archive_read_free(a);
archive_entry_free(ae);
archive_match_free(m);
#endif
}
static void
@ -787,15 +787,14 @@ test_older_mtime_than_file_mbs(void)
static void
test_older_ctime_than_file_mbs(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#else
struct archive *a;
struct archive_entry *ae;
struct archive *m;
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#endif
if (!assert((m = archive_match_new()) != NULL))
return;
if (!assert((ae = archive_entry_new()) != NULL)) {
@ -845,6 +844,7 @@ test_older_ctime_than_file_mbs(void)
archive_read_free(a);
archive_entry_free(ae);
archive_match_free(m);
#endif
}
static void
@ -907,15 +907,14 @@ test_older_mtime_than_file_wcs(void)
static void
test_older_ctime_than_file_wcs(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#else
struct archive *a;
struct archive_entry *ae;
struct archive *m;
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#endif
if (!assert((m = archive_match_new()) != NULL))
return;
if (!assert((ae = archive_entry_new()) != NULL)) {
@ -965,6 +964,7 @@ test_older_ctime_than_file_wcs(void)
archive_read_free(a);
archive_entry_free(ae);
archive_match_free(m);
#endif
}
static void
@ -1088,15 +1088,14 @@ test_mtime_between_files_wcs(void)
static void
test_ctime_between_files_mbs(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#else
struct archive *a;
struct archive_entry *ae;
struct archive *m;
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#endif
if (!assert((m = archive_match_new()) != NULL))
return;
if (!assert((ae = archive_entry_new()) != NULL)) {
@ -1147,20 +1146,20 @@ test_ctime_between_files_mbs(void)
archive_read_free(a);
archive_entry_free(ae);
archive_match_free(m);
#endif
}
static void
test_ctime_between_files_wcs(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#else
struct archive *a;
struct archive_entry *ae;
struct archive *m;
#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("Can't set ctime on Windows");
return;
#endif
if (!assert((m = archive_match_new()) != NULL))
return;
if (!assert((ae = archive_entry_new()) != NULL)) {
@ -1211,6 +1210,7 @@ test_ctime_between_files_wcs(void)
archive_read_free(a);
archive_entry_free(ae);
archive_match_free(m);
#endif
}
static void

View file

@ -0,0 +1,63 @@
/*-
* Copyright (c) 2024 Tobias Stoeckmann
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
#define __LIBARCHIVE_TEST
#include "archive_read_private.h"
static char buf[1024];
DEFINE_TEST(test_archive_read_ahead_eof)
{
struct archive *a;
struct archive_read *ar;
ssize_t avail;
/* prepare a reader of raw in-memory data */
assert((a = archive_read_new()) != NULL);
ar = (struct archive_read *)a;
assertA(0 == archive_read_support_format_raw(a));
assertA(0 == archive_read_open_memory(a, buf, sizeof(buf)));
/* perform a read which can be fulfilled */
assert(NULL != __archive_read_ahead(ar, sizeof(buf) - 1, &avail));
assertEqualInt(sizeof(buf), avail);
/* perform a read which cannot be fulfilled due to EOF */
assert(NULL == __archive_read_ahead(ar, sizeof(buf) + 1, &avail));
assertEqualInt(sizeof(buf), avail);
/* perform the same read again */
assert(NULL == __archive_read_ahead(ar, sizeof(buf) + 1, &avail));
assertEqualInt(sizeof(buf), avail);
/* perform another read which can be fulfilled */
assert(NULL != __archive_read_ahead(ar, sizeof(buf), &avail));
assertEqualInt(sizeof(buf), avail);
assert(0 == archive_read_free(a));
}

View file

@ -882,3 +882,138 @@ DEFINE_TEST(test_archive_string_conversion)
test_archive_string_canonicalization();
test_archive_string_set_get();
}
DEFINE_TEST(test_archive_string_conversion_utf16_utf8)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
skipping("This test is meant to verify unicode string handling on Windows");
#else
struct archive_mstring mstr;
const char* utf8_string;
memset(&mstr, 0, sizeof(mstr));
assertEqualInt(ARCHIVE_OK,
archive_mstring_copy_wcs(&mstr, L"\U0000043f\U00000440\U00000438"));
/* Conversion from WCS to UTF-8 should always succeed */
assertEqualInt(ARCHIVE_OK,
archive_mstring_get_utf8(NULL, &mstr, &utf8_string));
assertEqualString("\xD0\xBF\xD1\x80\xD0\xB8", utf8_string);
archive_mstring_clean(&mstr);
#endif
}
DEFINE_TEST(test_archive_string_conversion_utf8_utf16)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
skipping("This test is meant to verify unicode string handling on Windows");
#else
struct archive_mstring mstr;
const wchar_t* wcs_string;
memset(&mstr, 0, sizeof(mstr));
assertEqualInt(6,
archive_mstring_copy_utf8(&mstr, "\xD0\xBF\xD1\x80\xD0\xB8"));
/* Conversion from UTF-8 to WCS should always succeed */
assertEqualInt(ARCHIVE_OK,
archive_mstring_get_wcs(NULL, &mstr, &wcs_string));
assertEqualWString(L"\U0000043f\U00000440\U00000438", wcs_string);
archive_mstring_clean(&mstr);
#endif
}
DEFINE_TEST(test_archive_string_update_utf8_win)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
skipping("This test is meant to verify unicode string handling on Windows"
" with the C locale");
#else
static const char utf8_string[] = "\xD0\xBF\xD1\x80\xD0\xB8";
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
struct archive_mstring mstr;
int r;
memset(&mstr, 0, sizeof(mstr));
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
/* On Windows, this should reliably fail with the C locale */
assertEqualInt(-1, r);
assertEqualInt(0, mstr.aes_set & AES_SET_MBS);
/* NOTE: We access the internals to validate that they were set by the
* 'archive_mstring_update_utf8' function */
/* UTF-8 should always be set */
assertEqualInt(AES_SET_UTF8, mstr.aes_set & AES_SET_UTF8);
assertEqualString(utf8_string, mstr.aes_utf8.s);
/* WCS should always be set as well */
assertEqualInt(AES_SET_WCS, mstr.aes_set & AES_SET_WCS);
assertEqualWString(wcs_string, mstr.aes_wcs.s);
archive_mstring_clean(&mstr);
#endif
}
DEFINE_TEST(test_archive_string_update_utf8_utf8)
{
static const char utf8_string[] = "\xD0\xBF\xD1\x80\xD0\xB8";
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
struct archive_mstring mstr;
int r;
memset(&mstr, 0, sizeof(mstr));
if (setlocale(LC_ALL, "en_US.UTF-8") == NULL) {
skipping("UTF-8 not supported on this system.");
return;
}
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
/* All conversions should have succeeded */
assertEqualInt(0, r);
assertEqualInt(AES_SET_MBS | AES_SET_WCS | AES_SET_UTF8, mstr.aes_set);
assertEqualString(utf8_string, mstr.aes_utf8.s);
assertEqualString(utf8_string, mstr.aes_mbs.s);
assertEqualWString(wcs_string, mstr.aes_wcs.s);
archive_mstring_clean(&mstr);
}
DEFINE_TEST(test_archive_string_update_utf8_koi8)
{
static const char utf8_string[] = "\xD0\xBF\xD1\x80\xD0\xB8";
static const char koi8_string[] = "\xD0\xD2\xC9";
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
struct archive_mstring mstr;
int r;
memset(&mstr, 0, sizeof(mstr));
if (setlocale(LC_ALL, "ru_RU.KOI8-R") == NULL) {
skipping("KOI8-R locale not available on this system.");
return;
}
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
/* All conversions should have succeeded */
assertEqualInt(0, r);
assertEqualInt(AES_SET_MBS | AES_SET_WCS | AES_SET_UTF8, mstr.aes_set);
assertEqualString(utf8_string, mstr.aes_utf8.s);
assertEqualString(koi8_string, mstr.aes_mbs.s);
#if defined(_WIN32) && !defined(__CYGWIN__)
assertEqualWString(wcs_string, mstr.aes_wcs.s);
#else
/* No guarantee of how WCS strings behave, however this test test is
* primarily meant for Windows */
(void)wcs_string;
#endif
archive_mstring_clean(&mstr);
}

View file

@ -47,7 +47,7 @@ echo "f3" > $dir/d1/f3
rm -r $dir
}
#
# Make a lzip file from splitted tar file.
# Make a lzip file from split tar file.
#
name=test_compat_lzip_1
dir="$name`date +%Y%m%d%H%M%S`.$USER"

View file

@ -60,7 +60,7 @@ test_compat_solaris_pax_sparse_1(void)
assertEqualInt(0100644, archive_entry_mode(ae));
/* Verify the sparse information. */
failure("This sparse file should have tree data blocks");
failure("This sparse file should have three data blocks");
assertEqualInt(3, archive_entry_sparse_reset(ae));
assertEqualInt(ARCHIVE_OK,
archive_entry_sparse_next(ae, &offset, &length));

View file

@ -269,7 +269,7 @@ DEFINE_TEST(test_entry)
archive_entry_set_hardlink(e, "hardlink");
archive_entry_set_symlink(e, "symlink");
archive_entry_set_link(e, "link");
assertEqualString(archive_entry_hardlink(e), "hardlink");
assertEqualString(archive_entry_hardlink(e), NULL);
assertEqualString(archive_entry_symlink(e), "link");
/* mode */
@ -513,7 +513,6 @@ DEFINE_TEST(test_entry)
archive_entry_set_rdev(e, 532);
archive_entry_set_size(e, 987654321);
archive_entry_copy_sourcepath(e, "source");
archive_entry_set_symlink(e, "symlinkname");
archive_entry_set_uid(e, 83);
archive_entry_set_uname(e, "user");
/* Add an ACL entry. */
@ -548,7 +547,7 @@ DEFINE_TEST(test_entry)
assertEqualInt(archive_entry_rdev(e2), 532);
assertEqualInt(archive_entry_size(e2), 987654321);
assertEqualString(archive_entry_sourcepath(e2), "source");
assertEqualString(archive_entry_symlink(e2), "symlinkname");
assertEqualString(archive_entry_symlink(e2), NULL);
assertEqualInt(archive_entry_uid(e2), 83);
assertEqualString(archive_entry_uname(e2), "user");
@ -649,7 +648,7 @@ DEFINE_TEST(test_entry)
assertEqualInt(archive_entry_rdev(e2), 532);
assertEqualInt(archive_entry_size(e2), 987654321);
assertEqualString(archive_entry_sourcepath(e2), "source");
assertEqualString(archive_entry_symlink(e2), "symlinkname");
assertEqualString(archive_entry_symlink(e2), NULL);
assertEqualInt(archive_entry_uid(e2), 83);
assertEqualString(archive_entry_uname(e2), "user");
@ -705,6 +704,13 @@ DEFINE_TEST(test_entry)
/* Release clone. */
archive_entry_free(e2);
/* Verify that symlink is copied over by `clone` */
archive_entry_set_symlink(e, "symlinkpath");
e2 = archive_entry_clone(e);
assertEqualString(archive_entry_hardlink(e2), NULL);
assertEqualString(archive_entry_symlink(e2), "symlinkpath");
archive_entry_free(e2);
/*
* Test clear() implementation.
*/

View file

@ -389,3 +389,105 @@ DEFINE_TEST(test_gnutar_filename_encoding_CP932_UTF8)
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
}
DEFINE_TEST(test_gnutar_filename_encoding_UTF16_win)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
skipping("This test is meant to verify unicode string handling"
" on Windows with UTF-16 names");
return;
#else
struct archive *a;
struct archive_entry *entry;
char buff[4096];
size_t used;
/*
* Don't call setlocale because we're verifying that the '_w' functions
* work as expected when 'hdrcharset' is UTF-8
*/
/* Part 1: file */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
skipping("This system cannot convert character-set"
" from UTF-16 to UTF-8.");
archive_write_free(a);
return;
}
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the filename using a UTF-16 string */
archive_entry_copy_pathname_w(entry, L"\u8868.txt");
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
/* Part 2: directory */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the directory name using a UTF-16 string */
/* NOTE: Explicitly not adding trailing slash to test that code path */
archive_entry_copy_pathname_w(entry, L"\u8868");
archive_entry_set_filetype(entry, AE_IFDIR);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff, "\xE8\xA1\xA8/", 4);
/* Part 3: symlink */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the symlink target using a UTF-16 string */
archive_entry_set_pathname(entry, "link.txt");
archive_entry_copy_symlink_w(entry, L"\u8868.txt");
archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_symlink_type(entry, AE_SYMLINK_TYPE_FILE);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
/* Part 4: hardlink */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the symlink target using a UTF-16 string */
archive_entry_set_pathname(entry, "link.txt");
archive_entry_copy_hardlink_w(entry, L"\u8868.txt");
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
#endif
}

View file

@ -202,3 +202,48 @@ DEFINE_TEST(test_link_resolver)
test_linkify_old_cpio();
test_linkify_new_cpio();
}
DEFINE_TEST(test_link_resolver_unicode_win)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
skipping("This test is meant to verify unicode string handling"
" on Windows with UTF-16 names");
return;
#else
struct archive_entry *entry, *e2;
struct archive_entry_linkresolver *resolver;
/* Initialize the resolver. */
assert(NULL != (resolver = archive_entry_linkresolver_new()));
archive_entry_linkresolver_set_strategy(resolver,
ARCHIVE_FORMAT_TAR_USTAR);
/* Create an entry with a unicode filename and 2 links. */
assert(NULL != (entry = archive_entry_new()));
archive_entry_copy_pathname_w(entry, L"\u4f60\u597d.txt");
archive_entry_set_ino(entry, 1);
archive_entry_set_dev(entry, 2);
archive_entry_set_nlink(entry, 2);
archive_entry_set_size(entry, 10);
archive_entry_linkify(resolver, &entry, &e2);
/* Shouldn't be altered, since it wasn't seen before. */
assert(e2 == NULL);
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_pathname_w(entry));
assertEqualWString(NULL, archive_entry_hardlink_w(entry));
assertEqualInt(10, archive_entry_size(entry));
/* Link to the same file contents, but a new unicode name. */
archive_entry_copy_pathname_w(entry, L"\u518d\u89c1.txt");
archive_entry_linkify(resolver, &entry, &e2);
/* Size & link path should have changed. */
assert(e2 == NULL);
assertEqualWString(L"\u518d\u89c1.txt", archive_entry_pathname_w(entry));
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_hardlink_w(entry));
assertEqualInt(0, archive_entry_size(entry));
archive_entry_free(entry);
archive_entry_linkresolver_free(resolver);
#endif
}

View file

@ -579,6 +579,158 @@ DEFINE_TEST(test_pax_filename_encoding_KOI8R_CP1251)
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
/*
* Verify that unicode filenames are correctly preserved on Windows
*/
DEFINE_TEST(test_pax_filename_encoding_UTF16_win)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
skipping("This test is meant to verify unicode string handling"
" on Windows with UTF-16 names");
return;
#else
struct archive *a;
struct archive_entry *entry;
char buff[0x2000];
char *p;
size_t used;
/*
* Don't call setlocale because we're verifying that the '_w' functions
* work as expected when 'hdrcharset' is UTF-8
*/
/* Check if the platform completely supports the string conversion. */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
skipping("This system cannot convert character-set"
" from UTF-16 to UTF-8.");
archive_write_free(a);
return;
}
archive_write_free(a);
/*
* Create a new archive handle with default charset handling
*/
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
/* Part 1: file */
entry = archive_entry_new2(a);
archive_entry_copy_pathname_w(entry, L"\u4f60\u597d.txt");
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
/* Part 2: directory */
/* NOTE: Explicitly not adding trailing slash to test that code path */
archive_entry_copy_pathname_w(entry, L"\u043f\u0440\u0438");
archive_entry_set_filetype(entry, AE_IFDIR);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
/* Part 3: symlink */
archive_entry_copy_pathname_w(entry, L"\u518d\u89c1.txt");
archive_entry_copy_symlink_w(entry, L"\u4f60\u597d.txt");
archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_symlink_type(entry, AE_SYMLINK_TYPE_FILE);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
/* Part 4: hardlink */
archive_entry_copy_pathname_w(entry, L"\u665a\u5b89.txt");
archive_entry_copy_hardlink_w(entry, L"\u4f60\u597d.txt");
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Examine the bytes to ensure the filenames ended up UTF-8
* encoded as we expect.
*/
/* Part 1: file */
p = buff + 0;
assertEqualString(p + 0, "PaxHeader/\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* File name */
assertEqualInt(p[156], 'x'); /* Pax extension header */
p += 512; /* Pax extension body */
assertEqualString(p + 0, "19 path=\xE4\xBD\xA0\xE5\xA5\xBD.txt\n");
p += 512; /* Ustar header */
assertEqualString(p + 0, "\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* File name */
assertEqualInt(p[156], '0');
/* Part 2: directory */
p += 512; /* Pax extension header */
assertEqualString(p + 0, "PaxHeader/\xD0\xBF\xD1\x80\xD0\xB8"); /* File name */
assertEqualInt(p[156], 'x');
p += 512; /* Pax extension body */
assertEqualString(p + 0, "16 path=\xD0\xBF\xD1\x80\xD0\xB8/\n");
p += 512; /* Ustar header */
assertEqualString(p + 0, "\xD0\xBF\xD1\x80\xD0\xB8/"); /* File name */
assertEqualInt(p[156], '5'); /* directory */
/* Part 3: symlink */
p += 512; /* Pax Extension Header */
assertEqualString(p + 0, "PaxHeader/\xE5\x86\x8D\xE8\xA7\x81.txt"); /* File name */
p += 512; /* Pax extension body */
assertEqualString(p + 0,
"19 path=\xE5\x86\x8D\xE8\xA7\x81.txt\n"
"23 linkpath=\xE4\xBD\xA0\xE5\xA5\xBD.txt\n"
"31 LIBARCHIVE.symlinktype=file\n");
p += 512; /* Ustar header */
assertEqualString(p + 0, "\xE5\x86\x8D\xE8\xA7\x81.txt"); /* File name */
assertEqualInt(p[156], '2'); /* symlink */
assertEqualString(p + 157, "\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* link name */
/* Part 4: hardlink */
p += 512; /* Pax extension header */
assertEqualString(p + 0, "PaxHeader/\xE6\x99\x9A\xE5\xAE\x89.txt"); /* File name */
p += 512; /* Pax extension body */
assertEqualString(p + 0,
"19 path=\xE6\x99\x9A\xE5\xAE\x89.txt\n"
"23 linkpath=\xE4\xBD\xA0\xE5\xA5\xBD.txt\n"
"31 LIBARCHIVE.symlinktype=file\n");
p += 512; /* Ustar header */
assertEqualString(p + 0, "\xE6\x99\x9A\xE5\xAE\x89.txt"); /* File name */
assertEqualInt(p[156], '1'); /* hard link */
assertEqualString(p + 157, "\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* link name */
/*
* Read back the archive to see if we get the original names
*/
a = archive_read_new();
archive_read_support_format_all(a);
archive_read_support_filter_all(a);
assertEqualInt(0, archive_read_open_memory(a, buff, used));
/* Read part 1: file */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_pathname_w(entry));
/* Read part 2: directory */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
assertEqualWString(L"\u043f\u0440\u0438/", archive_entry_pathname_w(entry));
/* Read part 3: symlink */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
assertEqualWString(L"\u518d\u89c1.txt", archive_entry_pathname_w(entry));
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_symlink_w(entry));
/* Read part 4: hardlink */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
assertEqualWString(L"\u665a\u5b89.txt", archive_entry_pathname_w(entry));
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_hardlink_w(entry));
archive_free(a);
#endif
}
DEFINE_TEST(test_pax_filename_encoding)
{

View file

@ -1050,6 +1050,7 @@ test_arm_filter(const char *refname)
extract_reference_file(refname);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
@ -1123,6 +1124,7 @@ test_arm64_filter(const char *refname)
extract_reference_file(refname);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
@ -1255,5 +1257,47 @@ DEFINE_TEST(test_read_format_7zip_win_attrib)
assertEqualString("system", archive_entry_fflags_text(ae));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_extract_second)
{
struct archive *a;
char buffer[256];
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping(
"7zip:lzma decoding is not supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
/*
* The test archive has two files: first.txt which is a 65,536 file (the
* size of the uncompressed buffer), and second.txt which has contents
* we will validate. This test ensures we can skip first.txt and still
* be able to read the contents of second.txt
*/
const char *refname = "test_read_format_7zip_extract_second.7z";
extract_reference_file(refname);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
struct archive_entry *ae;
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("first.txt", archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("second.txt", archive_entry_pathname(ae));
assertEqualInt(23, archive_read_data(a, buffer, sizeof(buffer)));
assertEqualMem("This is from second.txt", buffer, 23);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View file

@ -0,0 +1,11 @@
begin 644 test_read_format_7zip_extract_second.7z
M-WJ\KR<<``-N%=VX!@$````````B`````````*R\U.<`&`Q"DFIGO`[1,RO\
MN,RA7-QU1L&_]O_/$0MMLIEBUR3'BDX@M2C-5'VG./-4,5@W3Q@*__^7_,[H
MEO`DB'[ZI>@H2_E>/W.2G$$.P01-X!YN5";SS[3#7Z4Q1G/EF.0'^D*[S8&8
M[FV9DYX7,SA%^.Q\'?__P!@`````@3,'K@_4WV/Q0A7VLXG$X?GH4=5W^`UM
M$N_EX$)LE*?K$W5?WLP:X0T[Q%V^?A!0E\VZRBB,)(MO`C`LO[O!3(1YL)<:
MJ."`';WU;>GP5',%Z=6?*/H9*Z)&\*!2^<F\P&>,RV`R30UOBH8+5.;;2IKF
M0W://&'?"L?0L2!)`*]F30B0&/_'<4``%P9Z`0F`C``'"P$``2,#`0$%70``
-@``,@*@*`6]FB2D`````
`
end

View file

@ -65,15 +65,6 @@ static unsigned char archive[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
/*
* XXX This must be removed when we use int64_t for uid.
*/
static int
uid_size(void)
{
return (sizeof(uid_t));
}
DEFINE_TEST(test_read_format_cpio_afio)
{
unsigned char *p;
@ -106,8 +97,7 @@ DEFINE_TEST(test_read_format_cpio_afio)
*/
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt(17, archive_entry_size(ae));
if (uid_size() > 4)
assertEqualInt(65536, archive_entry_uid(ae));
assertEqualInt(65536, archive_entry_uid(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
assertA(archive_filter_code(a, 0) == ARCHIVE_FILTER_NONE);
@ -117,3 +107,21 @@ DEFINE_TEST(test_read_format_cpio_afio)
free(p);
}
// From OSS Fuzz Issue 70019:
static unsigned char archive2[] = "070727bbbBbbbBabbbbbbcbcbbbbbbm726f777f777ffffffff518402ffffbbbabDDDDDDDDD7c7Ddd7DDDDnDDDdDDDB7777s77777777777C7727:";
DEFINE_TEST(test_read_format_cpio_afio_broken)
{
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, archive2, sizeof(archive2)));
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_AFIO_LARGE);
archive_read_free(a);
}

View file

@ -0,0 +1,50 @@
/*-
* Copyright (c) 2003-2024 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
DEFINE_TEST(test_read_format_huge_rpm)
{
struct archive_entry *ae;
struct archive *a;
const char *name = "test_read_format_huge_rpm.rpm";
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
/* This archive should have no entries -- if it has entries, the bid has screwed up */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify that the format detection worked. */
assertEqualInt(ARCHIVE_FILTER_RPM, archive_filter_code(a, 0));
assertEqualString("rpm", archive_filter_name(a, 0));
assertEqualInt(ARCHIVE_FORMAT_EMPTY, archive_format(a));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View file

@ -0,0 +1,244 @@
(
# set up ST_LEAD
python -c 'import sys; sys.stdout.buffer.write(b"\xED\xAB\xEE\xDB\x03\x00\x00\x01" + (96 - 8) * b"\x00")'
# set up ST_HEADER with 0x800000 sections
python -c 'import sys; sys.stdout.buffer.write(b"\x8E\xAD\xE8\x01" + 4 * b"\x00" + b"\x80" + 7 * b"\x00")'
# create archive
touch input.txt
bsdtar -cf - input.txt
) > test_read_format_huge_rpm.rpm
begin 644 test_read_format_huge_rpm.rpm
M[:ONVP,```$`````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````CJWH`0````"``````````&EN<'5T+G1X=```````````````````
M````````````````````````````````````````````````````````````
M```````````````````````````````````````````P,#`V-#0@`#`P,#<V
M-2``,#`P,#(T(``P,#`P,#`P,#`P,"`Q-#8Q-3(U-C0W-"`P,3(W,38`(#``
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````=7-T87(`,#!T:6T`````````````````````````````````
M`````'-T869F````````````````````````````````````,#`P,#`P(``P
M,#`P,#`@````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
"````
`
end

View file

@ -0,0 +1,40 @@
Same as test_read_format_iso_2.iso.Z except that the root directory record
size in the PVD has been changed to 68 bytes (instead of the 34 required
by the standard). This non-standard value was seen in the wild.
begin 644 test_read_format_iso_3.iso.Z
M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR
MI,F3*%.J7,FRI<N7,&/*G$FSILV;.'/JW,FSI\^?0(,*'4JTJ-&C2),J7<JT
MJ=.G4*-*G4JUJM6K6+-JW<JUJ]>O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
MKMV[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$Z408<04Q`!PH,01BCA
MA!16:.&%$!Z404$;>G0@``%\>"`""`#@04$>2)#0!`,1`0`%!<%8HD`EEF+C
MC:4($)"(!V+HXX]`!BGDD$06:>212":IY)),-NGDDU!&*>645%9II8\R%!@#
M##C$0(,,,6Q)PPP$DI-EF%QZ"::89,)`#H%PQBDGG&=NV>67:(Y9YH?_]>GG
MGX7](R"!!@)JZ*&()JKHHL<="...`AU80:0`!`$B`!=0.@2CG';JZ:>@A@H8
MGR]>:FI`DP9@*:F9!BCJJ[#&*NNLM#XE0JD$R3A0C3C:J*.I(0)PZZ,#Z4HC
M`+WZ"BF((=XZ*4&3SAA0B6\@X$`%"AA`SJ\\!G%KI@1E*BT`U%J+[0+;+AOB
MIK6VZ^Z[\,8;G;,%1;LK`-5>FVVZP!XX;(SDWIMLCNJ&:`(`%A1D@0$%&9`O
MMMI2"B(!0KBP0PSR9JSQQAQWW!P:9;#!QAL*>&SRR2BGK'*GWQ8D[KT/*X`N
MMSOZBVNQ`1\[,,W,!G`P!@5AP#!!#ILK,SD2!T``$19CO/+34$<M]=2$@2PR
MR51GK?767'?M]==@ARWVV&27;?;9:*>M]MILM^WVVW#'+??<=-=M]]UXYZWW
MWGSW[???@`<N^."$%V[XX8@GKOCBC#?N^..01R[YY)17;OGEF&>N^>:<=^[Y
MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,<N^^RTUV[[[;CGKOONO/?N^^_`!R_\
M\,07;_SQR">O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(<O_OCDEV_^
M^>BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@
M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$*
M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7
MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?(
MQC:Z\8UPC*,<YTC'.MKQCGC,HQ[WR,<^^O&/@`RD(`=)R$(:\I"(3*0B%\G(
M1CKRD9",I"0G2<E*6O*2F,RD)C?)R4YZ\I.@#*4H1TG*4IKRE*A,I2I7R<I6
MNO*5L(RE+&=)RUK:\I:XS*4N=\G+7OKRE\`,IC"'2<QB&O.8R$RF,I?)S&8Z
M\YG0C*8TITG-:EKSFMC,IC:WR<UN>O.;X`RG.,=)SG*:\YSH3*<ZU\G.=KKS
MG?",ISSG2<]ZVO.>^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A
M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P
MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"-
MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK
".`$`
`
end

View file

@ -40,8 +40,29 @@ test1(void)
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, name, 512));
/* Root directory */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualIntA(a, 1131434684, archive_entry_atime(ae));
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
assertEqualIntA(a, 1131434684, archive_entry_ctime(ae));
assertEqualIntA(a, 0, archive_entry_dev(ae));
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
assertEqualIntA(a, 0, archive_entry_gid(ae));
assertEqualStringA(a, NULL, archive_entry_gname(ae));
assertEqualIntA(a, 0, archive_entry_ino(ae));
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
assertEqualIntA(a, 1131434684, archive_entry_mtime(ae));
assertEqualIntA(a, 2, archive_entry_nlink(ae));
assertEqualStringA(a, ".", archive_entry_pathname(ae));
assertEqualIntA(a, 0700, archive_entry_perm(ae));
assertEqualIntA(a, 2048, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_entry_uid(ae));
assertEqualStringA(a, NULL, archive_entry_uname(ae));
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_next_header(a, &ae));
assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_filter_code(a, 0),
ARCHIVE_FILTER_COMPRESS);
@ -53,11 +74,10 @@ test1(void)
}
static void
test2(void)
test_small(const char *name)
{
struct archive_entry *ae;
struct archive *a;
const char *name = "test_read_format_iso_2.iso.Z";
extract_reference_file(name);
@ -68,21 +88,110 @@ test2(void)
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, name, 512));
/* Root directory */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualString(".", archive_entry_pathname(ae));
assertEqualIntA(a, 3443989665, archive_entry_atime(ae));
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
assertEqualIntA(a, 3443989665, archive_entry_ctime(ae));
assertEqualIntA(a, 0, archive_entry_dev(ae));
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
assertEqualIntA(a, 0, archive_entry_gid(ae));
assertEqualStringA(a, NULL, archive_entry_gname(ae));
assertEqualIntA(a, 0, archive_entry_ino(ae));
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
assertEqualIntA(a, 3443989665, archive_entry_mtime(ae));
assertEqualIntA(a, 4, archive_entry_nlink(ae));
assertEqualIntA(a, 0700, archive_entry_perm(ae));
assertEqualIntA(a, 2048, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_entry_uid(ae));
assertEqualStringA(a, NULL, archive_entry_uname(ae));
/* Directory "A" */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualString("A", archive_entry_pathname(ae));
assertEqualIntA(a, 1313381406, archive_entry_atime(ae));
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
assertEqualIntA(a, 1313381406, archive_entry_ctime(ae));
assertEqualIntA(a, 0, archive_entry_dev(ae));
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
assertEqualIntA(a, 0, archive_entry_gid(ae));
assertEqualStringA(a, NULL, archive_entry_gname(ae));
assertEqualIntA(a, 0, archive_entry_ino(ae));
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
assertEqualIntA(a, 1313381406, archive_entry_mtime(ae));
assertEqualIntA(a, 2, archive_entry_nlink(ae));
assertEqualIntA(a, 0700, archive_entry_perm(ae));
assertEqualIntA(a, 2048, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_entry_uid(ae));
assertEqualStringA(a, NULL, archive_entry_uname(ae));
/* File "A/B" */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualString("A/B", archive_entry_pathname(ae));
assertEqualIntA(a, 1313381406, archive_entry_atime(ae));
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
assertEqualIntA(a, 1313381406, archive_entry_ctime(ae));
assertEqualIntA(a, 0, archive_entry_dev(ae));
assertEqualIntA(a, AE_IFREG, archive_entry_filetype(ae));
assertEqualIntA(a, 0, archive_entry_gid(ae));
assertEqualStringA(a, NULL, archive_entry_gname(ae));
assertEqualIntA(a, 0, archive_entry_ino(ae));
assertEqualIntA(a, AE_IFREG | 0400, archive_entry_mode(ae));
assertEqualIntA(a, 1313381406, archive_entry_mtime(ae));
assertEqualIntA(a, 1, archive_entry_nlink(ae));
assertEqualIntA(a, 0400, archive_entry_perm(ae));
assertEqualIntA(a, 6, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_entry_uid(ae));
assertEqualStringA(a, NULL, archive_entry_uname(ae));
/* TODO: Verify that file contents are "hello\n" */
/* Directory "C" */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualString("C", archive_entry_pathname(ae));
assertEqualIntA(a, 1313381411, archive_entry_atime(ae));
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
assertEqualIntA(a, 1313381411, archive_entry_ctime(ae));
assertEqualIntA(a, 0, archive_entry_dev(ae));
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
assertEqualIntA(a, 0, archive_entry_gid(ae));
assertEqualStringA(a, NULL, archive_entry_gname(ae));
assertEqualIntA(a, 0, archive_entry_ino(ae));
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
assertEqualIntA(a, 1313381411, archive_entry_mtime(ae));
assertEqualIntA(a, 2, archive_entry_nlink(ae));
assertEqualIntA(a, 0700, archive_entry_perm(ae));
assertEqualIntA(a, 2048, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_entry_uid(ae));
assertEqualStringA(a, NULL, archive_entry_uname(ae));
/* File "C/D" */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualString("C/D", archive_entry_pathname(ae));
assertEqualIntA(a, 1313381411, archive_entry_atime(ae));
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
assertEqualIntA(a, 1313381411, archive_entry_ctime(ae));
assertEqualIntA(a, 0, archive_entry_dev(ae));
assertEqualIntA(a, AE_IFREG, archive_entry_filetype(ae));
assertEqualIntA(a, 0, archive_entry_gid(ae));
assertEqualStringA(a, NULL, archive_entry_gname(ae));
assertEqualIntA(a, 0, archive_entry_ino(ae));
assertEqualIntA(a, AE_IFREG | 0400, archive_entry_mode(ae));
assertEqualIntA(a, 1313381411, archive_entry_mtime(ae));
assertEqualIntA(a, 1, archive_entry_nlink(ae));
assertEqualIntA(a, 0400, archive_entry_perm(ae));
assertEqualIntA(a, 6, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_entry_uid(ae));
assertEqualStringA(a, NULL, archive_entry_uname(ae));
/* TODO: Verify that file contents are "hello\n" */
/* Final statistics */
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_next_header(a, &ae));
assertEqualInt(5, archive_file_count(a));
@ -98,5 +207,8 @@ test2(void)
DEFINE_TEST(test_read_format_iso_Z)
{
test1();
test2();
/* A very small ISO image with a variety of contents. */
test_small("test_read_format_iso_2.iso.Z");
/* As above, but with a non-standard 68-byte root directory in the PVD */
test_small("test_read_format_iso_3.iso.Z");
}

View file

@ -158,7 +158,7 @@ test_read_format_mtree1(void)
/* TODO: Mtree reader should probably return ARCHIVE_WARN for this. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString(archive_entry_pathname(ae), "dir2/toosmallfile");
assertEqualInt(archive_entry_size(ae), -1);
assertEqualInt(archive_entry_size(ae), 0);
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);

View file

@ -843,7 +843,7 @@ DEFINE_TEST(test_read_format_rar5_block_by_block)
struct archive_entry *ae;
struct archive *a;
uint8_t buf[173];
int bytes_read;
ssize_t bytes_read;
uint32_t computed_crc = 0;
extract_reference_file("test_read_format_rar5_compressed.rar");
@ -932,19 +932,22 @@ DEFINE_TEST(test_read_format_rar5_symlink)
assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
assertEqualString("file.txt", archive_entry_symlink(ae));
assertEqualInt(AE_SYMLINK_TYPE_FILE, archive_entry_symlink_type(ae));
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
assertEqualInt(0, archive_entry_size(ae));
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
assertA(0 == archive_read_next_header(a, &ae));
assertEqualString("dirlink", archive_entry_pathname(ae));
assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
assertEqualString("dir", archive_entry_symlink(ae));
assertEqualInt(AE_SYMLINK_TYPE_DIRECTORY, archive_entry_symlink_type(ae));
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
assertEqualInt(0, archive_entry_size(ae));
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
assertA(0 == archive_read_next_header(a, &ae));
assertEqualString("dir", archive_entry_pathname(ae));
assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
assertEqualInt(0, archive_entry_size(ae));
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
@ -969,7 +972,8 @@ DEFINE_TEST(test_read_format_rar5_hardlink)
assertEqualString("hardlink.txt", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualString("file.txt", archive_entry_hardlink(ae));
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
assertEqualInt(0, archive_entry_size(ae));
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
@ -1340,7 +1344,7 @@ DEFINE_TEST(test_read_format_rar5_sfx)
assertA(size == archive_read_data(a, buff, size));
assertEqualMem(buff, test_txt, size);
EPILOGUE();
}
@ -1402,3 +1406,26 @@ DEFINE_TEST(test_read_format_rar5_read_data_block_uninitialized_offset)
EPILOGUE();
}
DEFINE_TEST(test_read_format_rar5_data_ready_pointer_leak)
{
/* oss fuzz 70024 */
char buf[4096];
PROLOGUE("test_read_format_rar5_data_ready_pointer_leak.rar");
/* Return codes of those calls are ignored, because this sample file
* is invalid. However, the unpacker shouldn't produce any SIGSEGV
* errors during processing. */
(void) archive_read_next_header(a, &ae);
(void) archive_read_data(a, buf, sizeof(buf));
(void) archive_read_next_header(a, &ae);
(void) archive_read_data(a, buf, sizeof(buf));
(void) archive_read_data(a, buf, sizeof(buf));
(void) archive_read_next_header(a, &ae);
/* This call shouldn't produce SIGSEGV. */
(void) archive_read_data(a, buf, sizeof(buf));
EPILOGUE();
}

View file

@ -0,0 +1,28 @@
begin 644 test_read_format_rar5_data_ready_pointer_leak.rar.uu
M4F%R(1H'`0`]/-[E`@$`_R`@1#[Z5P("`P,`(/__(""`((``"2`@("`@_R`@
M("`@(%.`*O0#`N<B`A"`("#_((`+`00@("`@(""!)/\@("`@("`@(/\@("`@
M^I@R<00"WN<-\@$@_R`@(``C("`@("`@("`@("`@("`@("`@("`@("`@("#_
M____("`@(/___R#_("`@("`@("#___\@_____R`@("`@("`@(/__________
M____(/__(/\@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@________
M_________R`@____(/____\@("`@("`@("#______________R#___\@("`@
M("`@("`@("`@("`@("`@("`@(/\@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@_________R`@("`@_R`@("`@("`@
M("`@("`@(/__("`@("`@("`@("`@("`@(%.`*O0#`N<B`A"`_R`@_R#_"P$$
M("`@("`@@23_("`@_R`@("#_("`@(/J8,G$$`M[G#?(!(/\@("``(R`@("`@
M("`@("`@("`@("`@("`@("`@("#_("`@("`@("#_("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("#_
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@____("`@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@_R`@("`@("`@("`@("`@("`@("`@("`@("`@
M("!3@"KT`P+G(B`0@/\@(/\@_PL!_R"!)/\@("`@("`@(/\@("`@^I@R<00"
MWN<-\@$@_R`@(``C("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("#______________R`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@("`@(/\@(/_______R`@("`@("`@("`@("`@
M("`@("`@("`@_________R`@("`@("`@("`@("`@("`@(/________\@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(/\@
M("`@("`@(/\@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@(/\@($0^^E<"`@,#("`@(/\@@``)("`@("`@("`@
)("`@("`@("`@
`
end

View file

@ -437,7 +437,7 @@ static void verify(unsigned char *d, size_t s,
assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_open_memory(a, buff, s + 1024));
assertA(0 == archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt(archive_filter_code(a, 0), compression);
assertEqualInt(archive_format(a), format);
assertEqualInt(archive_entry_is_encrypted(ae), 0);

View file

@ -0,0 +1,65 @@
/*-
* Copyright (c) 2003-2023 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
/*
* Read a pax formatted tar archive that has an extremely large
* (8,000,000 bytes) attribute of unknown type. The pax reader should simply
* skip the attribute.
*/
DEFINE_TEST(test_read_format_tar_pax_large_attr)
{
char name[] = "test_read_format_tar_pax_large_attr.tar.Z";
struct archive_entry *ae;
struct archive *a;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
/* Read first entry. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("foo", archive_entry_pathname(ae));
assertEqualInt(1, archive_entry_mtime(ae));
assertEqualInt(1000, archive_entry_uid(ae));
assertEqualString("tim", archive_entry_uname(ae));
assertEqualInt(0, archive_entry_gid(ae));
assertEqualString("wheel", archive_entry_gname(ae));
assertEqualInt(0100644, archive_entry_mode(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
/* Verify the end-of-archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify that the format detection worked. */
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View file

@ -0,0 +1,149 @@
Decode this file with:
cat test_read_format_tar_pax_large_attr.tar.Z.uu | uudecode -p | uncompress | hexdump -C
It contains a single tar entry with a pax header that has a single
attribute of 8000000 bytes
00000200 38 30 30 30 30 30 30 20 75 6e 6b 6e 6f 77 6e 3d |8000000 unknown=|
00000210 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b |++++++++++++++++|
*
007a13f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 0a |+++++++++++++++.|
begin 644 test_read_format_tar_pax_large_attr.tar.Z
M'YV04,+@05(F#)DR<EZ8>?,&@,.'$"-*G$BQHL6+&"O"V&B#!@T0`#;"N&&C
M!DB1,&1\#+EQ1L<8,42"B$&CA@P;-UQZM`$"1HP9-6+<```"3\:C2),J73JQ
MSAPZ8>2PI).F#5.+3\.8,7-U(LJ-)[^"[$JVK-FS:-'B^`H#1!TW:]R\N>.F
MQXJ[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
MO?OW\./+GT^_OOW[^//KW\^_O___``8HX(`$%FC@@0@FJ.""##;HX(,01BCA
MA!16:.&%&&:HX88<=NCAAR"&*.*())9HXHDHIJCBBBRVZ.*+,,8HXXPTUFCC
MC3CFJ...//;HXX]`!BGDD$06:>212":IY)),-NGDDU!&*>645%9IY9589JGE
MEEQVZ>678(8IYIADEFGFF6BFJ>::;+;IYIMPQBGGG'36:>>=>.:IYYY\]NGG
MGX`&*NB@A!9JZ*&()JKHHHPVZNBCD$8JZ:245FKII9AFJNFFG';JZ:>@ABKJ
MJ*26:NJIJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYJKKKKSVZNNOP`8K[+#$%FOL
ML<@FJ^RRS#;K[+/01BOMM-16:^VUV&:K[;;<=NOMM^"&*^ZXY)9K[KGHIJON
MNNRVZ^Z[\,8K[[STUFOOO?CFJ^^^_/;K[[\`!RSPP`07;/#!"">L\,(,-^SP
MPQ!'+/'$%%=L\<489ZSQQAQW[/''((<L\L@DEVSRR2BGK/+*++?L\LLPQRSS
MS#37;//-..>L\\X\]^SSST`'+?301!=M]-%()ZWTTDPW[?334$<M]=145VWU
MU5AGK?767'?M]==@ARWVV&27;?;9:*>M]MILM^WVVW#'+??<=-=M]]UXYZWW
MWGSW[???@`<N^."$%V[XX8@GKOCBC#?N^..01R[YY)17;OGEF&>N^>:<=^[Y
MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,<N^^RTUV[[[;CGKOONO/?N^^_`!R_\
M\,07;_SQR">O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(<O_OCDEV_^
M^>BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@
M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$*
M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7
MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?(
MQC:Z\8UPC*,<YTC'.MKQCGC,HQ[WR,<^^O&/@`RD(`=)R$(:\I"(3*0B%\G(
M1CKRD9",I"0G2<E*6O*2F,RD)C?)R4YZ\I.@#*4H1TG*4IKRE*A,I2I7R<I6
MNO*5L(RE+&=)RUK:\I:XS*4N=\G+7OKRE\`,IC"'2<QB&O.8R$RF,I?)S&8Z
M\YG0C*8TITG-:EKSFMC,IC:WR<UN>O.;X`RG.,=)SG*:\YSH3*<ZU\G.=KKS
MG?",ISSG2<]ZVO.>^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A
M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P
MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"-
MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK
M7.=*U[K:]:YXS:M>]\K7OOKUKX`-K&`'2]C"&O:PB$VL8A?+V,8Z]K&0C:QD
M)TO9REKVLIC-K&8WR]G.>O:SH`VM:$=+VM*:]K2H3:UJ5\O:UKKVM;"-K6QG
M2]O:VO:VN,VM;G?+V][Z]K?`#:YPATO<XAKWN,A-KG*7R]SF.O>YT(VN=*=+
MW>I:][K8S:YVM\O=[GKWN^`-KWC'2][RFO>\Z$VO>M?+WO:Z][WPC:]\YTO?
M^MKWOOC-KW[WR]_^^O>_``ZP@`=,X`(;^,`(3K""%\S@!COXP1".L(0G3.$*
M6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK;
M^,8XSK&.=\SC'OOXQT`.LI"'3.0B&_G(2$ZRDI?,Y"8[^<E0CK*4ITSE*EOY
MREC.LI:WS.4N>_G+8`ZSF,=,YC*;^<QH3K.:U\SF-KOYS7".LYSG3.<ZV_G.
M>,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8
MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC.
MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV
MMK?-[6Y[^]O@#K>XQTWN<IO[W.A.M[K7S>YVN_O=\(ZWO.=-[WK;^][XSK>^
M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W
MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/N<QG3O.:V_SF.,^YSG?.
M\Y[[_.=`#[K0AT[THAO]Z$A/NM*7SO2F._WI4(^ZU*=.]:I;_>I8S[K6M\[U
MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O<YT[WNMO][GC/N][WSO>^
M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^<Y[
M_O.@#[WH1T_ZTIO^]*A/O>I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^
M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[
MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\`
M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($<V($>
M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\
MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5:
MN(5<V(5>^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X
MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6
M>(F8F(F:N(F<V(F>^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT
M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2
M.(W46(W6>(W8F(W:N(W<V(W>^(W@&([B.([D6([F>([HF([JN([LV([N^([P
M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`.
M^9`0&9$2.9$469$6>9$8F9$:N9$<V9$>^9$@&9(B.9(D69(F>9(HF9(JN9(L
MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91*
MN91,V91.^910&952.9546956>958F95:N95<V95>^95@&99B.99D699F>99H
MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B&
M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F<V9F>^9F@&9JB.9JD
M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S"
M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W<V9W>^9W@
M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^
M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$<
MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z
MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58
MFJ5:NJ5<VJ5>^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V
M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4
M6JF6>JF8FJF:NJF<VJF>^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR
M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0
M&JW2.JW46JW6>JW8FJW:NJW<VJW>^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N
M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`,
MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$<V[$>^[$@&[(B.[(D6[(F>[(HF[(J
MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1(
MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5<V[5>^[5@&[9B.[9D6[9F
M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$
M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F<V[F>^[F@&[JB
M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O`
M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W<V[W>
M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\
MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$:
MO,$<W,$>_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X
MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56
M?,58G,5:O,5<W,5>_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T
M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2
M/,F47,F6?,F8G,F:O,F<W,F>_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP
M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S.
M_,S0',W2/,W47,W6?,W8G,W:O,W<W,W>_,W@',[B/,[D7,[F?,[HG,[JO,[L
MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`*
MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$<W=$>_=$@'=(B/=(D7=(F?=(H
MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1&
M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5<W=5>_=5@'=9B/=9D
M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B"
M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F<W=F>_=F@
M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^
M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W<
MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z
MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8
MGN$:ON$<WN$>_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V
M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54
M7N56?N58GN5:ON5<WN5>_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R
M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0
M'NF2/NF47NF6?NF8GNF:ONF<WNF>_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN
M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS,
MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW<WNW>_NW@'N[B/N[D7N[F?N[HGN[J
MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`(
MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$<W_$>__$@'_(B/_(D7_(F
M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$
M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5<W_5>__5@'_9B
M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>`
M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F<W_F>
M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\
MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W:
MO_W<W_W>__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X
MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@!
M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P
M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27(
M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R#
M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)!
M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\
MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K"
M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U
MO(;8,!MJPVW(#;NA-_R&X#`<BL-Q2`[+H3D\A^@P':K#=<@.VZ$[?(?P,![*
MPWE(#^NA/;R'^#`?ZL-]R`_[H3_\AP`Q(`K$@4@0"Z)!/(@(,2$JQ(7($!NB
M0WR($#$B2L2)2!%ID@)8"`TA+6C$C8@11$)'6`D;02C4@+;`$E!"6&`+,@$E
MBH08T!-@`@UP"40!!G#$F4@3FT)6D`H;@2I8!8UX!]!`&2@#;"`ML(63*!-J
MHE$\BD@Q*2K%I<@4FZ)3?(I0,2I*Q:E(%:NB5;R*6#$K:L6MR!6[HE?\BF`Q
M+(K%L4@6RZ)9/(MH,2VJQ;7(%MNB6WR+<#$NRL6Y2!?KHEV\BW@Q+^K%O<@7
M^Z)?_(N`,3`*QL%(&`NC83R,B#$Q*L;%R!@;HV-\C)`Q,DK&R4@9*Z-EO(R8
),3-JQLW(&0$C
`
end

View file

@ -860,3 +860,34 @@ DEFINE_TEST(test_read_format_xar)
verify(archive12, sizeof(archive12), verify12, NULL, GZIP);
verifyB(archive13, sizeof(archive13));
}
DEFINE_TEST(test_read_format_xar_duplicate_filename_node)
{
static const char *reffiles[] =
{
"test_read_format_xar_duplicate_filename_node.xar",
NULL
};
struct archive_entry *ae;
struct archive *a;
int r;
extract_reference_files(reffiles);
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_filter_all(a));
r = archive_read_support_format_xar(a);
if (r == ARCHIVE_WARN) {
skipping("xar reading not fully supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertA(0 == archive_read_open_filenames(a, reffiles, 10240));
assertA(0 == archive_read_next_header(a, &ae));
assertEqualString("File", archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View file

@ -0,0 +1,14 @@
begin 644 test_read_format_xar_duplicate_filename_node.xar
M>&%R(0`<``$````````!EP````````.]`````7B<A5-);H,P%-U7ZAT0>VIC
MC('((;N<H-UT][$-L<H0@1,E.7T-`0H=TI6?__OSP'>7JG3.JNUT4V]=_P6[
MCJI%(W5=;-VWU[T7N[OT^8E?H+6/XW#3B`%8*%H%QMIY1E<J)9A0#S//IZ\$
M;PC=^(RCM<ID=U#BHSM53F>NI=JZW0%\=R0MW>1YITR*.1K1S'3ZUL?A:`"C
M-S2YFP2Y+I6CI:UFX;0&&W]O&8X&^#]AKD>5Y@,QP)G0=2-M&E'"DIBC^V\F
MI3IKH>HF]0-&68!]PM$LF[6JW@8S9CM4K<Q/6O:%]\\L*^ZR8BD3O[<<)^^V
M'XM>][$>J%9K57B@"FM5"0;FG_V7JB[,(?5MHB-<D.,<R<^1SD-=S7203VLX
M;0D<CZ46PS:ABU?<]-%UT-(`6G'09R6]W_<KIG$LJ9\%"6!)"&80R#`)<"!R
M'(DL)T`CH2384K\[6J5U,2T(\V>8#&+(0L`DQED2!@!)1(,PS^.$,I&)+"-1
M&`*)./KIZ:N]:-%?COHMO%\?NI\?1_T]?@(L`P/8\;44V2:R;"\D48GC?CRL
C(UAG)C5XG./E`@``)@`8>)R%4TEN@S`4W5?J'1![:F.,@<@`
`
end

View file

@ -41,7 +41,7 @@ DEFINE_TEST(test_read_format_zip_traditional_encryption_data)
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
if (ARCHIVE_OK != archive_write_set_options(a,
"zip:encryption=traditional")) {
skipping("This system does not have cryptographic liberary");
skipping("This system does not have cryptographic library");
archive_write_free(a);
return;
}

View file

@ -38,7 +38,7 @@ test_winzip_aes(const char *refname, int need_libz)
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
if (ARCHIVE_OK != archive_write_set_options(a,
"zip:encryption=aes256")) {
skipping("This system does not have cryptographic liberary");
skipping("This system does not have cryptographic library");
archive_write_free(a);
return;
}

View file

@ -39,7 +39,7 @@ DEFINE_TEST(test_read_format_zip_winzip_aes256_large)
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
if (ARCHIVE_OK != archive_write_set_options(a,
"zip:encryption=aes256")) {
skipping("This system does not have cryptographic liberary");
skipping("This system does not have cryptographic library");
archive_write_free(a);
return;
}

View file

@ -390,3 +390,105 @@ DEFINE_TEST(test_ustar_filename_encoding_CP932_UTF8)
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
}
DEFINE_TEST(test_ustar_filename_encoding_UTF16_win)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
skipping("This test is meant to verify unicode string handling"
" on Windows with UTF-16 names");
return;
#else
struct archive *a;
struct archive_entry *entry;
char buff[4096];
size_t used;
/*
* Don't call setlocale because we're verifying that the '_w' functions
* work as expected when 'hdrcharset' is UTF-8
*/
/* Part 1: file */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
skipping("This system cannot convert character-set"
" from UTF-16 to UTF-8.");
archive_write_free(a);
return;
}
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the filename using a UTF-16 string */
archive_entry_copy_pathname_w(entry, L"\u8868.txt");
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
/* Part 2: directory */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the directory name using a UTF-16 string */
/* NOTE: Explicitly not adding trailing slash to test that code path */
archive_entry_copy_pathname_w(entry, L"\u8868");
archive_entry_set_filetype(entry, AE_IFDIR);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff, "\xE8\xA1\xA8/", 4);
/* Part 3: symlink */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the symlink target using a UTF-16 string */
archive_entry_set_pathname(entry, "link.txt");
archive_entry_copy_symlink_w(entry, L"\u8868.txt");
archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_symlink_type(entry, AE_SYMLINK_TYPE_FILE);
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
/* Part 4: hardlink */
a = archive_write_new();
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
assertEqualInt(ARCHIVE_OK,
archive_write_open_memory(a, buff, sizeof(buff), &used));
entry = archive_entry_new2(a);
/* Set the symlink target using a UTF-16 string */
archive_entry_set_pathname(entry, "link.txt");
archive_entry_copy_hardlink_w(entry, L"\u8868.txt");
archive_entry_set_size(entry, 0);
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check UTF-8 version. */
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
#endif
}

View file

@ -230,12 +230,8 @@ DEFINE_TEST(test_write_filter_zstd)
archive_write_set_filter_option(a, NULL, "max-frame-out", "1GB"));
#endif
#if ZSTD_VERSION_NUMBER >= MINVER_LONG
if ((int)(sizeof(size_t) == 4))
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "long", "26"));
else
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "long", "27"));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "long", "23"));
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_filter_option(a, NULL, "long", "-1")); /* negative */
#endif

Some files were not shown because too many files have changed in this diff Show more