mirror of
https://github.com/libarchive/libarchive.git
synced 2026-01-28 18:34:51 +00:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d114ceee6d | ||
|
|
7d94cdaf66 | ||
|
|
2ded466c2a | ||
|
|
e00289a268 | ||
|
|
08cb8d2121 | ||
|
|
e65d075083 | ||
|
|
8d6b2335df | ||
|
|
df9967323e | ||
|
|
1368b08875 | ||
|
|
476369f600 | ||
|
|
d59cf5aa65 | ||
|
|
ec3bcb46e0 | ||
|
|
f1ad45f513 | ||
|
|
de18ca9888 | ||
|
|
17526e5c52 | ||
|
|
0da204ab11 | ||
|
|
c9b5cf5910 | ||
|
|
50716e1959 | ||
|
|
30ca142b35 | ||
|
|
7f4314ca47 | ||
|
|
88ca4fcf98 | ||
|
|
82b57a9740 | ||
|
|
0646e21c6f | ||
|
|
076a050bbf | ||
|
|
c359384806 | ||
|
|
7f53fce04e | ||
|
|
ed84daf889 | ||
|
|
82e31ba4a9 | ||
|
|
200ae00a12 | ||
|
|
78731e288a | ||
|
|
400abd1d7f | ||
|
|
94817fa277 | ||
|
|
7c0980ee6c | ||
|
|
e3cb54b42b | ||
|
|
53e8522453 | ||
|
|
a6d47272af | ||
|
|
dc6ea847e1 | ||
|
|
ec91352d64 | ||
|
|
1b5e6d4aed | ||
|
|
927dd43020 | ||
|
|
8055fbd321 | ||
|
|
044dd73668 | ||
|
|
af9e8bf368 | ||
|
|
f162db9618 | ||
|
|
53d2bc4f89 | ||
|
|
44681dd67f | ||
|
|
ab5ae538f6 | ||
|
|
12c8b3f895 | ||
|
|
5797a13c1f | ||
|
|
31b219bffa | ||
|
|
10ab6874cb | ||
|
|
a4a65701f4 | ||
|
|
45849e410b | ||
|
|
80815b7a18 | ||
|
|
51b5ac2f11 | ||
|
|
dabc205b20 | ||
|
|
de09764140 | ||
|
|
1f27094c78 | ||
|
|
57168d660b | ||
|
|
1cab1650fd | ||
|
|
dafb79b967 | ||
|
|
bb6b6d20cf | ||
|
|
7a15e83449 | ||
|
|
42371f7236 | ||
|
|
0c491a75ca | ||
|
|
f75fb1a13f | ||
|
|
affb84375d | ||
|
|
2aaa3389d1 | ||
|
|
0d32537a91 | ||
|
|
7278794021 | ||
|
|
0fadc61d5b | ||
|
|
f0020dcb21 | ||
|
|
7a32f7f9b1 | ||
|
|
a7a864bc1b | ||
|
|
56914db37f | ||
|
|
9525f90ca4 | ||
|
|
7a0b0caea1 | ||
|
|
bc2fcdafce | ||
|
|
14de0d62d3 | ||
|
|
8e1092726c | ||
|
|
94208dc524 | ||
|
|
6050823986 | ||
|
|
95a8adc7e5 | ||
|
|
3e718bf2d4 | ||
|
|
0dc4f71fcb | ||
|
|
b92f70d190 | ||
|
|
ab1d9a37eb | ||
|
|
119aec5306 | ||
|
|
ebbd18c365 | ||
|
|
6445be4ea6 | ||
|
|
30e662a0a5 | ||
|
|
66b380ed5a | ||
|
|
ad4d2eefa8 | ||
|
|
8a3cdd71cb | ||
|
|
22ef0ee13e | ||
|
|
4937278516 | ||
|
|
97a48a0d79 | ||
|
|
53c7eb8adf | ||
|
|
70ff28fcf0 |
10
.cirrus.yml
10
.cirrus.yml
@ -10,21 +10,21 @@ FreeBSD_task:
|
||||
BS: cmake
|
||||
matrix:
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
image_family: freebsd-14-3
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-5
|
||||
prepare_script:
|
||||
- ./build/ci/cirrus_ci/ci.sh prepare
|
||||
configure_script:
|
||||
- env CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a autogen
|
||||
- env CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a configure
|
||||
- env MAKE=gmake CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a configure
|
||||
build_script:
|
||||
- env MAKE_ARGS="-j 2" ./build/ci/build.sh -a build
|
||||
- env MAKE=gmake MAKE_ARGS="-j 2" ./build/ci/build.sh -a build
|
||||
test_script:
|
||||
- env SKIP_TEST_RESTORE_ATIME=1 MAKE_ARGS="-j 2" ./build/ci/build.sh -a test
|
||||
- env MAKE=gmake SKIP_TEST_RESTORE_ATIME=1 MAKE_ARGS="-j 2" ./build/ci/build.sh -a test
|
||||
- ./build/ci/cirrus_ci/ci.sh test
|
||||
install_script:
|
||||
- env MAKE_ARGS="-j 2" ./build/ci/build.sh -a install
|
||||
- env MAKE=gmake MAKE_ARGS="-j 2" ./build/ci/build.sh -a install
|
||||
|
||||
Windows_Cygwin_task:
|
||||
windows_container:
|
||||
|
||||
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
matrix:
|
||||
bs: [autotools, cmake]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Install dependencies
|
||||
run: ./build/ci/github_actions/install-macos-dependencies.sh
|
||||
- name: Autogen
|
||||
@ -59,7 +59,7 @@ jobs:
|
||||
bs: [autotools, cmake]
|
||||
crypto: [mbedtls, nettle, openssl]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Update apt cache
|
||||
run: sudo apt-get update
|
||||
- name: Install dependencies
|
||||
@ -100,7 +100,7 @@ jobs:
|
||||
Ubuntu-distcheck:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Update package definitions
|
||||
run: sudo apt-get update
|
||||
- name: Install dependencies
|
||||
@ -127,7 +127,7 @@ jobs:
|
||||
matrix:
|
||||
be: [mingw-gcc, msvc]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Install mingw
|
||||
if: ${{ matrix.be=='mingw-gcc' }}
|
||||
run: choco install mingw
|
||||
|
||||
8
.github/workflows/codeql.yml
vendored
8
.github/workflows/codeql.yml
vendored
@ -26,18 +26,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/init@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/autobuild@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/analyze@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
||||
6
.github/workflows/scorecard.yml
vendored
6
.github/workflows/scorecard.yml
vendored
@ -29,12 +29,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
|
||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.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@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 3.17 FATAL_ERROR)
|
||||
|
||||
PROJECT(libarchive C)
|
||||
#
|
||||
# Include standard installation directories
|
||||
include(GNUInstallDirs)
|
||||
#
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
|
||||
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
|
||||
@ -16,7 +19,7 @@ endif()
|
||||
# MinSizeRel : Release Min Size build
|
||||
# None : No build type
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
|
||||
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
|
||||
# value type is "UNINITIALIZED".
|
||||
@ -255,6 +258,10 @@ OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
|
||||
OPTION(ENABLE_COVERAGE "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)" FALSE)
|
||||
OPTION(ENABLE_INSTALL "Enable installing of libraries" ON)
|
||||
|
||||
IF(WIN32 AND MSVC)
|
||||
OPTION(MSVC_USE_STATIC_CRT "Use static CRT" OFF)
|
||||
ENDIF()
|
||||
|
||||
SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
|
||||
SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
|
||||
SET(WINDOWS_VERSION "WIN10" CACHE STRING "Set Windows version to use (Windows only)")
|
||||
@ -1257,7 +1264,7 @@ ELSE(LIBXML2_FOUND)
|
||||
# Check linkage as well; versions of mingw-w64 before v11.0.0
|
||||
# do not contain an import library for xmllite.
|
||||
cmake_push_check_state()
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "xmllite")
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "xmllite" "uuid")
|
||||
check_c_source_compiles("
|
||||
#include <initguid.h>
|
||||
#include <xmllite.h>
|
||||
@ -1268,7 +1275,7 @@ ELSE(LIBXML2_FOUND)
|
||||
cmake_pop_check_state()
|
||||
IF(HAVE_XMLLITE_H)
|
||||
SET(XMLLITE_FOUND TRUE)
|
||||
LIST(APPEND ADDITIONAL_LIBS "xmllite")
|
||||
LIST(APPEND ADDITIONAL_LIBS "xmllite" "uuid")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF(EXPAT_FOUND)
|
||||
@ -1472,6 +1479,8 @@ CHECK_FUNCTION_EXISTS_GLIBC(arc4random_buf HAVE_ARC4RANDOM_BUF)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(closefrom HAVE_CLOSEFROM)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(close_range HAVE_CLOSE_RANGE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
|
||||
@ -1489,15 +1498,19 @@ CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getegid HAVE_GETEGID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getresgid HAVE_GETRESGID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getresuid HAVE_GETRESUID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(issetugid HAVE_ISSETUGID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN)
|
||||
@ -1516,6 +1529,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(posix_spawn HAVE_POSIX_SPAWN)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(posix_spawnp HAVE_POSIX_SPAWNP)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(readpassphrase HAVE_READPASSPHRASE)
|
||||
@ -1579,12 +1593,6 @@ CHECK_C_SOURCE_COMPILES(
|
||||
"#include <sys/types.h>\n#include <sys/mount.h>\nint main(void) { struct statfs s; return sizeof(s);}"
|
||||
HAVE_STRUCT_STATFS)
|
||||
|
||||
# Make sure we have the POSIX version of readdir_r, not the
|
||||
# older 2-argument version.
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
|
||||
HAVE_READDIR_R)
|
||||
|
||||
# dirfd can be either a function or a macro.
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); return dirfd(d);}"
|
||||
|
||||
243
Makefile.am
243
Makefile.am
@ -96,60 +96,73 @@ distclean-local:
|
||||
|
||||
include_HEADERS= libarchive/archive.h libarchive/archive_entry.h
|
||||
|
||||
libarchive_la_SOURCES= \
|
||||
libarchive/archive_acl.c \
|
||||
noinst_HEADERS= \
|
||||
libarchive/archive_acl_private.h \
|
||||
libarchive/archive_check_magic.c \
|
||||
libarchive/archive_cmdline.c \
|
||||
libarchive/archive_cmdline_private.h \
|
||||
libarchive/archive_crc32.h \
|
||||
libarchive/archive_cryptor.c \
|
||||
libarchive/archive_cryptor_private.h \
|
||||
libarchive/archive_digest.c \
|
||||
libarchive/archive_digest_private.h \
|
||||
libarchive/archive_endian.h \
|
||||
libarchive/archive_entry.c \
|
||||
libarchive/archive_entry.h \
|
||||
libarchive/archive_entry_copy_stat.c \
|
||||
libarchive/archive_entry_link_resolver.c \
|
||||
libarchive/archive_entry_locale.h \
|
||||
libarchive/archive_entry_private.h \
|
||||
libarchive/archive_hmac_private.h \
|
||||
libarchive/archive_openssl_evp_private.h \
|
||||
libarchive/archive_openssl_hmac_private.h \
|
||||
libarchive/archive_options_private.h \
|
||||
libarchive/archive_pack_dev.h \
|
||||
libarchive/archive_pathmatch.h \
|
||||
libarchive/archive_platform.h \
|
||||
libarchive/archive_platform_acl.h \
|
||||
libarchive/archive_platform_stat.h \
|
||||
libarchive/archive_platform_xattr.h \
|
||||
libarchive/archive_ppmd7_private.h \
|
||||
libarchive/archive_ppmd8_private.h \
|
||||
libarchive/archive_ppmd_private.h \
|
||||
libarchive/archive_private.h \
|
||||
libarchive/archive_random_private.h \
|
||||
libarchive/archive_rb.h \
|
||||
libarchive/archive_read_disk_private.h \
|
||||
libarchive/archive_read_private.h \
|
||||
libarchive/archive_string.h \
|
||||
libarchive/archive_string_composition.h \
|
||||
libarchive/archive_time_private.h \
|
||||
libarchive/archive_write_disk_private.h \
|
||||
libarchive/archive_write_private.h \
|
||||
libarchive/archive_write_set_format_private.h \
|
||||
libarchive/archive_xxhash.h \
|
||||
libarchive/config_freebsd.h \
|
||||
libarchive/filter_fork.h
|
||||
|
||||
libarchive_la_SOURCES= \
|
||||
libarchive/archive_acl.c \
|
||||
libarchive/archive_check_magic.c \
|
||||
libarchive/archive_cmdline.c \
|
||||
libarchive/archive_cryptor.c \
|
||||
libarchive/archive_digest.c \
|
||||
libarchive/archive_entry.c \
|
||||
libarchive/archive_entry_copy_stat.c \
|
||||
libarchive/archive_entry_link_resolver.c \
|
||||
libarchive/archive_entry_sparse.c \
|
||||
libarchive/archive_entry_stat.c \
|
||||
libarchive/archive_entry_strmode.c \
|
||||
libarchive/archive_entry_xattr.c \
|
||||
libarchive/archive_hmac.c \
|
||||
libarchive/archive_hmac_private.h \
|
||||
libarchive/archive_match.c \
|
||||
libarchive/archive_openssl_evp_private.h \
|
||||
libarchive/archive_openssl_hmac_private.h \
|
||||
libarchive/archive_options.c \
|
||||
libarchive/archive_options_private.h \
|
||||
libarchive/archive_pack_dev.h \
|
||||
libarchive/archive_pack_dev.c \
|
||||
libarchive/archive_parse_date.c \
|
||||
libarchive/archive_pathmatch.c \
|
||||
libarchive/archive_pathmatch.h \
|
||||
libarchive/archive_platform.h \
|
||||
libarchive/archive_platform_acl.h \
|
||||
libarchive/archive_platform_xattr.h \
|
||||
libarchive/archive_ppmd_private.h \
|
||||
libarchive/archive_ppmd7.c \
|
||||
libarchive/archive_ppmd7_private.h \
|
||||
libarchive/archive_ppmd8.c \
|
||||
libarchive/archive_ppmd8_private.h \
|
||||
libarchive/archive_private.h \
|
||||
libarchive/archive_random.c \
|
||||
libarchive/archive_random_private.h \
|
||||
libarchive/archive_rb.c \
|
||||
libarchive/archive_rb.h \
|
||||
libarchive/archive_read.c \
|
||||
libarchive/archive_read_add_passphrase.c \
|
||||
libarchive/archive_read_append_filter.c \
|
||||
libarchive/archive_read_data_into_fd.c \
|
||||
libarchive/archive_read_disk_entry_from_file.c \
|
||||
libarchive/archive_read_disk_posix.c \
|
||||
libarchive/archive_read_disk_private.h \
|
||||
libarchive/archive_read_disk_set_standard_lookup.c \
|
||||
libarchive/archive_read_extract.c \
|
||||
libarchive/archive_read_extract2.c \
|
||||
@ -157,12 +170,11 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_read_open_file.c \
|
||||
libarchive/archive_read_open_filename.c \
|
||||
libarchive/archive_read_open_memory.c \
|
||||
libarchive/archive_read_private.h \
|
||||
libarchive/archive_read_set_format.c \
|
||||
libarchive/archive_read_set_options.c \
|
||||
libarchive/archive_read_support_filter_all.c \
|
||||
libarchive/archive_read_support_filter_bzip2.c \
|
||||
libarchive/archive_read_support_filter_by_code.c \
|
||||
libarchive/archive_read_support_filter_bzip2.c \
|
||||
libarchive/archive_read_support_filter_compress.c \
|
||||
libarchive/archive_read_support_filter_grzip.c \
|
||||
libarchive/archive_read_support_filter_gzip.c \
|
||||
@ -193,23 +205,12 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_read_support_format_xar.c \
|
||||
libarchive/archive_read_support_format_zip.c \
|
||||
libarchive/archive_string.c \
|
||||
libarchive/archive_string.h \
|
||||
libarchive/archive_string_composition.h \
|
||||
libarchive/archive_string_sprintf.c \
|
||||
libarchive/archive_time.c \
|
||||
libarchive/archive_time_private.h \
|
||||
libarchive/archive_util.c \
|
||||
libarchive/archive_version_details.c \
|
||||
libarchive/archive_virtual.c \
|
||||
libarchive/archive_write.c \
|
||||
libarchive/archive_write_disk_posix.c \
|
||||
libarchive/archive_write_disk_private.h \
|
||||
libarchive/archive_write_disk_set_standard_lookup.c \
|
||||
libarchive/archive_write_open_fd.c \
|
||||
libarchive/archive_write_open_file.c \
|
||||
libarchive/archive_write_open_filename.c \
|
||||
libarchive/archive_write_open_memory.c \
|
||||
libarchive/archive_write_private.h \
|
||||
libarchive/archive_write_add_filter.c \
|
||||
libarchive/archive_write_add_filter_b64encode.c \
|
||||
libarchive/archive_write_add_filter_by_name.c \
|
||||
@ -225,6 +226,12 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_write_add_filter_uuencode.c \
|
||||
libarchive/archive_write_add_filter_xz.c \
|
||||
libarchive/archive_write_add_filter_zstd.c \
|
||||
libarchive/archive_write_disk_posix.c \
|
||||
libarchive/archive_write_disk_set_standard_lookup.c \
|
||||
libarchive/archive_write_open_fd.c \
|
||||
libarchive/archive_write_open_file.c \
|
||||
libarchive/archive_write_open_filename.c \
|
||||
libarchive/archive_write_open_memory.c \
|
||||
libarchive/archive_write_set_format.c \
|
||||
libarchive/archive_write_set_format_7zip.c \
|
||||
libarchive/archive_write_set_format_ar.c \
|
||||
@ -234,59 +241,54 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_write_set_format_cpio_newc.c \
|
||||
libarchive/archive_write_set_format_cpio_odc.c \
|
||||
libarchive/archive_write_set_format_filter_by_ext.c \
|
||||
libarchive/archive_write_set_format_gnutar.c \
|
||||
libarchive/archive_write_set_format_iso9660.c \
|
||||
libarchive/archive_write_set_format_mtree.c \
|
||||
libarchive/archive_write_set_format_pax.c \
|
||||
libarchive/archive_write_set_format_private.h \
|
||||
libarchive/archive_write_set_format_raw.c \
|
||||
libarchive/archive_write_set_format_shar.c \
|
||||
libarchive/archive_write_set_format_ustar.c \
|
||||
libarchive/archive_write_set_format_v7tar.c \
|
||||
libarchive/archive_write_set_format_gnutar.c \
|
||||
libarchive/archive_write_set_format_warc.c \
|
||||
libarchive/archive_write_set_format_xar.c \
|
||||
libarchive/archive_write_set_format_zip.c \
|
||||
libarchive/archive_write_set_options.c \
|
||||
libarchive/archive_write_set_passphrase.c \
|
||||
libarchive/archive_xxhash.h \
|
||||
libarchive/config_freebsd.h \
|
||||
libarchive/filter_fork_posix.c \
|
||||
libarchive/filter_fork.h \
|
||||
libarchive/xxhash.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+= \
|
||||
libarchive/archive_windows.h
|
||||
libarchive_la_SOURCES+= \
|
||||
libarchive/archive_entry_copy_bhfi.c \
|
||||
libarchive/archive_read_disk_windows.c \
|
||||
libarchive/archive_windows.h \
|
||||
libarchive/archive_windows.c \
|
||||
libarchive/archive_write_disk_windows.c \
|
||||
libarchive/filter_fork_windows.c
|
||||
endif
|
||||
|
||||
if INC_BLAKE2
|
||||
libarchive_la_SOURCES+= \
|
||||
noinst_HEADERS+= \
|
||||
libarchive/archive_blake2.h \
|
||||
libarchive/archive_blake2_impl.h \
|
||||
libarchive/archive_blake2_impl.h
|
||||
libarchive_la_SOURCES+= \
|
||||
libarchive/archive_blake2s_ref.c \
|
||||
libarchive/archive_blake2sp_ref.c
|
||||
endif
|
||||
|
||||
if INC_LINUX_ACL
|
||||
libarchive_la_SOURCES+= libarchive/archive_disk_acl_linux.c
|
||||
else
|
||||
endif
|
||||
if INC_SUNOS_ACL
|
||||
libarchive_la_SOURCES+= libarchive/archive_disk_acl_sunos.c
|
||||
else
|
||||
endif
|
||||
if INC_DARWIN_ACL
|
||||
libarchive_la_SOURCES+= libarchive/archive_disk_acl_darwin.c
|
||||
else
|
||||
endif
|
||||
if INC_FREEBSD_ACL
|
||||
libarchive_la_SOURCES+= libarchive/archive_disk_acl_freebsd.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# -no-undefined marks that libarchive doesn't rely on symbols
|
||||
# defined in the application. This is mandatory for cygwin.
|
||||
@ -350,22 +352,24 @@ pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = build/pkgconfig/libarchive.pc
|
||||
|
||||
# Sources needed by all test programs
|
||||
noinst_HEADERS+= \
|
||||
test_utils/test_common.h \
|
||||
test_utils/test_utils.h
|
||||
test_utils_SOURCES= \
|
||||
test_utils/test_utils.c \
|
||||
test_utils/test_utils.h \
|
||||
test_utils/test_main.c \
|
||||
test_utils/test_common.h
|
||||
test_utils/test_utils.c
|
||||
|
||||
#
|
||||
#
|
||||
# libarchive_test program
|
||||
#
|
||||
#
|
||||
noinst_HEADERS+= \
|
||||
libarchive/test/test.h
|
||||
libarchive_test_SOURCES= \
|
||||
$(libarchive_la_SOURCES) \
|
||||
$(test_utils_SOURCES) \
|
||||
libarchive/test/read_open_memory.c \
|
||||
libarchive/test/test.h \
|
||||
libarchive/test/test_7zip_filename_encoding.c \
|
||||
libarchive/test/test_acl_nfs4.c \
|
||||
libarchive/test/test_acl_pax.c \
|
||||
@ -465,6 +469,7 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_read_format_7zip_encryption_data.c \
|
||||
libarchive/test/test_read_format_7zip_encryption_partially.c \
|
||||
libarchive/test/test_read_format_7zip_encryption_header.c \
|
||||
libarchive/test/test_read_format_7zip_issue2765.c \
|
||||
libarchive/test/test_read_format_7zip_malformed.c \
|
||||
libarchive/test/test_read_format_7zip_packinfo_digests.c \
|
||||
libarchive/test/test_read_format_ar.c \
|
||||
@ -525,14 +530,17 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_read_format_rar5.c \
|
||||
libarchive/test/test_read_format_raw.c \
|
||||
libarchive/test/test_read_format_tar.c \
|
||||
libarchive/test/test_read_format_tar_V_negative_size.c \
|
||||
libarchive/test/test_read_format_tar_concatenated.c \
|
||||
libarchive/test/test_read_format_tar_empty_pax.c \
|
||||
libarchive/test/test_read_format_tar_empty_filename.c \
|
||||
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_mac_metadata.c \
|
||||
libarchive/test/test_read_format_tar_pax_g_large.c \
|
||||
libarchive/test/test_read_format_tar_pax_large_attr.c \
|
||||
libarchive/test/test_read_format_tar_pax_negative_time.c \
|
||||
libarchive/test/test_read_format_tbz.c \
|
||||
libarchive/test/test_read_format_tgz.c \
|
||||
libarchive/test/test_read_format_tlz.c \
|
||||
@ -565,6 +573,7 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_read_format_zip_zip64.c \
|
||||
libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c \
|
||||
libarchive/test/test_read_large.c \
|
||||
libarchive/test/test_read_pax_empty_val_no_nl.c \
|
||||
libarchive/test/test_read_pax_xattr_rht_security_selinux.c \
|
||||
libarchive/test/test_read_pax_xattr_schily.c \
|
||||
libarchive/test/test_read_pax_truncated.c \
|
||||
@ -667,7 +676,6 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_write_read_format_zip.c \
|
||||
libarchive/test/test_xattr_platform.c \
|
||||
libarchive/test/test_zip_filename_encoding.c
|
||||
|
||||
libarchive_test_CPPFLAGS= \
|
||||
-I$(top_srcdir)/libarchive \
|
||||
-I$(top_srcdir)/libarchive/test \
|
||||
@ -680,9 +688,9 @@ libarchive_test_LDADD= $(LTLIBICONV)
|
||||
# The "list.h" file just lists all of the tests defined in all of the sources.
|
||||
# Building it automatically provides a sanity-check on libarchive_test_SOURCES
|
||||
# above.
|
||||
libarchive/test/list.h: Makefile
|
||||
libarchive/test/list.h: $(libarchive_test_SOURCES)
|
||||
$(MKDIR_P) libarchive/test
|
||||
cat $(top_srcdir)/libarchive/test/test_*.c | grep '^DEFINE_TEST' > libarchive/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test LRZIP=NOCONFIG
|
||||
|
||||
@ -702,6 +710,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_compat_lz4_2.tar.lz4.uu \
|
||||
libarchive/test/test_compat_lz4_3.tar.lz4.uu \
|
||||
libarchive/test/test_compat_lz4_B4.tar.lz4.uu \
|
||||
libarchive/test/test_compat_lz4_skippable_frames_B4.tar.lz4.uu \
|
||||
libarchive/test/test_compat_lz4_B4BD.tar.lz4.uu \
|
||||
libarchive/test/test_compat_lz4_B4BDBX.tar.lz4.uu \
|
||||
libarchive/test/test_compat_lz4_B5.tar.lz4.uu \
|
||||
@ -808,6 +817,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
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_issue2765.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 \
|
||||
@ -918,6 +928,9 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_rar4_encrypted_filenames.rar.uu \
|
||||
libarchive/test/test_read_format_rar4_solid_encrypted.rar.uu \
|
||||
libarchive/test/test_read_format_rar4_solid_encrypted_filenames.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_encrypted.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_encrypted_filenames.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_solid_encrypted.rar.uu \
|
||||
@ -949,6 +962,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_rar5_multiple_files.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_nonempty_dir_stream.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_dirdata.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_owner.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_sfx.exe.uu \
|
||||
@ -957,6 +971,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_rar5_stored_manyfiles.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_symlink.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_truncated_huff.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_unicode.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_win32.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \
|
||||
@ -969,14 +984,17 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_raw.data.gz.uu \
|
||||
libarchive/test/test_read_format_raw.data.Z.uu \
|
||||
libarchive/test/test_read_format_raw.data.uu \
|
||||
libarchive/test/test_read_format_tar_V_negative_size.tar.uu \
|
||||
libarchive/test/test_read_format_tar_concatenated.tar.uu \
|
||||
libarchive/test/test_read_format_tar_empty_filename.tar.uu \
|
||||
libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu \
|
||||
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_mac_metadata_1.tar.uu \
|
||||
libarchive/test/test_read_format_tar_pax_g_large.tar.uu \
|
||||
libarchive/test/test_read_format_tar_pax_large_attr.tar.Z.uu \
|
||||
libarchive/test/test_read_format_tar_pax_negative_time.tar.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 \
|
||||
@ -1041,6 +1059,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_large_splitted_rar_ac.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ad.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ae.uu \
|
||||
libarchive/test/test_read_pax_empty_val_no_nl.tar.uu \
|
||||
libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu \
|
||||
libarchive/test/test_read_pax_xattr_schily.tar.uu \
|
||||
libarchive/test/test_read_splitted_rar_aa.uu \
|
||||
@ -1052,6 +1071,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_splitted_rar_seek_support_ab.uu \
|
||||
libarchive/test/test_splitted_rar_seek_support_ac.uu \
|
||||
libarchive/test/test_write_disk_appledouble.cpio.gz.uu \
|
||||
libarchive/test/test_write_disk_appledouble_zip.zip.uu \
|
||||
libarchive/test/test_write_disk_hfs_compression.tgz.uu \
|
||||
libarchive/test/test_write_disk_mac_metadata.tar.gz.uu \
|
||||
libarchive/test/test_write_disk_no_hfs_compression.tgz.uu \
|
||||
@ -1061,14 +1081,15 @@ libarchive_test_EXTRA_DIST=\
|
||||
#
|
||||
# Common code for libarchive frontends (cpio, tar)
|
||||
#
|
||||
libarchive_fe_la_SOURCES= \
|
||||
libarchive_fe/err.c \
|
||||
libarchive_fe/err.h \
|
||||
noinst_HEADERS+= \
|
||||
libarchive_fe/lafe_err.h \
|
||||
libarchive_fe/lafe_platform.h \
|
||||
libarchive_fe/line_reader.c \
|
||||
libarchive_fe/line_reader.h \
|
||||
libarchive_fe/passphrase.c \
|
||||
libarchive_fe/passphrase.h
|
||||
libarchive_fe_la_SOURCES= \
|
||||
libarchive_fe/lafe_err.c \
|
||||
libarchive_fe/line_reader.c \
|
||||
libarchive_fe/passphrase.c
|
||||
|
||||
libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
|
||||
#
|
||||
@ -1077,21 +1098,23 @@ libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
|
||||
#
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
tar/bsdtar.h \
|
||||
tar/bsdtar_platform.h
|
||||
bsdtar_SOURCES= \
|
||||
tar/bsdtar.c \
|
||||
tar/bsdtar.h \
|
||||
tar/bsdtar_platform.h \
|
||||
tar/cmdline.c \
|
||||
tar/creation_set.c \
|
||||
tar/read.c \
|
||||
tar/subst.c \
|
||||
tar/util.c \
|
||||
tar/write.c
|
||||
tar/bsdtar.c \
|
||||
tar/cmdline.c \
|
||||
tar/creation_set.c \
|
||||
tar/read.c \
|
||||
tar/subst.c \
|
||||
tar/util.c \
|
||||
tar/write.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+= \
|
||||
tar/bsdtar_windows.h
|
||||
bsdtar_SOURCES+= \
|
||||
tar/bsdtar_windows.h \
|
||||
tar/bsdtar_windows.c
|
||||
tar/bsdtar_windows.c
|
||||
endif
|
||||
|
||||
bsdtar_DEPENDENCIES= libarchive.la libarchive_fe.la
|
||||
@ -1128,12 +1151,15 @@ endif
|
||||
# bsdtar_test
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
tar/test/test.h
|
||||
|
||||
bsdtar_test_SOURCES= \
|
||||
$(test_utils_SOURCES) \
|
||||
tar/test/test.h \
|
||||
tar/test/test_0.c \
|
||||
tar/test/test_basic.c \
|
||||
tar/test/test_copy.c \
|
||||
tar/test/test_crlf_mtree.c \
|
||||
tar/test/test_empty_mtree.c \
|
||||
tar/test/test_extract_tar_Z.c \
|
||||
tar/test/test_extract_tar_bz2.c \
|
||||
@ -1210,9 +1236,9 @@ bsdtar_test_CPPFLAGS=\
|
||||
-I$(top_builddir)/tar/test \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
|
||||
tar/test/list.h: Makefile
|
||||
tar/test/list.h: $(bsdtar_test_SOURCES)
|
||||
$(MKDIR_P) tar/test
|
||||
cat $(top_srcdir)/tar/test/test_*.c | grep '^DEFINE_TEST' > tar/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDTAR
|
||||
bsdtar_test_programs= bsdtar_test
|
||||
@ -1253,16 +1279,18 @@ bsdtar_test_EXTRA_DIST= \
|
||||
#
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
cpio/cpio.h \
|
||||
cpio/cpio_platform.h
|
||||
bsdcpio_SOURCES= \
|
||||
cpio/cmdline.c \
|
||||
cpio/cpio.c \
|
||||
cpio/cpio.h \
|
||||
cpio/cpio_platform.h
|
||||
cpio/cmdline.c \
|
||||
cpio/cpio.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+= \
|
||||
cpio/cpio_windows.h
|
||||
bsdcpio_SOURCES+= \
|
||||
cpio/cpio_windows.h \
|
||||
cpio/cpio_windows.c
|
||||
cpio/cpio_windows.c
|
||||
endif
|
||||
|
||||
bsdcpio_DEPENDENCIES = libarchive.la libarchive_fe.la
|
||||
@ -1301,10 +1329,11 @@ endif
|
||||
# bsdcpio_test
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
cpio/test/test.h
|
||||
bsdcpio_test_SOURCES= \
|
||||
$(test_utils_SOURCES) \
|
||||
cpio/cmdline.c \
|
||||
cpio/test/test.h \
|
||||
cpio/test/test_0.c \
|
||||
cpio/test/test_basic.c \
|
||||
cpio/test/test_cmdline.c \
|
||||
@ -1363,9 +1392,9 @@ bsdcpio_test_CPPFLAGS= \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
bsdcpio_test_LDADD=libarchive_fe.la
|
||||
|
||||
cpio/test/list.h: Makefile
|
||||
cpio/test/list.h: $(bsdcpio_test_SOURCES)
|
||||
$(MKDIR_P) cpio/test
|
||||
cat $(top_srcdir)/cpio/test/test_*.c | grep '^DEFINE_TEST' > cpio/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDCPIO
|
||||
bsdcpio_test_programs= bsdcpio_test
|
||||
@ -1410,13 +1439,15 @@ bsdcpio_test_EXTRA_DIST= \
|
||||
#
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
cat/bsdcat.h \
|
||||
cat/bsdcat_platform.h
|
||||
bsdcat_SOURCES= \
|
||||
cat/bsdcat.c \
|
||||
cat/bsdcat.h \
|
||||
cat/bsdcat_platform.h \
|
||||
cat/cmdline.c
|
||||
cat/bsdcat.c \
|
||||
cat/cmdline.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+=
|
||||
bsdcat_SOURCES+=
|
||||
endif
|
||||
|
||||
@ -1453,9 +1484,10 @@ endif
|
||||
# bsdcat_test
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
cat/test/test.h
|
||||
bsdcat_test_SOURCES= \
|
||||
$(test_utils_SOURCES) \
|
||||
cat/test/test.h \
|
||||
cat/test/test_0.c \
|
||||
cat/test/test_empty_gz.c \
|
||||
cat/test/test_empty_lz4.c \
|
||||
@ -1483,9 +1515,9 @@ bsdcat_test_CPPFLAGS= \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
bsdcat_test_LDADD=libarchive_fe.la
|
||||
|
||||
cat/test/list.h: Makefile
|
||||
cat/test/list.h: $(bsdcat_test_SOURCES)
|
||||
$(MKDIR_P) cat/test
|
||||
cat $(top_srcdir)/cat/test/test_*.c | grep '^DEFINE_TEST' > cat/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDCAT
|
||||
bsdcat_test_programs= bsdcat_test
|
||||
@ -1516,16 +1548,18 @@ bsdcat_test_EXTRA_DIST= \
|
||||
#
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
unzip/bsdunzip.h \
|
||||
unzip/bsdunzip_platform.h \
|
||||
unzip/la_getline.h \
|
||||
unzip/la_queue.h
|
||||
bsdunzip_SOURCES= \
|
||||
unzip/bsdunzip.c \
|
||||
unzip/bsdunzip.h \
|
||||
unzip/bsdunzip_platform.h \
|
||||
unzip/cmdline.c \
|
||||
unzip/la_getline.c \
|
||||
unzip/la_getline.h \
|
||||
unzip/la_queue.h
|
||||
unzip/bsdunzip.c \
|
||||
unzip/cmdline.c \
|
||||
unzip/la_getline.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+=
|
||||
bsdunzip_SOURCES+=
|
||||
endif
|
||||
|
||||
@ -1562,9 +1596,10 @@ endif
|
||||
# bsdunzip_test
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
unzip/test/test.h
|
||||
bsdunzip_test_SOURCES= \
|
||||
$(test_utils_SOURCES) \
|
||||
unzip/test/test.h \
|
||||
unzip/test/test_0.c \
|
||||
unzip/test/test_basic.c \
|
||||
unzip/test/test_doubledash.c \
|
||||
@ -1595,9 +1630,9 @@ bsdunzip_test_CPPFLAGS= \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
bsdunzip_test_LDADD=libarchive_fe.la
|
||||
|
||||
unzip/test/list.h: Makefile
|
||||
unzip/test/list.h: $(bsdunzip_test_SOURCES)
|
||||
$(MKDIR_P) unzip/test
|
||||
cat $(top_srcdir)/unzip/test/test_*.c | grep '^DEFINE_TEST' > unzip/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDUNZIP
|
||||
bsdunzip_test_programs= bsdunzip_test
|
||||
|
||||
18
NEWS
18
NEWS
@ -1,3 +1,21 @@
|
||||
Dec 01, 2025: libarchive 3.8.4 released
|
||||
|
||||
Nov 17, 2025: libarchive 3.8.3 released
|
||||
|
||||
Oct 15, 2025: libarchive 3.8.2 released
|
||||
|
||||
Jun 01, 2025: libarchive 3.8.1 released
|
||||
|
||||
May 20, 2025: libarchive 3.8.0 released
|
||||
|
||||
Mar 30, 2025: libarchive 3.7.9 released
|
||||
|
||||
Mar 20, 2025: libarchive 3.7.8 released
|
||||
|
||||
Oct 13, 2024: libarchive 3.7.7 released
|
||||
|
||||
Sep 23, 2024: libarchive 3.7.6 released
|
||||
|
||||
Sep 13, 2024: libarchive 3.7.5 released
|
||||
|
||||
Apr 26, 2024: libarchive 3.7.4 released
|
||||
|
||||
@ -16,4 +16,4 @@ Please provide the following information in your report:
|
||||
- How to reproduce the issue
|
||||
|
||||
This project is maintained by volunteers on a reasonable-effort basis. As such, we ask
|
||||
that you give me 90 days to work on a fix before public exposure.
|
||||
that you give us 90 days to work on a fix before public exposure.
|
||||
|
||||
@ -23,7 +23,7 @@ then
|
||||
tunefs -N enable /dev/$MD
|
||||
mount /dev/$MD /tmp_acl_nfsv4
|
||||
chmod 1777 /tmp_acl_nfsv4
|
||||
pkg install -y autoconf automake cmake libiconv libtool pkgconf expat libxml2 liblz4 zstd
|
||||
pkg install -y autoconf automake cmake libiconv libtool pkgconf expat libxml2 liblz4 zstd gmake
|
||||
elif [ "${UNAME}" = "Darwin" ]
|
||||
then
|
||||
set -x -e
|
||||
|
||||
@ -5,6 +5,9 @@ set -eux
|
||||
#brew update > /dev/null
|
||||
#brew upgrade > /dev/null
|
||||
|
||||
# Workaround for cmake in local/pinned tap issue
|
||||
brew uninstall cmake
|
||||
|
||||
# This does an upgrade if the package is already installed
|
||||
brew install \
|
||||
autoconf \
|
||||
|
||||
@ -29,5 +29,5 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in
|
||||
# And install it, of course ;).
|
||||
IF(ENABLE_INSTALL)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc
|
||||
DESTINATION "lib/pkgconfig")
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
ENDIF()
|
||||
|
||||
@ -405,6 +405,12 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
#cmakedefine HAVE_CHROOT 1
|
||||
|
||||
/* Define to 1 if you have the `closefrom' function. */
|
||||
#cmakedefine HAVE_CLOSEFROM 1
|
||||
|
||||
/* Define to 1 if you have the `close_range' function. */
|
||||
#cmakedefine HAVE_CLOSE_RANGE 1
|
||||
|
||||
/* Define to 1 if you have the <copyfile.h> header file. */
|
||||
#cmakedefine HAVE_COPYFILE_H 1
|
||||
|
||||
@ -970,9 +976,6 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#cmakedefine HAVE_PWD_H 1
|
||||
|
||||
/* Define to 1 if you have the `readdir_r' function. */
|
||||
#cmakedefine HAVE_READDIR_R 1
|
||||
|
||||
/* Define to 1 if you have the `readlink' function. */
|
||||
#cmakedefine HAVE_READLINK 1
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
3008000
|
||||
3008004
|
||||
|
||||
@ -13,8 +13,8 @@ IF(ENABLE_CAT)
|
||||
bsdcat.h
|
||||
bsdcat_platform.h
|
||||
cmdline.c
|
||||
../libarchive_fe/err.c
|
||||
../libarchive_fe/err.h
|
||||
../libarchive_fe/lafe_err.c
|
||||
../libarchive_fe/lafe_err.h
|
||||
../libarchive_fe/lafe_platform.h
|
||||
)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
|
||||
|
||||
15
cat/bsdcat.c
15
cat/bsdcat.c
@ -7,6 +7,9 @@
|
||||
|
||||
#include "bsdcat_platform.h"
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
@ -22,7 +25,7 @@
|
||||
#include <archive_entry.h>
|
||||
|
||||
#include "bsdcat.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
#define BYTES_PER_BLOCK (20*512)
|
||||
|
||||
@ -105,6 +108,16 @@ main(int argc, char **argv)
|
||||
bsdcat = &bsdcat_storage;
|
||||
memset(bsdcat, 0, sizeof(*bsdcat));
|
||||
|
||||
#if defined(HAVE_SIGACTION) && defined(SIGCHLD)
|
||||
{ /* Do not ignore SIGCHLD. */
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
lafe_setprogname(*argv, "bsdcat");
|
||||
|
||||
bsdcat->argv = argv;
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include "bsdcat.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
/*
|
||||
* Short options for bsdcat. Please keep this sorted.
|
||||
|
||||
40
configure.ac
40
configure.ac
@ -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.8.0dev])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3008000])
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.8.4])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3008004])
|
||||
|
||||
dnl bsdtar and bsdcpio versioning tracks libarchive
|
||||
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
|
||||
@ -258,7 +258,8 @@ AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ])
|
||||
case $host in
|
||||
*mingw* | *cygwin* | *msys* )
|
||||
AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#ifdef _WIN32_WINNT
|
||||
[[#include <windows.h>
|
||||
#ifdef _WIN32_WINNT
|
||||
# error _WIN32_WINNT already defined
|
||||
#endif
|
||||
]],[[;]])
|
||||
@ -267,7 +268,8 @@ case $host in
|
||||
AC_DEFINE([NTDDI_VERSION], 0x05020000, [Define to '0x05020000' for Windows Server 2003 APIs.])
|
||||
])
|
||||
AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#ifdef WINVER
|
||||
[[#include <windows.h>
|
||||
#ifdef WINVER
|
||||
# error WINVER already defined
|
||||
#endif
|
||||
]],[[;]])
|
||||
@ -436,13 +438,15 @@ if test "x$with_bz2lib" != "xno"; then
|
||||
esac
|
||||
fi
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_ARG_WITH([libb2],
|
||||
AS_HELP_STRING([--without-libb2], [Don't build support for BLAKE2 through libb2]))
|
||||
|
||||
if test "x$with_libb2" != "xno"; then
|
||||
AC_CHECK_HEADERS([blake2.h])
|
||||
AC_CHECK_LIB(b2,blake2sp_init)
|
||||
BLAKE2_PC_VER=`pkg-config --modversion libb2`
|
||||
BLAKE2_PC_VER=`$PKG_CONFIG --modversion libb2`
|
||||
if test "x$BLAKE2_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBB2_PKGCONFIG_VERSION], ["$BLAKE2_PC_VER"], [Libb2 version coming from pkg-config.])
|
||||
fi
|
||||
@ -817,16 +821,20 @@ AC_FUNC_VPRINTF
|
||||
# To avoid necessity for including windows.h or special forward declaration
|
||||
# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
|
||||
AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
|
||||
AC_CHECK_FUNCS([arc4random_buf chflags chown chroot ctime_r])
|
||||
AC_CHECK_FUNCS([arc4random_buf chflags chown chroot])
|
||||
AC_CHECK_FUNCS([closefrom close_range ctime_r])
|
||||
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fnmatch fork])
|
||||
AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
|
||||
AC_CHECK_FUNCS([futimens futimes futimesat])
|
||||
AC_CHECK_FUNCS([geteuid getline getpid getgrgid_r getgrnam_r])
|
||||
AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
|
||||
AC_CHECK_FUNCS([getegid geteuid getline getpid getresgid getresuid])
|
||||
AC_CHECK_FUNCS([getgrgid_r getgrnam_r getpwnam_r getpwuid_r])
|
||||
AC_CHECK_FUNCS([getvfsbyname gmtime_r])
|
||||
AC_CHECK_FUNCS([issetugid])
|
||||
AC_CHECK_FUNCS([lchflags lchmod lchown link linkat localtime_r lstat lutimes])
|
||||
AC_CHECK_FUNCS([mbrtowc memmove memset])
|
||||
AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
|
||||
AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat])
|
||||
AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawn posix_spawnp])
|
||||
AC_CHECK_FUNCS([readlink readlinkat])
|
||||
AC_CHECK_FUNCS([readpassphrase])
|
||||
AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
|
||||
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strnlen strrchr symlink])
|
||||
@ -877,14 +885,6 @@ AC_CHECK_TYPES(struct statfs,,,
|
||||
#include <sys/mount.h>
|
||||
])
|
||||
|
||||
# There are several variants of readdir_r around; we only
|
||||
# accept the POSIX-compliant version.
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <dirent.h>]],
|
||||
[[DIR *dir; struct dirent e, *r;
|
||||
return(readdir_r(dir, &e, &r));]])],
|
||||
[AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])]
|
||||
)
|
||||
# dirfd can be either a function or a macro.
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <dirent.h>
|
||||
@ -925,7 +925,7 @@ if test "x$enable_xattr" != "xno"; then
|
||||
])
|
||||
AC_CHECK_DECLS([XATTR_NOFOLLOW], [], [], [#include <sys/xattr.h>
|
||||
])
|
||||
ATTR_PC_VER=`pkg-config --modversion libattr`
|
||||
ATTR_PC_VER=`$PKG_CONFIG --modversion libattr`
|
||||
if test "x$ATTR_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBATTR_PKGCONFIG_VERSION], ["$ATTR_PC_VER"], [Libattr version coming from pkg-config.])
|
||||
fi
|
||||
@ -1024,7 +1024,7 @@ AC_ARG_ENABLE([acl],
|
||||
if test "x$enable_acl" != "xno"; then
|
||||
# Libacl
|
||||
AC_CHECK_LIB([acl], [acl_get_file])
|
||||
ACL_PC_VER=`pkg-config --modversion libacl`
|
||||
ACL_PC_VER=`$PKG_CONFIG --modversion libacl`
|
||||
if test "x$ACL_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBACL_PKGCONFIG_VERSION], ["$ACL_PC_VER"], [Libacl version coming from pkg-config.])
|
||||
fi
|
||||
@ -1038,7 +1038,7 @@ if test "x$enable_acl" != "xno"; then
|
||||
])
|
||||
|
||||
AC_CHECK_LIB([richacl], [richacl_get_file])
|
||||
RICHACL_PC_VER=`pkg-config --modversion librichacl`
|
||||
RICHACL_PC_VER=`$PKG_CONFIG --modversion librichacl`
|
||||
if test "x$RICHACL_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBRICHACL_PKGCONFIG_VERSION], ["$RICHACL_PC_VER"], [Librichacl version coming from pkg-config.])
|
||||
fi
|
||||
|
||||
@ -151,7 +151,7 @@ else
|
||||
libarchive_host_src_files :=
|
||||
endif
|
||||
|
||||
libarchive_fe_src_files := libarchive_fe/err.c \
|
||||
libarchive_fe_src_files := libarchive_fe/lafe_err.c \
|
||||
libarchive_fe/line_reader.c \
|
||||
libarchive_fe/passphrase.c
|
||||
|
||||
|
||||
@ -40,6 +40,8 @@
|
||||
|
||||
#define HAVE_CHOWN 1
|
||||
#define HAVE_CHROOT 1
|
||||
#define HAVE_CLOSEFROM 1
|
||||
#define HAVE_CLOSE_RANGE 1
|
||||
#define HAVE_CTIME_R 1
|
||||
#define HAVE_CTYPE_H 1
|
||||
#define HAVE_DECL_EXTATTR_NAMESPACE_USER 0
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
#define HAVE_CHOWN 1
|
||||
#define HAVE_CHROOT 1
|
||||
#define HAVE_CLOSEFROM 1
|
||||
#define HAVE_CLOSE_RANGE 1
|
||||
#define HAVE_CTIME_R 1
|
||||
#define HAVE_CTYPE_H 1
|
||||
#define HAVE_DECL_EXTATTR_NAMESPACE_USER 0
|
||||
@ -180,7 +182,7 @@
|
||||
#define HAVE_WMEMCMP 1
|
||||
#define HAVE_WMEMCPY 1
|
||||
#define HAVE_ZLIB_H 1
|
||||
#define ICONV_CONST
|
||||
#define ICONV_CONST
|
||||
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
|
||||
#define SIZEOF_WCHAR_T 4
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
@ -175,6 +175,12 @@
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
/* #undef HAVE_CHROOT */
|
||||
|
||||
/* Define to 1 if you have the `closefrom' function. */
|
||||
/* #undef HAVE_CLOSEFROM */
|
||||
|
||||
/* Define to 1 if you have the `close_range' function. */
|
||||
/* #undef HAVE_CLOSE_RANGE */
|
||||
|
||||
/* Define to 1 if you have the <copyfile.h> header file. */
|
||||
/* #undef HAVE_COPYFILE_H */
|
||||
|
||||
@ -620,9 +626,6 @@
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
/* #undef HAVE_PWD_H */
|
||||
|
||||
/* Define to 1 if you have a POSIX compatible readdir_r */
|
||||
#define HAVE_READDIR_R 1
|
||||
|
||||
/* Define to 1 if you have the `readlink' function. */
|
||||
/* #undef HAVE_READLINK */
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Macros for file64 functions
|
||||
*
|
||||
* Android does not support the macro _FILE_OFFSET_BITS=64
|
||||
@ -19,7 +19,6 @@
|
||||
#include <sys/vfs.h>
|
||||
|
||||
//dirent.h
|
||||
#define readdir_r readdir64_r
|
||||
#define readdir readdir64
|
||||
#define dirent dirent64
|
||||
//fcntl.h
|
||||
|
||||
@ -13,8 +13,8 @@ IF(ENABLE_CPIO)
|
||||
cpio.c
|
||||
cpio.h
|
||||
cpio_platform.h
|
||||
../libarchive_fe/err.c
|
||||
../libarchive_fe/err.h
|
||||
../libarchive_fe/lafe_err.c
|
||||
../libarchive_fe/lafe_err.h
|
||||
../libarchive_fe/lafe_platform.h
|
||||
../libarchive_fe/line_reader.c
|
||||
../libarchive_fe/line_reader.h
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
#endif
|
||||
|
||||
#include "cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
/*
|
||||
* Short options for cpio. Please keep this sorted.
|
||||
|
||||
14
cpio/cpio.c
14
cpio/cpio.c
@ -60,7 +60,7 @@
|
||||
#endif
|
||||
|
||||
#include "cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
#include "line_reader.h"
|
||||
#include "passphrase.h"
|
||||
|
||||
@ -124,13 +124,21 @@ main(int argc, char *argv[])
|
||||
cpio->buff_size = sizeof(buff);
|
||||
|
||||
|
||||
#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
|
||||
{ /* Ignore SIGPIPE signals. */
|
||||
#if defined(HAVE_SIGACTION)
|
||||
{
|
||||
struct sigaction sa;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
#ifdef SIGPIPE
|
||||
/* Ignore SIGPIPE signals. */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &sa, NULL);
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
/* Do not ignore SIGCHLD. */
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#include <sddl.h>
|
||||
|
||||
#include "cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
#define EPOC_TIME (116444736000000000ULL)
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
IF(ENABLE_CPIO AND ENABLE_TEST)
|
||||
SET(bsdcpio_test_SOURCES
|
||||
../cmdline.c
|
||||
../../libarchive_fe/err.c
|
||||
../../libarchive_fe/lafe_err.c
|
||||
../../test_utils/test_utils.c
|
||||
../../test_utils/test_main.c
|
||||
test.h
|
||||
|
||||
@ -219,7 +219,7 @@ DEFINE_TEST(test_format_newc)
|
||||
assert(is_hex(e, 110));
|
||||
assertEqualMem(e + 0, "070701", 6); /* Magic */
|
||||
assert(is_hex(e + 6, 8)); /* ino */
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Mode: Group members bits and others bits do not work. */
|
||||
assertEqualInt(0xa180, from_hex(e + 14, 8) & 0xffc0);
|
||||
#else
|
||||
|
||||
@ -52,7 +52,7 @@ test_create(void)
|
||||
* #ifdef this section out. Most of the test below is
|
||||
* still valid. */
|
||||
memset(×, 0, sizeof(times));
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
times.actime = 86400;
|
||||
times.modtime = 86400;
|
||||
#else
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#include "test.h"
|
||||
|
||||
#include "../cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#define ROOT "root"
|
||||
|
||||
@ -52,6 +52,7 @@ SET(libarchive_SOURCES
|
||||
archive_pathmatch.h
|
||||
archive_platform.h
|
||||
archive_platform_acl.h
|
||||
archive_platform_stat.h
|
||||
archive_platform_xattr.h
|
||||
archive_ppmd_private.h
|
||||
archive_ppmd8.c
|
||||
@ -248,11 +249,14 @@ 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
|
||||
SET_TARGET_PROPERTIES(archive PROPERTIES
|
||||
VERSION ${SOVERSION_FULL}
|
||||
SOVERSION ${SOVERSION}
|
||||
MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
|
||||
MACHO_CURRENT_VERSION ${MACHO_CURRENT_VERSION})
|
||||
IF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
|
||||
SET_PROPERTY(TARGET archive PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
ENDIF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
|
||||
# archive_static is a static library
|
||||
@ -261,6 +265,9 @@ TARGET_INCLUDE_DIRECTORIES(archive_static PUBLIC .)
|
||||
TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
|
||||
SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
|
||||
LIBARCHIVE_STATIC)
|
||||
IF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
|
||||
SET_PROPERTY(TARGET archive_static PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
ENDIF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
|
||||
# On Posix systems, libarchive.so and libarchive.a can co-exist.
|
||||
IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
|
||||
SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
|
||||
@ -271,13 +278,13 @@ IF(ENABLE_INSTALL)
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
INSTALL(TARGETS archive
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
INSTALL(TARGETS archive_static
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
INSTALL_MAN(${libarchive_MANS})
|
||||
INSTALL(FILES ${include_HEADERS} DESTINATION include)
|
||||
ENDIF()
|
||||
|
||||
@ -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 3008000
|
||||
#define ARCHIVE_VERSION_NUMBER 3008004
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void);
|
||||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.8.0dev"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.8.4"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
@ -1250,8 +1250,10 @@ __LA_DECL int archive_match_include_gname_w(struct archive *,
|
||||
const wchar_t *);
|
||||
|
||||
/* Utility functions */
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Convenience function to sort a NULL terminated list of strings */
|
||||
__LA_DECL int archive_utility_string_sort(char **);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -270,6 +270,19 @@ acl_new_entry(struct archive_acl *acl,
|
||||
{
|
||||
struct archive_acl_entry *ap, *aq;
|
||||
|
||||
/* Reject an invalid type */
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
break;
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Type argument must be a valid NFS4 or POSIX.1e type.
|
||||
* The type must agree with anything already set and
|
||||
* the permset must be compatible. */
|
||||
@ -822,6 +835,9 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
|
||||
wname = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
default:
|
||||
**wp = '\0';
|
||||
break;
|
||||
}
|
||||
*wp += wcslen(*wp);
|
||||
*(*wp)++ = L':';
|
||||
@ -878,6 +894,7 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
|
||||
wcscpy(*wp, L"alarm");
|
||||
break;
|
||||
default:
|
||||
*(*wp) = L'\0';
|
||||
break;
|
||||
}
|
||||
*wp += wcslen(*wp);
|
||||
@ -1057,6 +1074,9 @@ append_entry(char **p, const char *prefix, int type,
|
||||
name = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
default:
|
||||
**p = '\0';
|
||||
break;
|
||||
}
|
||||
*p += strlen(*p);
|
||||
*(*p)++ = ':';
|
||||
@ -1112,6 +1132,9 @@ append_entry(char **p, const char *prefix, int type,
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
strcpy(*p, "alarm");
|
||||
break;
|
||||
default:
|
||||
*(*p) = '\0';
|
||||
break;
|
||||
}
|
||||
*p += strlen(*p);
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@ -54,8 +55,14 @@ errmsg(const char *m)
|
||||
|
||||
while (s > 0) {
|
||||
written = write(2, m, s);
|
||||
if (written <= 0)
|
||||
if (written == 0)
|
||||
return;
|
||||
if (written < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
m += written;
|
||||
s -= written;
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
(void)rounds; /* UNUSED */
|
||||
(void)derived_key; /* UNUSED */
|
||||
(void)derived_key_len; /* UNUSED */
|
||||
return -1; /* UNSUPPORTED */
|
||||
return CRYPTOR_STUB_FUNCTION; /* UNSUPPORTED */
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -439,14 +439,14 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
(void)ctx; /* UNUSED */
|
||||
(void)key; /* UNUSED */
|
||||
(void)key_len; /* UNUSED */
|
||||
return -1;
|
||||
return CRYPTOR_STUB_FUNCTION;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
(void)ctx; /* UNUSED */
|
||||
return -1;
|
||||
return CRYPTOR_STUB_FUNCTION;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -469,7 +469,7 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
|
||||
(void)out; /* UNUSED */
|
||||
(void)out_len; /* UNUSED */
|
||||
aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
|
||||
return -1;
|
||||
return CRYPTOR_STUB_FUNCTION;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -490,9 +490,9 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
|
||||
size_t in_len, uint8_t * const out, size_t *out_len)
|
||||
{
|
||||
uint8_t *const ebuf = ctx->encr_buf;
|
||||
unsigned pos = ctx->encr_pos;
|
||||
unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
|
||||
unsigned i;
|
||||
size_t pos = ctx->encr_pos;
|
||||
size_t max = (in_len < *out_len)? in_len: *out_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < max; ) {
|
||||
if (pos == AES_BLOCK_SIZE) {
|
||||
|
||||
@ -43,7 +43,7 @@ int __libarchive_cryptor_build_hack(void);
|
||||
#ifdef __APPLE__
|
||||
# include <AvailabilityMacros.h>
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
|
||||
# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -56,10 +56,10 @@ int __libarchive_cryptor_build_hack(void);
|
||||
typedef struct {
|
||||
CCCryptorRef ctx;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
size_t key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
size_t encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
@ -144,6 +144,16 @@ typedef struct {
|
||||
|
||||
#else
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_WIN)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__) && !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
#define ARCHIVE_CRYPTOR_USE_WINCRYPT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_MAX_KEY_SIZE 32
|
||||
typedef int archive_crypto_ctx;
|
||||
@ -168,6 +178,9 @@ typedef int archive_crypto_ctx;
|
||||
#define archive_encrypto_aes_ctr_release(ctx) \
|
||||
__archive_cryptor.encrypto_aes_ctr_release(ctx)
|
||||
|
||||
/* Stub return value if no encryption support exists. */
|
||||
#define CRYPTOR_STUB_FUNCTION -2
|
||||
|
||||
/* Minimal interface to cryptographic functionality for internal use in
|
||||
* libarchive */
|
||||
struct archive_cryptor
|
||||
|
||||
@ -124,7 +124,6 @@ static void
|
||||
add_trivial_nfs4_acl(struct archive_entry *entry)
|
||||
{
|
||||
mode_t mode;
|
||||
int i;
|
||||
const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
|
||||
const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA;
|
||||
@ -195,7 +194,7 @@ add_trivial_nfs4_acl(struct archive_entry *entry)
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tacl_entry[1].permset |= eperm;
|
||||
|
||||
for (i = 0; i < sizeof(tacl_entry) / sizeof(tacl_entry[0]); i++) {
|
||||
for (size_t i = 0; i < sizeof(tacl_entry) / sizeof(tacl_entry[0]); i++) {
|
||||
if (tacl_entry[i].permset != 0) {
|
||||
archive_entry_acl_add_entry(entry,
|
||||
tacl_entry[i].type, tacl_entry[i].permset,
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3008000
|
||||
#define ARCHIVE_VERSION_NUMBER 3008004
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
||||
@ -64,7 +64,7 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
|
||||
.Fn archive_entry_copy_hardlink_w "struct archive_entry *a" "const wchar_t *path"
|
||||
.Ft int
|
||||
.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
|
||||
@ -207,7 +207,7 @@ for setting is recommended.
|
||||
The function
|
||||
.Fn archive_entry_size
|
||||
returns the file size, if it has been set, and 0 otherwise.
|
||||
.Fn archive_entry_size
|
||||
.Fn archive_entry_size_is_set
|
||||
can be used to query that status.
|
||||
.Fn archive_entry_set_size
|
||||
and
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
const struct stat *
|
||||
archive_entry_stat(struct archive_entry *entry)
|
||||
{
|
||||
int64_t size;
|
||||
struct stat *st;
|
||||
if (entry->stat == NULL) {
|
||||
entry->stat = calloc(1, sizeof(*st));
|
||||
@ -74,7 +75,10 @@ archive_entry_stat(struct archive_entry *entry)
|
||||
st->st_ino = (ino_t)archive_entry_ino64(entry);
|
||||
st->st_nlink = archive_entry_nlink(entry);
|
||||
st->st_rdev = archive_entry_rdev(entry);
|
||||
st->st_size = (off_t)archive_entry_size(entry);
|
||||
size = archive_entry_size(entry);
|
||||
st->st_size = (off_t)size;
|
||||
if (st->st_size < 0 || (int64_t)st->st_size != size)
|
||||
st->st_size = 0;
|
||||
st->st_mode = archive_entry_mode(entry);
|
||||
|
||||
/*
|
||||
|
||||
@ -35,6 +35,9 @@
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
@ -53,8 +56,7 @@ struct match {
|
||||
struct match_list {
|
||||
struct match *first;
|
||||
struct match **last;
|
||||
int count;
|
||||
int unmatched_count;
|
||||
size_t unmatched_count;
|
||||
struct match *unmatched_next;
|
||||
int unmatched_eof;
|
||||
};
|
||||
@ -73,7 +75,6 @@ struct match_file {
|
||||
struct entry_list {
|
||||
struct match_file *first;
|
||||
struct match_file **last;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct id_array {
|
||||
@ -144,12 +145,15 @@ static int add_pattern_mbs(struct archive_match *, struct match_list *,
|
||||
const char *);
|
||||
static int add_pattern_wcs(struct archive_match *, struct match_list *,
|
||||
const wchar_t *);
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
static int cmp_key_mbs(const struct archive_rb_node *, const void *);
|
||||
static int cmp_key_wcs(const struct archive_rb_node *, const void *);
|
||||
static int cmp_node_mbs(const struct archive_rb_node *,
|
||||
const struct archive_rb_node *);
|
||||
#else
|
||||
static int cmp_key_wcs(const struct archive_rb_node *, const void *);
|
||||
static int cmp_node_wcs(const struct archive_rb_node *,
|
||||
const struct archive_rb_node *);
|
||||
#endif
|
||||
static void entry_list_add(struct entry_list *, struct match_file *);
|
||||
static void entry_list_free(struct entry_list *);
|
||||
static void entry_list_init(struct entry_list *);
|
||||
@ -189,12 +193,12 @@ static int validate_time_flag(struct archive *, int, const char *);
|
||||
|
||||
#define get_date archive_parse_date
|
||||
|
||||
static const struct archive_rb_tree_ops rb_ops_mbs = {
|
||||
static const struct archive_rb_tree_ops rb_ops = {
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
cmp_node_mbs, cmp_key_mbs
|
||||
};
|
||||
|
||||
static const struct archive_rb_tree_ops rb_ops_wcs = {
|
||||
#else
|
||||
cmp_node_wcs, cmp_key_wcs
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -228,7 +232,7 @@ archive_match_new(void)
|
||||
a->recursive_include = 1;
|
||||
match_list_init(&(a->inclusions));
|
||||
match_list_init(&(a->exclusions));
|
||||
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
|
||||
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops);
|
||||
entry_list_init(&(a->exclusion_entry_list));
|
||||
match_list_init(&(a->inclusion_unames));
|
||||
match_list_init(&(a->inclusion_gnames));
|
||||
@ -507,7 +511,9 @@ archive_match_path_unmatched_inclusions(struct archive *_a)
|
||||
ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions");
|
||||
a = (struct archive_match *)_a;
|
||||
|
||||
return (a->inclusions.unmatched_count);
|
||||
if (a->inclusions.unmatched_count > (size_t)INT_MAX)
|
||||
return INT_MAX;
|
||||
return (int)(a->inclusions.unmatched_count);
|
||||
}
|
||||
|
||||
int
|
||||
@ -650,7 +656,7 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (*b == 0x0d || *b == 0x0a) {
|
||||
if (*b == 0x0d || *b == 0x0a) {
|
||||
found_separator = 1;
|
||||
break;
|
||||
}
|
||||
@ -735,7 +741,7 @@ path_excluded(struct archive_match *a, int mbs, const void *pathname)
|
||||
}
|
||||
}
|
||||
|
||||
/* Exclusions take priority */
|
||||
/* Exclusions take priority. */
|
||||
for (match = a->exclusions.first; match != NULL;
|
||||
match = match->next){
|
||||
r = match_path_exclusion(a, match, mbs, pathname);
|
||||
@ -834,7 +840,6 @@ match_list_init(struct match_list *list)
|
||||
{
|
||||
list->first = NULL;
|
||||
list->last = &(list->first);
|
||||
list->count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -855,7 +860,6 @@ match_list_add(struct match_list *list, struct match *m)
|
||||
{
|
||||
*list->last = m;
|
||||
list->last = &(m->next);
|
||||
list->count++;
|
||||
list->unmatched_count++;
|
||||
}
|
||||
|
||||
@ -1275,6 +1279,7 @@ set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
|
||||
/*
|
||||
* Call back functions for archive_rb.
|
||||
*/
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
static int
|
||||
cmp_node_mbs(const struct archive_rb_node *n1,
|
||||
const struct archive_rb_node *n2)
|
||||
@ -1291,7 +1296,7 @@ cmp_node_mbs(const struct archive_rb_node *n1,
|
||||
return (-1);
|
||||
return (strcmp(p1, p2));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmp_key_mbs(const struct archive_rb_node *n, const void *key)
|
||||
{
|
||||
@ -1303,7 +1308,7 @@ cmp_key_mbs(const struct archive_rb_node *n, const void *key)
|
||||
return (-1);
|
||||
return (strcmp(p, (const char *)key));
|
||||
}
|
||||
|
||||
#else
|
||||
static int
|
||||
cmp_node_wcs(const struct archive_rb_node *n1,
|
||||
const struct archive_rb_node *n2)
|
||||
@ -1320,7 +1325,7 @@ cmp_node_wcs(const struct archive_rb_node *n1,
|
||||
return (-1);
|
||||
return (wcscmp(p1, p2));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmp_key_wcs(const struct archive_rb_node *n, const void *key)
|
||||
{
|
||||
@ -1332,13 +1337,13 @@ cmp_key_wcs(const struct archive_rb_node *n, const void *key)
|
||||
return (-1);
|
||||
return (wcscmp(p, (const wchar_t *)key));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
entry_list_init(struct entry_list *list)
|
||||
{
|
||||
list->first = NULL;
|
||||
list->last = &(list->first);
|
||||
list->count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1359,7 +1364,6 @@ entry_list_add(struct entry_list *list, struct match_file *file)
|
||||
{
|
||||
*list->last = file;
|
||||
list->last = &(file->next);
|
||||
list->count++;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1382,9 +1386,7 @@ add_entry(struct archive_match *a, int flag,
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
archive_mstring_copy_wcs(&(f->pathname), pathname);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
|
||||
#else
|
||||
(void)rb_ops_wcs;
|
||||
pathname = archive_entry_pathname(entry);
|
||||
if (pathname == NULL) {
|
||||
free(f);
|
||||
@ -1392,7 +1394,6 @@ add_entry(struct archive_match *a, int flag,
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
archive_mstring_copy_mbs(&(f->pathname), pathname);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_mbs;
|
||||
#endif
|
||||
f->flag = flag;
|
||||
f->mtime_sec = archive_entry_mtime(entry);
|
||||
@ -1517,16 +1518,13 @@ time_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
}
|
||||
|
||||
/* If there is no exclusion list, include the file. */
|
||||
if (a->exclusion_entry_list.count == 0)
|
||||
if (a->exclusion_entry_list.first == NULL)
|
||||
return (0);
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
pathname = archive_entry_pathname_w(entry);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
|
||||
#else
|
||||
(void)rb_ops_wcs;
|
||||
pathname = archive_entry_pathname(entry);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_mbs;
|
||||
#endif
|
||||
if (pathname == NULL)
|
||||
return (0);
|
||||
@ -1682,7 +1680,7 @@ archive_match_owner_excluded(struct archive *_a,
|
||||
static int
|
||||
add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
|
||||
{
|
||||
unsigned i;
|
||||
size_t i;
|
||||
|
||||
if (ids->count + 1 >= ids->size) {
|
||||
void *p;
|
||||
@ -1719,10 +1717,10 @@ add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
|
||||
static int
|
||||
match_owner_id(struct id_array *ids, int64_t id)
|
||||
{
|
||||
unsigned b, m, t;
|
||||
size_t b, m, t;
|
||||
|
||||
t = 0;
|
||||
b = (unsigned)ids->count;
|
||||
b = ids->count;
|
||||
while (t < b) {
|
||||
m = (t + b)>>1;
|
||||
if (ids->ids[m] == id)
|
||||
@ -1817,7 +1815,7 @@ owner_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (a->inclusion_unames.count) {
|
||||
if (a->inclusion_unames.first != NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
r = match_owner_name_wcs(a, &(a->inclusion_unames),
|
||||
archive_entry_uname_w(entry));
|
||||
@ -1831,7 +1829,7 @@ owner_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
return (r);
|
||||
}
|
||||
|
||||
if (a->inclusion_gnames.count) {
|
||||
if (a->inclusion_gnames.first != NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
r = match_owner_name_wcs(a, &(a->inclusion_gnames),
|
||||
archive_entry_gname_w(entry));
|
||||
|
||||
@ -703,9 +703,7 @@ Convert(time_t Month, time_t Day, time_t Year,
|
||||
Year += 1900;
|
||||
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
|
||||
? 29 : 28;
|
||||
/* Checking for 2038 bogusly assumes that time_t is 32 bits. But
|
||||
I'm too lazy to try to check for time_t overflow in another way. */
|
||||
if (Year < EPOCH || Year >= 2038
|
||||
if (Year < EPOCH || (sizeof(time_t) <= 4 && Year >= 2038)
|
||||
|| Month < 1 || Month > 12
|
||||
/* Lint fluff: "conversion from long may lose accuracy" */
|
||||
|| Day < 1 || Day > DaysInMonth[(int)--Month]
|
||||
|
||||
@ -183,16 +183,6 @@
|
||||
#define CAN_RESTORE_METADATA_FD
|
||||
#endif
|
||||
|
||||
/*
|
||||
* glibc 2.24 deprecates readdir_r
|
||||
* bionic c deprecates readdir_r too
|
||||
*/
|
||||
#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__))
|
||||
#define USE_READDIR_R 1
|
||||
#else
|
||||
#undef USE_READDIR_R
|
||||
#endif
|
||||
|
||||
/* Set up defaults for internal error codes. */
|
||||
#ifndef ARCHIVE_ERRNO_FILE_FORMAT
|
||||
#if HAVE_EFTYPE
|
||||
|
||||
45
libarchive/archive_platform_stat.h
Normal file
45
libarchive/archive_platform_stat.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 Tobias Stoeckmann
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
|
||||
|
||||
#ifndef ARCHIVE_PLATFORM_STAT_H_INCLUDED
|
||||
#define ARCHIVE_PLATFORM_STAT_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* We use _lseeki64() on Windows. */
|
||||
typedef int64_t la_seek_t;
|
||||
|
||||
struct la_seek_stat {
|
||||
int64_t st_mtime;
|
||||
ino_t st_ino;
|
||||
unsigned short st_mode;
|
||||
uint32_t st_nlink;
|
||||
gid_t st_gid;
|
||||
la_seek_t st_size;
|
||||
uid_t st_uid;
|
||||
dev_t st_dev;
|
||||
dev_t st_rdev;
|
||||
};
|
||||
typedef struct la_seek_stat la_seek_stat_t;
|
||||
|
||||
#define la_seek_fstat(fd, st) __la_seek_fstat((fd), (st))
|
||||
#define la_seek_stat(fd, st) __la_seek_stat((fd), (st))
|
||||
|
||||
#else
|
||||
typedef off_t la_seek_t;
|
||||
typedef struct stat la_seek_stat_t;
|
||||
|
||||
#define la_seek_fstat(fd, st) fstat((fd), (st))
|
||||
#define la_seek_stat(fd, st) stat((fd), (st))
|
||||
#endif
|
||||
|
||||
#endif /* !ARCHIVE_PLATFORM_STAT_H_INCLUDED */
|
||||
@ -158,6 +158,7 @@ int __archive_check_magic(struct archive *, unsigned int magic,
|
||||
__LA_NORETURN void __archive_errx(int retvalue, const char *msg);
|
||||
|
||||
void __archive_ensure_cloexec_flag(int fd);
|
||||
int __archive_get_tempdir(struct archive_string *);
|
||||
int __archive_mktemp(const char *tmpdir);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
int __archive_mkstemp(wchar_t *templates);
|
||||
|
||||
@ -575,8 +575,7 @@ choose_filters(struct archive_read *a)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
filter
|
||||
= calloc(1, sizeof(*filter));
|
||||
filter = calloc(1, sizeof(*filter));
|
||||
if (filter == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
filter->bidder = best_bidder;
|
||||
@ -834,7 +833,9 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||
r = archive_read_data_block(a, &read_buf,
|
||||
&a->read_data_remaining, &a->read_data_offset);
|
||||
a->read_data_block = read_buf;
|
||||
if (r == ARCHIVE_EOF)
|
||||
if (r == ARCHIVE_EOF &&
|
||||
a->read_data_offset == a->read_data_output_offset &&
|
||||
a->read_data_remaining == 0)
|
||||
return (bytes_read);
|
||||
/*
|
||||
* Error codes are all negative, so the status
|
||||
|
||||
@ -254,7 +254,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
if (S_ISLNK(st->st_mode)) {
|
||||
size_t linkbuffer_len = st->st_size;
|
||||
char *linkbuffer;
|
||||
int lnklen;
|
||||
ssize_t lnklen;
|
||||
|
||||
linkbuffer = malloc(linkbuffer_len + 1);
|
||||
if (linkbuffer == NULL) {
|
||||
@ -338,7 +338,7 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
int ret = ARCHIVE_OK;
|
||||
void *buff = NULL;
|
||||
int have_attrs;
|
||||
const char *name, *tempdir;
|
||||
const char *name;
|
||||
struct archive_string tempfile;
|
||||
|
||||
(void)fd; /* UNUSED */
|
||||
@ -357,15 +357,11 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
if (have_attrs == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
tempdir = NULL;
|
||||
if (issetugid() == 0)
|
||||
tempdir = getenv("TMPDIR");
|
||||
if (tempdir == NULL)
|
||||
tempdir = _PATH_TMP;
|
||||
archive_string_init(&tempfile);
|
||||
archive_strcpy(&tempfile, tempdir);
|
||||
archive_strcat(&tempfile, "tar.md.XXXXXX");
|
||||
tempfd = mkstemp(tempfile.s);
|
||||
archive_strcpy(&tempfile, name);
|
||||
archive_string_dirname(&tempfile);
|
||||
archive_strcat(&tempfile, "/tar.XXXXXXXX");
|
||||
tempfd = __archive_mkstemp(tempfile.s);
|
||||
if (tempfd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Could not open extended attribute file");
|
||||
@ -896,7 +892,7 @@ setup_sparse_fiemap(struct archive_read_disk *a,
|
||||
for (iters = 0; ; ++iters) {
|
||||
int i, r;
|
||||
|
||||
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
||||
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
||||
if (r < 0) {
|
||||
/* When something error happens, it is better we
|
||||
* should return ARCHIVE_OK because an earlier
|
||||
@ -1083,4 +1079,3 @@ setup_sparse(struct archive_read_disk *a,
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
|
||||
|
||||
|
||||
@ -107,6 +107,8 @@
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
#define MAX_FILESYSTEM_ID 1000000
|
||||
|
||||
#if defined(__hpux) && !defined(HAVE_DIRFD)
|
||||
#define dirfd(x) ((x)->__dd_fd)
|
||||
#define HAVE_DIRFD
|
||||
@ -168,9 +170,6 @@ struct filesystem {
|
||||
int synthetic;
|
||||
int remote;
|
||||
int noatime;
|
||||
#if defined(USE_READDIR_R)
|
||||
size_t name_max;
|
||||
#endif
|
||||
long incr_xfer_size;
|
||||
long max_xfer_size;
|
||||
long min_xfer_size;
|
||||
@ -203,10 +202,6 @@ struct tree {
|
||||
DIR *d;
|
||||
#define INVALID_DIR_HANDLE NULL
|
||||
struct dirent *de;
|
||||
#if defined(USE_READDIR_R)
|
||||
struct dirent *dirent;
|
||||
size_t dirent_allocated;
|
||||
#endif
|
||||
int flags;
|
||||
int visit_type;
|
||||
/* Error code from last failed operation. */
|
||||
@ -869,7 +864,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
tree_enter_initial_dir(t);
|
||||
return (ARCHIVE_FATAL);
|
||||
case TREE_ERROR_DIR:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
archive_set_error(&a->archive, t->tree_errno,
|
||||
"%s: Couldn't visit directory",
|
||||
tree_current_path(t));
|
||||
tree_enter_initial_dir(t);
|
||||
@ -1419,8 +1414,12 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
* This is the new filesystem which we have to generate a new ID for.
|
||||
*/
|
||||
fid = t->max_filesystem_id++;
|
||||
if (fid > MAX_FILESYSTEM_ID) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Too many filesystems");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (t->max_filesystem_id > t->allocated_filesystem) {
|
||||
size_t s;
|
||||
int s;
|
||||
void *p;
|
||||
|
||||
s = t->max_filesystem_id * 2;
|
||||
@ -1578,9 +1577,6 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
# endif
|
||||
#endif
|
||||
int r, xr = 0;
|
||||
#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
|
||||
long nm;
|
||||
#endif
|
||||
|
||||
t->current_filesystem->synthetic = -1;
|
||||
t->current_filesystem->remote = -1;
|
||||
@ -1647,35 +1643,6 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
#endif
|
||||
t->current_filesystem->noatime = 0;
|
||||
|
||||
#if defined(USE_READDIR_R)
|
||||
/* Set maximum filename length. */
|
||||
#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
|
||||
t->current_filesystem->name_max = sfs.f_namemax;
|
||||
#else
|
||||
# if defined(_PC_NAME_MAX)
|
||||
/* Mac OS X does not have f_namemax in struct statfs. */
|
||||
if (tree_current_is_symblic_link_target(t)) {
|
||||
if (tree_enter_working_dir(t) != 0) {
|
||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
|
||||
} else
|
||||
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
|
||||
# else
|
||||
nm = -1;
|
||||
# endif
|
||||
if (nm == -1)
|
||||
t->current_filesystem->name_max = NAME_MAX;
|
||||
else
|
||||
t->current_filesystem->name_max = nm;
|
||||
#endif
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif /* USE_READDIR_R */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -1732,8 +1699,6 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
#endif
|
||||
t->current_filesystem->noatime = 0;
|
||||
|
||||
/* Set maximum filename length. */
|
||||
t->current_filesystem->name_max = svfs.f_namemax;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -1863,19 +1828,6 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
#endif
|
||||
t->current_filesystem->noatime = 0;
|
||||
|
||||
#if defined(USE_READDIR_R)
|
||||
/* Set maximum filename length. */
|
||||
#if defined(HAVE_STATVFS)
|
||||
t->current_filesystem->name_max = svfs.f_namemax;
|
||||
#else
|
||||
t->current_filesystem->name_max = sfs.f_namelen;
|
||||
#endif
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -1953,15 +1905,6 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
#endif
|
||||
t->current_filesystem->noatime = 0;
|
||||
|
||||
#if defined(USE_READDIR_R)
|
||||
/* Set maximum filename length. */
|
||||
t->current_filesystem->name_max = svfs.f_namemax;
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -1975,9 +1918,6 @@ static int
|
||||
setup_current_filesystem(struct archive_read_disk *a)
|
||||
{
|
||||
struct tree *t = a->tree;
|
||||
#if defined(_PC_NAME_MAX) && defined(USE_READDIR_R)
|
||||
long nm;
|
||||
#endif
|
||||
t->current_filesystem->synthetic = -1;/* Not supported */
|
||||
t->current_filesystem->remote = -1;/* Not supported */
|
||||
t->current_filesystem->noatime = 0;
|
||||
@ -1987,40 +1927,6 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
t->current_filesystem->min_xfer_size = -1;
|
||||
t->current_filesystem->incr_xfer_size = -1;
|
||||
|
||||
#if defined(USE_READDIR_R)
|
||||
/* Set maximum filename length. */
|
||||
# if defined(_PC_NAME_MAX)
|
||||
if (tree_current_is_symblic_link_target(t)) {
|
||||
if (tree_enter_working_dir(t) != 0) {
|
||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
|
||||
} else
|
||||
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
|
||||
if (nm == -1)
|
||||
# endif /* _PC_NAME_MAX */
|
||||
/*
|
||||
* Some systems (HP-UX or others?) incorrectly defined
|
||||
* NAME_MAX macro to be a smaller value.
|
||||
*/
|
||||
# if defined(NAME_MAX) && NAME_MAX >= 255
|
||||
t->current_filesystem->name_max = NAME_MAX;
|
||||
# else
|
||||
/* No way to get a trusted value of maximum filename
|
||||
* length. */
|
||||
t->current_filesystem->name_max = PATH_MAX;
|
||||
# endif /* NAME_MAX */
|
||||
# if defined(_PC_NAME_MAX)
|
||||
else
|
||||
t->current_filesystem->name_max = nm;
|
||||
# endif /* _PC_NAME_MAX */
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif /* USE_READDIR_R */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -2445,16 +2351,20 @@ static int
|
||||
tree_dir_next_posix(struct tree *t)
|
||||
{
|
||||
int r;
|
||||
#if defined(HAVE_FDOPENDIR)
|
||||
int fd;
|
||||
#endif
|
||||
const char *name;
|
||||
size_t namelen;
|
||||
|
||||
if (t->d == NULL) {
|
||||
#if defined(USE_READDIR_R)
|
||||
size_t dirent_size;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FDOPENDIR)
|
||||
t->d = fdopendir(tree_dup(t->working_dir_fd));
|
||||
if (t->working_dir_fd >= 0) {
|
||||
fd = tree_dup(t->working_dir_fd);
|
||||
if (fd != -1)
|
||||
t->d = fdopendir(fd);
|
||||
}
|
||||
#else /* HAVE_FDOPENDIR */
|
||||
if (tree_enter_working_dir(t) == 0) {
|
||||
t->d = opendir(".");
|
||||
@ -2470,45 +2380,12 @@ tree_dir_next_posix(struct tree *t)
|
||||
t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
|
||||
return (t->visit_type);
|
||||
}
|
||||
#if defined(USE_READDIR_R)
|
||||
dirent_size = offsetof(struct dirent, d_name) +
|
||||
t->filesystem_table[t->current->filesystem_id].name_max + 1;
|
||||
if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
|
||||
free(t->dirent);
|
||||
t->dirent = malloc(dirent_size);
|
||||
if (t->dirent == NULL) {
|
||||
closedir(t->d);
|
||||
t->d = INVALID_DIR_HANDLE;
|
||||
(void)tree_ascend(t);
|
||||
tree_pop(t);
|
||||
t->tree_errno = ENOMEM;
|
||||
t->visit_type = TREE_ERROR_DIR;
|
||||
return (t->visit_type);
|
||||
}
|
||||
t->dirent_allocated = dirent_size;
|
||||
}
|
||||
#endif /* USE_READDIR_R */
|
||||
}
|
||||
for (;;) {
|
||||
errno = 0;
|
||||
#if defined(USE_READDIR_R)
|
||||
r = readdir_r(t->d, t->dirent, &t->de);
|
||||
#ifdef _AIX
|
||||
/* Note: According to the man page, return value 9 indicates
|
||||
* that the readdir_r was not successful and the error code
|
||||
* is set to the global errno variable. And then if the end
|
||||
* of directory entries was reached, the return value is 9
|
||||
* and the third parameter is set to NULL and errno is
|
||||
* unchanged. */
|
||||
if (r == 9)
|
||||
r = errno;
|
||||
#endif /* _AIX */
|
||||
if (r != 0 || t->de == NULL) {
|
||||
#else
|
||||
t->de = readdir(t->d);
|
||||
if (t->de == NULL) {
|
||||
r = errno;
|
||||
#endif
|
||||
closedir(t->d);
|
||||
t->d = INVALID_DIR_HANDLE;
|
||||
if (r != 0) {
|
||||
@ -2747,9 +2624,6 @@ tree_free(struct tree *t)
|
||||
if (t == NULL)
|
||||
return;
|
||||
archive_string_free(&t->path);
|
||||
#if defined(USE_READDIR_R)
|
||||
free(t->dirent);
|
||||
#endif
|
||||
free(t->sparse_list);
|
||||
for (i = 0; i < t->max_filesystem_id; i++)
|
||||
free(t->filesystem_table[i].allocation_ptr);
|
||||
|
||||
@ -53,6 +53,8 @@
|
||||
/* To deal with absolute symlink issues */
|
||||
#define START_ABSOLUTE_SYMLINK_REPARSE L"\\??\\"
|
||||
|
||||
#define MAX_FILESYSTEM_ID 1000000
|
||||
|
||||
/*-
|
||||
* This is a new directory-walking system that addresses a number
|
||||
* of problems I've had with fts(3). In particular, it has no
|
||||
@ -1449,8 +1451,12 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
* There is a new filesystem, we generate a new ID for.
|
||||
*/
|
||||
fid = t->max_filesystem_id++;
|
||||
if (fid > MAX_FILESYSTEM_ID) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Too many filesystems");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (t->max_filesystem_id > t->allocated_filesystem) {
|
||||
size_t s;
|
||||
int s;
|
||||
void *p;
|
||||
|
||||
s = t->max_filesystem_id * 2;
|
||||
@ -1652,7 +1658,7 @@ tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
|
||||
/*
|
||||
* Append a name to the current dir path.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
tree_append(struct tree *t, const wchar_t *name, size_t name_length)
|
||||
{
|
||||
size_t size_needed;
|
||||
@ -1665,7 +1671,8 @@ tree_append(struct tree *t, const wchar_t *name, size_t name_length)
|
||||
|
||||
/* Resize pathname buffer as needed. */
|
||||
size_needed = name_length + t->dirname_length + 2;
|
||||
archive_wstring_ensure(&t->path, size_needed);
|
||||
if (archive_wstring_ensure(&t->path, size_needed) == NULL)
|
||||
return (TREE_ERROR_FATAL);
|
||||
/* Add a separating '/' if it's needed. */
|
||||
if (t->dirname_length > 0 &&
|
||||
t->path.s[archive_strlen(&t->path)-1] != L'/')
|
||||
@ -1677,13 +1684,15 @@ tree_append(struct tree *t, const wchar_t *name, size_t name_length)
|
||||
t->full_path.s[t->full_path_dir_length] = L'\0';
|
||||
t->full_path.length = t->full_path_dir_length;
|
||||
size_needed = name_length + t->full_path_dir_length + 2;
|
||||
archive_wstring_ensure(&t->full_path, size_needed);
|
||||
if (archive_wstring_ensure(&t->full_path, size_needed) == NULL)
|
||||
return (TREE_ERROR_FATAL);
|
||||
/* Add a separating '\' if it's needed. */
|
||||
if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
|
||||
archive_wstrappend_wchar(&t->full_path, L'\\');
|
||||
archive_wstrncat(&t->full_path, name, name_length);
|
||||
t->restore_time.full_path = t->full_path.s;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1697,7 +1706,10 @@ tree_open(const wchar_t *path, int symlink_mode, int restore_time)
|
||||
t = calloc(1, sizeof(*t));
|
||||
archive_string_init(&(t->full_path));
|
||||
archive_string_init(&t->path);
|
||||
archive_wstring_ensure(&t->path, 15);
|
||||
if (archive_wstring_ensure(&t->path, 15) == NULL) {
|
||||
free(t);
|
||||
return (NULL);
|
||||
}
|
||||
t->initial_symlink_mode = symlink_mode;
|
||||
return (tree_reopen(t, path, restore_time));
|
||||
}
|
||||
@ -1756,7 +1768,8 @@ tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
|
||||
p = wcsrchr(base, L'/');
|
||||
if (p != NULL) {
|
||||
*p = L'\0';
|
||||
tree_append(t, base, p - base);
|
||||
if (tree_append(t, base, p - base))
|
||||
goto failed;
|
||||
t->dirname_length = archive_strlen(&t->path);
|
||||
base = p + 1;
|
||||
}
|
||||
@ -1892,8 +1905,10 @@ tree_next(struct tree *t)
|
||||
}
|
||||
/* Top stack item needs a regular visit. */
|
||||
t->current = t->stack;
|
||||
tree_append(t, t->stack->name.s,
|
||||
r = tree_append(t, t->stack->name.s,
|
||||
archive_strlen(&(t->stack->name)));
|
||||
if (r != 0)
|
||||
return (r);
|
||||
//t->dirname_length = t->path_length;
|
||||
//tree_pop(t);
|
||||
t->stack->flags &= ~needsFirstVisit;
|
||||
@ -1901,8 +1916,10 @@ tree_next(struct tree *t)
|
||||
} else if (t->stack->flags & needsDescent) {
|
||||
/* Top stack item is dir to descend into. */
|
||||
t->current = t->stack;
|
||||
tree_append(t, t->stack->name.s,
|
||||
r = tree_append(t, t->stack->name.s,
|
||||
archive_strlen(&(t->stack->name)));
|
||||
if (r != 0)
|
||||
return (r);
|
||||
t->stack->flags &= ~needsDescent;
|
||||
r = tree_descent(t);
|
||||
if (r != 0) {
|
||||
@ -1945,9 +1962,10 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
|
||||
struct archive_wstring pt;
|
||||
|
||||
archive_string_init(&pt);
|
||||
archive_wstring_ensure(&pt,
|
||||
if (archive_wstring_ensure(&pt,
|
||||
archive_strlen(&(t->full_path))
|
||||
+ 2 + wcslen(pattern));
|
||||
+ 2 + wcslen(pattern)) == NULL)
|
||||
return (TREE_ERROR_FATAL);
|
||||
archive_wstring_copy(&pt, &(t->full_path));
|
||||
archive_wstrappend_wchar(&pt, L'\\');
|
||||
archive_wstrcat(&pt, pattern);
|
||||
@ -1979,7 +1997,9 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
|
||||
continue;
|
||||
if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
|
||||
continue;
|
||||
tree_append(t, name, namelen);
|
||||
r = tree_append(t, name, namelen);
|
||||
if (r != 0)
|
||||
return (r);
|
||||
return (t->visit_type = TREE_REGULAR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_platform_stat.h"
|
||||
|
||||
struct read_fd_data {
|
||||
int fd;
|
||||
@ -65,12 +66,12 @@ static int64_t file_skip(struct archive *, void *, int64_t request);
|
||||
int
|
||||
archive_read_open_fd(struct archive *a, int fd, size_t block_size)
|
||||
{
|
||||
struct stat st;
|
||||
la_seek_stat_t st;
|
||||
struct read_fd_data *mine;
|
||||
void *b;
|
||||
|
||||
archive_clear_error(a);
|
||||
if (fstat(fd, &st) != 0) {
|
||||
if (la_seek_fstat(fd, &st) != 0) {
|
||||
archive_set_error(a, errno, "Can't stat fd %d", fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
@ -133,7 +134,7 @@ static int64_t
|
||||
file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
off_t skip = (off_t)request;
|
||||
la_seek_t skip = (la_seek_t)request;
|
||||
int64_t old_offset, new_offset;
|
||||
int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
|
||||
|
||||
@ -149,7 +150,8 @@ file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
}
|
||||
|
||||
/* Reduce 'skip' to the next smallest multiple of block_size */
|
||||
skip = (off_t)(((int64_t)skip / mine->block_size) * mine->block_size);
|
||||
skip = (la_seek_t)(((int64_t)skip / mine->block_size) * mine->block_size);
|
||||
|
||||
if (skip == 0)
|
||||
return (0);
|
||||
|
||||
@ -185,27 +187,28 @@ static int64_t
|
||||
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
off_t seek = (off_t)request;
|
||||
la_seek_t seek = (la_seek_t)request;
|
||||
int64_t r;
|
||||
int seek_bits = sizeof(seek) * 8 - 1; /* off_t is a signed type. */
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
|
||||
/* Reduce a request that would overflow the 'seek' variable. */
|
||||
/* Do not perform a seek which cannot be fulfilled. */
|
||||
if (sizeof(request) > sizeof(seek)) {
|
||||
const int64_t max_seek =
|
||||
(((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
|
||||
const int64_t min_seek = ~max_seek;
|
||||
if (request > max_seek)
|
||||
seek = (off_t)max_seek;
|
||||
else if (request < min_seek)
|
||||
seek = (off_t)min_seek;
|
||||
if (request < min_seek || request > max_seek) {
|
||||
errno = EOVERFLOW;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
r = lseek(mine->fd, seek, whence);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
err:
|
||||
if (errno == ESPIPE) {
|
||||
archive_set_error(a, errno,
|
||||
"A file descriptor(%d) is not seekable(PIPE)", mine->fd);
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_platform_stat.h"
|
||||
|
||||
struct read_FILE_data {
|
||||
FILE *f;
|
||||
@ -65,7 +66,7 @@ static int64_t FILE_skip(struct archive *, void *, int64_t);
|
||||
int
|
||||
archive_read_open_FILE(struct archive *a, FILE *f)
|
||||
{
|
||||
struct stat st;
|
||||
la_seek_stat_t st;
|
||||
struct read_FILE_data *mine;
|
||||
size_t block_size = 128 * 1024;
|
||||
void *b;
|
||||
@ -88,7 +89,7 @@ archive_read_open_FILE(struct archive *a, FILE *f)
|
||||
* streams that don't support fileno()). As a result, fileno()
|
||||
* should be used cautiously.)
|
||||
*/
|
||||
if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
if (la_seek_fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||
/* Enable the seek optimization only for regular files. */
|
||||
mine->can_skip = 1;
|
||||
@ -132,7 +133,7 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
|
||||
#else
|
||||
long skip = (long)request;
|
||||
#endif
|
||||
int64_t old_offset, new_offset;
|
||||
int64_t old_offset, new_offset = -1;
|
||||
int skip_bits = sizeof(skip) * 8 - 1;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
@ -170,11 +171,14 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
|
||||
#ifdef __ANDROID__
|
||||
new_offset = lseek(fileno(mine->f), skip, SEEK_CUR);
|
||||
#elif HAVE__FSEEKI64
|
||||
new_offset = _fseeki64(mine->f, skip, SEEK_CUR);
|
||||
if (_fseeki64(mine->f, skip, SEEK_CUR) == 0)
|
||||
new_offset = _ftelli64(mine->f);
|
||||
#elif HAVE_FSEEKO
|
||||
new_offset = fseeko(mine->f, skip, SEEK_CUR);
|
||||
if (fseeko(mine->f, skip, SEEK_CUR) == 0)
|
||||
new_offset = ftello(mine->f);
|
||||
#else
|
||||
new_offset = fseek(mine->f, skip, SEEK_CUR);
|
||||
if (fseek(mine->f, skip, SEEK_CUR) == 0)
|
||||
new_offset = ftell(mine->f);
|
||||
#endif
|
||||
if (new_offset >= 0)
|
||||
return (new_offset - old_offset);
|
||||
@ -202,15 +206,15 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
int seek_bits = sizeof(seek) * 8 - 1;
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
/* Reduce a request that would overflow the 'seek' variable. */
|
||||
/* Do not perform a seek which cannot be fulfilled. */
|
||||
if (sizeof(request) > sizeof(seek)) {
|
||||
const int64_t max_seek =
|
||||
(((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
|
||||
const int64_t min_seek = ~max_seek;
|
||||
if (request > max_seek)
|
||||
seek = max_seek;
|
||||
else if (request < min_seek)
|
||||
seek = min_seek;
|
||||
if (request < min_seek || request > max_seek) {
|
||||
errno = EOVERFLOW;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@ -233,6 +237,7 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
}
|
||||
#endif
|
||||
/* If we arrive here, the input is corrupted or truncated so fail. */
|
||||
err:
|
||||
archive_set_error(a, errno, "Error seeking in FILE* pointer");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_platform_stat.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
@ -136,8 +137,10 @@ archive_read_open_filenames(struct archive *a, const char **filenames,
|
||||
mine->filename_type = FNT_STDIN;
|
||||
} else
|
||||
mine->filename_type = FNT_MBS;
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) {
|
||||
free(mine);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (filenames == NULL)
|
||||
break;
|
||||
filename = *(filenames++);
|
||||
@ -216,8 +219,10 @@ archive_read_open_filenames_w(struct archive *a, const wchar_t **wfilenames,
|
||||
archive_string_free(&fn);
|
||||
#endif
|
||||
}
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) {
|
||||
free(mine);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (wfilenames == NULL)
|
||||
break;
|
||||
wfilename = *(wfilenames++);
|
||||
@ -248,7 +253,7 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
|
||||
static int
|
||||
file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
struct stat st;
|
||||
la_seek_stat_t st;
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
void *buffer;
|
||||
const char *filename = NULL;
|
||||
@ -313,7 +318,7 @@ file_open(struct archive *a, void *client_data)
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
if (la_seek_fstat(fd, &st) != 0) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if (mine->filename_type == FNT_WCS)
|
||||
archive_set_error(a, errno, "Can't stat '%ls'",
|
||||
@ -482,10 +487,11 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* We use _lseeki64() on Windows. */
|
||||
int64_t old_offset, new_offset, skip = request;
|
||||
int64_t old_offset, new_offset;
|
||||
#else
|
||||
off_t old_offset, new_offset, skip = (off_t)request;
|
||||
off_t old_offset, new_offset;
|
||||
#endif
|
||||
la_seek_t skip = (la_seek_t)request;
|
||||
int skip_bits = sizeof(skip) * 8 - 1;
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
@ -552,21 +558,21 @@ static int64_t
|
||||
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
off_t seek = (off_t)request;
|
||||
la_seek_t seek = (la_seek_t)request;
|
||||
int64_t r;
|
||||
int seek_bits = sizeof(seek) * 8 - 1;
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
|
||||
/* Reduce a request that would overflow the 'seek' variable. */
|
||||
/* Do not perform a seek which cannot be fulfilled. */
|
||||
if (sizeof(request) > sizeof(seek)) {
|
||||
const int64_t max_seek =
|
||||
(((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
|
||||
const int64_t min_seek = ~max_seek;
|
||||
if (request > max_seek)
|
||||
seek = (off_t)max_seek;
|
||||
else if (request < min_seek)
|
||||
seek = (off_t)min_seek;
|
||||
if (request < min_seek || request > max_seek) {
|
||||
errno = EOVERFLOW;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
r = lseek(mine->fd, seek, whence);
|
||||
@ -574,6 +580,7 @@ file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
return r;
|
||||
|
||||
/* If the input is corrupted or truncated, fail. */
|
||||
err:
|
||||
if (mine->filename_type == FNT_STDIN)
|
||||
archive_set_error(a, errno, "Error seeking in stdin");
|
||||
else if (mine->filename_type == FNT_MBS)
|
||||
|
||||
@ -37,7 +37,7 @@ int
|
||||
archive_read_set_format(struct archive *_a, int code)
|
||||
{
|
||||
int r1, r2, slots, i;
|
||||
char str[10];
|
||||
const char *str;
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
|
||||
@ -49,49 +49,49 @@ archive_read_set_format(struct archive *_a, int code)
|
||||
switch (code & ARCHIVE_FORMAT_BASE_MASK)
|
||||
{
|
||||
case ARCHIVE_FORMAT_7ZIP:
|
||||
strcpy(str, "7zip");
|
||||
str = "7zip";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_AR:
|
||||
strcpy(str, "ar");
|
||||
str = "ar";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_CAB:
|
||||
strcpy(str, "cab");
|
||||
str = "cab";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
strcpy(str, "cpio");
|
||||
str = "cpio";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_EMPTY:
|
||||
strcpy(str, "empty");
|
||||
str = "empty";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
strcpy(str, "iso9660");
|
||||
str = "iso9660";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_LHA:
|
||||
strcpy(str, "lha");
|
||||
str = "lha";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_MTREE:
|
||||
strcpy(str, "mtree");
|
||||
str = "mtree";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR:
|
||||
strcpy(str, "rar");
|
||||
str = "rar";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
strcpy(str, "rar5");
|
||||
str = "rar5";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAW:
|
||||
strcpy(str, "raw");
|
||||
str = "raw";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
strcpy(str, "tar");
|
||||
str = "tar";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_WARC:
|
||||
strcpy(str, "warc");
|
||||
str = "warc";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
strcpy(str, "xar");
|
||||
str = "xar";
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ZIP:
|
||||
strcpy(str, "zip");
|
||||
str = "zip";
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
|
||||
@ -328,6 +328,7 @@ next_code(struct archive_read_filter *self)
|
||||
static int debug_buff[1024];
|
||||
static unsigned debug_index;
|
||||
|
||||
again:
|
||||
code = newcode = getbits(self, state->bits);
|
||||
if (code < 0)
|
||||
return (code);
|
||||
@ -360,7 +361,7 @@ next_code(struct archive_read_filter *self)
|
||||
state->section_end_code = (1 << state->bits) - 1;
|
||||
state->free_ent = 257;
|
||||
state->oldcode = -1;
|
||||
return (next_code(self));
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (code > state->free_ent
|
||||
|
||||
@ -49,9 +49,12 @@
|
||||
#include "archive_xxhash.h"
|
||||
|
||||
#define LZ4_MAGICNUMBER 0x184d2204
|
||||
#define LZ4_SKIPPABLED 0x184d2a50
|
||||
#define LZ4_LEGACY 0x184c2102
|
||||
|
||||
// Note: LZ4 and zstd share the same skippable frame format with the same magic numbers.
|
||||
#define LZ4_SKIPPABLE_START 0x184D2A50
|
||||
#define LZ4_SKIPPABLE_MASK 0xFFFFFFF0
|
||||
|
||||
#if defined(HAVE_LIBLZ4)
|
||||
struct private_data {
|
||||
enum { SELECT_STREAM,
|
||||
@ -141,19 +144,67 @@ lz4_reader_bid(struct archive_read_filter_bidder *self,
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
ssize_t avail;
|
||||
int bits_checked;
|
||||
uint32_t number;
|
||||
int bits_checked = 0;
|
||||
ssize_t min_lz4_archive_size = 11;
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
// LZ4 skippable frames contain a 4 byte magic number followed by
|
||||
// a 4 byte frame data size, then that number of bytes of data. Regular
|
||||
// frames contain a 4 byte magic number followed by a 2-14 byte frame
|
||||
// header, some data, and a 3 byte end marker.
|
||||
ssize_t min_lz4_frame_size = 8;
|
||||
|
||||
/* Minimal lz4 archive is 11 bytes. */
|
||||
buffer = __archive_read_filter_ahead(filter, 11, &avail);
|
||||
ssize_t offset_in_buffer = 0;
|
||||
ssize_t max_lookahead = 64 * 1024;
|
||||
|
||||
(void)self; // UNUSED
|
||||
|
||||
// Zstd and LZ4 skippable frame magic numbers are identical. To
|
||||
// differentiate these two, we need to look for a non-skippable
|
||||
// frame.
|
||||
|
||||
// Minimal lz4 archive is 11 bytes.
|
||||
buffer = __archive_read_filter_ahead(filter, min_lz4_archive_size, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
|
||||
/* First four bytes must be LZ4 magic numbers. */
|
||||
bits_checked = 0;
|
||||
if ((number = archive_le32dec(buffer)) == LZ4_MAGICNUMBER) {
|
||||
uint32_t magic_number = archive_le32dec(buffer);
|
||||
|
||||
while ((magic_number & LZ4_SKIPPABLE_MASK) == LZ4_SKIPPABLE_START) {
|
||||
|
||||
offset_in_buffer += 4; // Skip over the magic number
|
||||
|
||||
// Ensure that we can read another 4 bytes.
|
||||
if (offset_in_buffer + 4 > avail) {
|
||||
buffer = __archive_read_filter_ahead(filter, offset_in_buffer + 4, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
}
|
||||
|
||||
uint32_t frame_data_size = archive_le32dec(buffer + offset_in_buffer);
|
||||
|
||||
// Skip over the 4 frame data size bytes, plus the value stored there.
|
||||
offset_in_buffer += 4 + frame_data_size;
|
||||
|
||||
// There should be at least one more frame if this is LZ4 data.
|
||||
if (offset_in_buffer + min_lz4_frame_size > avail) { // TODO: should this be >= ?
|
||||
if (offset_in_buffer + min_lz4_frame_size > max_lookahead)
|
||||
return (0);
|
||||
|
||||
buffer = __archive_read_filter_ahead(filter, offset_in_buffer + min_lz4_frame_size, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
}
|
||||
|
||||
magic_number = archive_le32dec(buffer + offset_in_buffer);
|
||||
}
|
||||
|
||||
// We have skipped over any skippable frames. Either a regular LZ4 frame
|
||||
// follows, or this isn't LZ4 data.
|
||||
|
||||
bits_checked = offset_in_buffer;
|
||||
buffer = buffer + offset_in_buffer;
|
||||
|
||||
if (magic_number == LZ4_MAGICNUMBER) {
|
||||
unsigned char flag, BD;
|
||||
|
||||
bits_checked += 32;
|
||||
@ -175,11 +226,16 @@ lz4_reader_bid(struct archive_read_filter_bidder *self,
|
||||
if (BD & ~0x70)
|
||||
return (0);
|
||||
bits_checked += 8;
|
||||
} else if (number == LZ4_LEGACY) {
|
||||
bits_checked += 32;
|
||||
|
||||
return (bits_checked);
|
||||
}
|
||||
|
||||
return (bits_checked);
|
||||
|
||||
if (magic_number == LZ4_LEGACY) {
|
||||
bits_checked += 32;
|
||||
return (bits_checked);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if !defined(HAVE_LIBLZ4)
|
||||
@ -342,7 +398,7 @@ lz4_filter_read(struct archive_read_filter *self, const void **p)
|
||||
return lz4_filter_read_default_stream(self, p);
|
||||
else if (number == LZ4_LEGACY)
|
||||
return lz4_filter_read_legacy_stream(self, p);
|
||||
else if ((number & ~0xF) == LZ4_SKIPPABLED) {
|
||||
else if ((number & LZ4_SKIPPABLE_MASK) == LZ4_SKIPPABLE_START) {
|
||||
read_buf = __archive_read_filter_ahead(
|
||||
self->upstream, 4, NULL);
|
||||
if (read_buf == NULL) {
|
||||
|
||||
@ -110,7 +110,7 @@ struct program_filter {
|
||||
pid_t child;
|
||||
#endif
|
||||
int exit_status;
|
||||
int waitpid_return;
|
||||
pid_t waitpid_return;
|
||||
int child_stdin, child_stdout;
|
||||
|
||||
char *out_buf;
|
||||
@ -242,16 +242,13 @@ child_stop(struct archive_read_filter *self, struct program_filter *state)
|
||||
state->waitpid_return
|
||||
= waitpid(state->child, &state->exit_status, 0);
|
||||
} while (state->waitpid_return == -1 && errno == EINTR);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
CloseHandle(state->child);
|
||||
#endif
|
||||
state->child = 0;
|
||||
}
|
||||
|
||||
if (state->waitpid_return < 0) {
|
||||
/* waitpid() failed? This is ugly. */
|
||||
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Child process exited badly");
|
||||
"Error closing child process");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
|
||||
@ -110,24 +110,67 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
ssize_t avail;
|
||||
unsigned prefix;
|
||||
|
||||
/* Zstd frame magic values */
|
||||
unsigned zstd_magic = 0xFD2FB528U;
|
||||
unsigned zstd_magic_skippable_start = 0x184D2A50U;
|
||||
unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
|
||||
// Zstandard skippable frames contain a 4 byte magic number followed by
|
||||
// a 4 byte frame data size, then that number of bytes of data. Regular
|
||||
// frames contain a 4 byte magic number followed by a 2-14 byte frame
|
||||
// header, some data, and a 3 byte end marker.
|
||||
ssize_t min_zstd_frame_size = 8;
|
||||
|
||||
(void) self; /* UNUSED */
|
||||
ssize_t offset_in_buffer = 0;
|
||||
ssize_t max_lookahead = 64 * 1024;
|
||||
|
||||
buffer = __archive_read_filter_ahead(filter, 4, &avail);
|
||||
// Zstd regular frame magic number.
|
||||
uint32_t zstd_magic = 0xFD2FB528U;
|
||||
|
||||
// Note: Zstd and LZ4 skippable frame magic numbers are identical.
|
||||
// To differentiate these two, we need to look for a non-skippable
|
||||
// frame.
|
||||
uint32_t zstd_magic_skippable_start = 0x184D2A50;
|
||||
uint32_t zstd_magic_skippable_mask = 0xFFFFFFF0;
|
||||
|
||||
(void) self; // UNUSED
|
||||
|
||||
buffer = __archive_read_filter_ahead(filter, min_zstd_frame_size, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
|
||||
prefix = archive_le32dec(buffer);
|
||||
if (prefix == zstd_magic)
|
||||
return (32);
|
||||
if ((prefix & zstd_magic_skippable_mask) == zstd_magic_skippable_start)
|
||||
return (32);
|
||||
uint32_t magic_number = archive_le32dec(buffer);
|
||||
|
||||
while ((magic_number & zstd_magic_skippable_mask) == zstd_magic_skippable_start) {
|
||||
|
||||
offset_in_buffer += 4; // Skip over the magic number
|
||||
|
||||
// Ensure that we can read another 4 bytes.
|
||||
if (offset_in_buffer + 4 > avail) {
|
||||
buffer = __archive_read_filter_ahead(filter, offset_in_buffer + 4, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
}
|
||||
|
||||
uint32_t frame_data_size = archive_le32dec(buffer + offset_in_buffer);
|
||||
|
||||
// Skip over the 4 frame data size bytes, plus the value stored there.
|
||||
offset_in_buffer += 4 + frame_data_size;
|
||||
|
||||
// There should be at least one more frame if this is zstd data.
|
||||
if (offset_in_buffer + min_zstd_frame_size > avail) {
|
||||
if (offset_in_buffer + min_zstd_frame_size > max_lookahead)
|
||||
return (0);
|
||||
|
||||
buffer = __archive_read_filter_ahead(filter, offset_in_buffer + min_zstd_frame_size, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
}
|
||||
|
||||
magic_number = archive_le32dec(buffer + offset_in_buffer);
|
||||
}
|
||||
|
||||
// We have skipped over any skippable frames. Either a regular zstd frame
|
||||
// follows, or this isn't zstd data.
|
||||
|
||||
if (magic_number == zstd_magic)
|
||||
return (offset_in_buffer + 4);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
/*
|
||||
* ELF format
|
||||
*/
|
||||
#define ELF_HDR_MIN_LEN 0x34
|
||||
#define ELF_HDR_MIN_LEN 0x3f
|
||||
#define ELF_HDR_EI_CLASS_OFFSET 0x04
|
||||
#define ELF_HDR_EI_DATA_OFFSET 0x05
|
||||
|
||||
@ -744,6 +744,7 @@ find_elf_data_sec(struct archive_read *a)
|
||||
const char *h;
|
||||
char big_endian, format_64;
|
||||
ssize_t bytes, min_addr = SFX_MIN_ADDR;
|
||||
ssize_t request;
|
||||
uint64_t e_shoff, strtab_offset, strtab_size;
|
||||
uint16_t e_shentsize, e_shnum, e_shstrndx;
|
||||
uint16_t (*dec16)(const void *);
|
||||
@ -796,7 +797,12 @@ find_elf_data_sec(struct archive_read *a)
|
||||
if (__archive_read_seek(a, e_shoff, SEEK_SET) < 0) {
|
||||
break;
|
||||
}
|
||||
h = __archive_read_ahead(a, (size_t)e_shnum * (size_t)e_shentsize, NULL);
|
||||
if (format_64) {
|
||||
request = (size_t)e_shnum * (size_t)e_shentsize + 0x28;
|
||||
} else {
|
||||
request = (size_t)e_shnum * (size_t)e_shentsize + 0x18;
|
||||
}
|
||||
h = __archive_read_ahead(a, request, &bytes);
|
||||
if (h == NULL) {
|
||||
break;
|
||||
}
|
||||
@ -811,6 +817,8 @@ find_elf_data_sec(struct archive_read *a)
|
||||
strtab_size = (*dec32)(
|
||||
h + e_shstrndx * e_shentsize + 0x14);
|
||||
}
|
||||
if (strtab_size < 6 || strtab_size > SIZE_MAX)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Read the STRTAB section to find the .data offset
|
||||
@ -1391,7 +1399,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
* size to liblzma when using lzma_raw_decoder() liblzma
|
||||
* could correctly deal with BCJ+LZMA. But unfortunately
|
||||
* there is no way to do that.
|
||||
* Discussion about this can be found at XZ Utils forum.
|
||||
*
|
||||
* Reference: https://web.archive.org/web/20240405171610/https://www.mail-archive.com/xz-devel@tukaani.org/msg00373.html
|
||||
*/
|
||||
if (coder2 != NULL) {
|
||||
zip->codec2 = coder2->codec;
|
||||
|
||||
@ -363,7 +363,12 @@ archive_read_support_format_cab(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_string_init(&cab->ws);
|
||||
archive_wstring_ensure(&cab->ws, 256);
|
||||
if (archive_wstring_ensure(&cab->ws, 256) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory");
|
||||
free(cab);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
r = __archive_read_register_format(a,
|
||||
cab,
|
||||
|
||||
@ -689,7 +689,7 @@ archive_read_format_lha_read_header(struct archive_read *a,
|
||||
* a pathname and a symlink has '\' character, a directory
|
||||
* separator in DOS/Windows. So we should convert it to '/'.
|
||||
*/
|
||||
if (p[H_LEVEL_OFFSET] == 0)
|
||||
if (lha->level == 0)
|
||||
lha_replace_path_separator(lha, entry);
|
||||
|
||||
archive_entry_set_mode(entry, lha->mode);
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_entry_private.h"
|
||||
#include "archive_platform_stat.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_rb.h"
|
||||
#include "archive_read_private.h"
|
||||
@ -1073,6 +1074,8 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
/* Non-printable characters are not allowed */
|
||||
for (s = p;s < p + len - 1; s++) {
|
||||
if (!isprint((unsigned char)*s) && *s != '\t') {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Non-printable character 0x%02X", (unsigned char)(*s));
|
||||
r = ARCHIVE_FATAL;
|
||||
break;
|
||||
}
|
||||
@ -1175,7 +1178,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
|
||||
{
|
||||
const char *path;
|
||||
struct stat st_storage, *st;
|
||||
la_seek_stat_t st_storage, *st;
|
||||
struct mtree_entry *mp;
|
||||
struct archive_entry *sparse_entry;
|
||||
int r = ARCHIVE_OK, r1, parsed_kws;
|
||||
@ -1270,7 +1273,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
|
||||
st = &st_storage;
|
||||
if (mtree->fd >= 0) {
|
||||
if (fstat(mtree->fd, st) == -1) {
|
||||
if (la_seek_fstat(mtree->fd, st) == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Could not fstat %s", path);
|
||||
r = ARCHIVE_WARN;
|
||||
@ -1283,7 +1286,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
#ifdef HAVE_LSTAT
|
||||
else if (lstat(path, st) == -1)
|
||||
#else
|
||||
else if (la_stat(path, st) == -1)
|
||||
else if (la_seek_stat(path, st) == -1)
|
||||
#endif
|
||||
{
|
||||
st = NULL;
|
||||
@ -2130,6 +2133,13 @@ readline(struct archive_read *a, struct mtree *mtree, char **start,
|
||||
for (u = mtree->line.s + find_off; *u; ++u) {
|
||||
if (u[0] == '\n') {
|
||||
/* Ends with unescaped newline. */
|
||||
/* Check if preceded by '\r' for CRLF handling */
|
||||
if (u > mtree->line.s && u[-1] == '\r') {
|
||||
/* CRLF ending - remove the '\r' */
|
||||
u[-1] = '\n';
|
||||
u[0] = '\0';
|
||||
total_size--;
|
||||
}
|
||||
*start = mtree->line.s;
|
||||
return total_size;
|
||||
} else if (u[0] == '#') {
|
||||
@ -2144,6 +2154,11 @@ readline(struct archive_read *a, struct mtree *mtree, char **start,
|
||||
total_size -= 2;
|
||||
mtree->line.s[total_size] = '\0';
|
||||
break;
|
||||
} else if (u[1] == '\r' && u[2] == '\n') {
|
||||
/* Trim escaped CRLF. */
|
||||
total_size -= 3;
|
||||
mtree->line.s[total_size] = '\0';
|
||||
break;
|
||||
} else if (u[1] != '\0') {
|
||||
/* Skip the two-char escape sequence */
|
||||
++u;
|
||||
|
||||
@ -1117,8 +1117,6 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||
if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
|
||||
*size = 0;
|
||||
*offset = rar->offset;
|
||||
if (*offset < rar->unp_size)
|
||||
*offset = rar->unp_size;
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
|
||||
@ -1455,7 +1453,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
return (ARCHIVE_FATAL);
|
||||
#endif
|
||||
}
|
||||
/* If no CRC error, Go on parsing File Header. */
|
||||
/* If no CRC error, go on parsing File Header. */
|
||||
p = h;
|
||||
endp = p + header_size - 7;
|
||||
memcpy(&file_header, p, sizeof(file_header));
|
||||
@ -2368,8 +2366,8 @@ parse_codes(struct archive_read *a)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Make sure ppmd7_contest is freed before Ppmd7_Construct
|
||||
* because reading a broken file cause this abnormal sequence. */
|
||||
/* Make sure ppmd7_context is freed before Ppmd7_Construct
|
||||
* because reading a broken file causes this abnormal sequence. */
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
|
||||
rar->bytein.a = a;
|
||||
|
||||
@ -1619,10 +1619,13 @@ static int process_head_file_extra(struct archive_read* a,
|
||||
{
|
||||
uint64_t extra_field_size;
|
||||
uint64_t extra_field_id = 0;
|
||||
int ret = ARCHIVE_FATAL;
|
||||
uint64_t var_size;
|
||||
|
||||
while(extra_data_size > 0) {
|
||||
/* Make sure we won't fail if the file declares only unsupported
|
||||
attributes. */
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
if(!read_var(a, &extra_field_size, &var_size))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
@ -1675,12 +1678,53 @@ static int process_head_file_extra(struct archive_read* a,
|
||||
if (ARCHIVE_OK != consume(a, extra_field_size)) {
|
||||
return ARCHIVE_EOF;
|
||||
}
|
||||
|
||||
/* Don't fail on unsupported attribute -- we've handled it
|
||||
by skipping over it. */
|
||||
ret = ARCHIVE_OK;
|
||||
}
|
||||
|
||||
if (ret != ARCHIVE_OK) {
|
||||
/* Forward any errors signalled by the attribute parsing
|
||||
functions. */
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret != ARCHIVE_OK) {
|
||||
/* Attribute not implemented. */
|
||||
return ret;
|
||||
if (extra_data_size != 0) {
|
||||
/* We didn't skip everything, or we skipped too much; either way,
|
||||
there's an error in this parsing function. */
|
||||
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"unsupported structure of file header extra data");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
static int file_entry_sanity_checks(struct archive_read* a,
|
||||
size_t block_flags, uint8_t is_dir, uint64_t unpacked_size,
|
||||
size_t packed_size)
|
||||
{
|
||||
if (is_dir) {
|
||||
const int declares_data_size =
|
||||
(int) (unpacked_size != 0 || packed_size != 0);
|
||||
|
||||
/* FILE entries for directories still declare HFL_DATA in block flags,
|
||||
even though attaching data to such blocks doesn't make much sense. */
|
||||
if (declares_data_size) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"directory entries cannot have any data");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
} else {
|
||||
const int declares_hfl_data = (int) ((block_flags & HFL_DATA) != 0);
|
||||
if (!declares_hfl_data) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"no data found in file/service block");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
return ARCHIVE_OK;
|
||||
@ -1701,6 +1745,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
|
||||
int c_method = 0, c_version = 0;
|
||||
char name_utf8_buf[MAX_NAME_IN_BYTES];
|
||||
const uint8_t* p;
|
||||
int sanity_ret;
|
||||
|
||||
enum FILE_FLAGS {
|
||||
DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
|
||||
@ -1744,10 +1789,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
|
||||
rar->file.bytes_remaining = data_size;
|
||||
} else {
|
||||
rar->file.bytes_remaining = 0;
|
||||
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"no data found in file/service block");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
if(!read_var_sized(a, &file_flags, NULL))
|
||||
@ -1764,6 +1805,13 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
|
||||
|
||||
rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0);
|
||||
|
||||
sanity_ret = file_entry_sanity_checks(a, block_flags, rar->file.dir,
|
||||
unpacked_size, data_size);
|
||||
|
||||
if (sanity_ret != ARCHIVE_OK) {
|
||||
return sanity_ret;
|
||||
}
|
||||
|
||||
if(!read_var_sized(a, &file_attr, NULL))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
@ -4163,7 +4211,7 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
|
||||
* it's impossible to perform any decompression. */
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Can't decompress an entry marked as a directory");
|
||||
return ARCHIVE_FAILED;
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) {
|
||||
|
||||
@ -174,7 +174,7 @@ static int gnu_sparse_old_parse(struct archive_read *, struct tar *,
|
||||
const struct gnu_sparse *sparse, int length);
|
||||
static int gnu_sparse_01_parse(struct archive_read *, struct tar *,
|
||||
const char *, size_t);
|
||||
static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *,
|
||||
static int64_t gnu_sparse_10_read(struct archive_read *, struct tar *,
|
||||
int64_t *);
|
||||
static int header_Solaris_ACL(struct archive_read *, struct tar *,
|
||||
struct archive_entry *, const void *, int64_t *);
|
||||
@ -233,7 +233,7 @@ static int tar_read_header(struct archive_read *, struct tar *,
|
||||
struct archive_entry *, int64_t *);
|
||||
static int tohex(int c);
|
||||
static char *url_decode(const char *, size_t);
|
||||
static void tar_flush_unconsumed(struct archive_read *, int64_t *);
|
||||
static int tar_flush_unconsumed(struct archive_read *, int64_t *);
|
||||
|
||||
/* Sanity limits: These numbers should be low enough to
|
||||
* prevent a maliciously-crafted archive from forcing us to
|
||||
@ -477,7 +477,7 @@ archive_read_format_tar_options(struct archive_read *a,
|
||||
* how much unconsumed data we have floating around, and to consume
|
||||
* anything outstanding since we're going to do read_aheads
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
tar_flush_unconsumed(struct archive_read *a, int64_t *unconsumed)
|
||||
{
|
||||
if (*unconsumed) {
|
||||
@ -490,9 +490,13 @@ tar_flush_unconsumed(struct archive_read *a, int64_t *unconsumed)
|
||||
memset(data, 0xff, *unconsumed);
|
||||
}
|
||||
*/
|
||||
__archive_read_consume(a, *unconsumed);
|
||||
int64_t consumed = __archive_read_consume(a, *unconsumed);
|
||||
if (consumed != *unconsumed) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
*unconsumed = 0;
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -628,7 +632,10 @@ archive_read_format_tar_read_data(struct archive_read *a,
|
||||
/* If we're at end of file, return EOF. */
|
||||
if (tar->sparse_list == NULL ||
|
||||
tar->entry_bytes_remaining == 0) {
|
||||
if (__archive_read_consume(a, tar->entry_padding) < 0)
|
||||
int64_t request = tar->entry_bytes_remaining +
|
||||
tar->entry_padding;
|
||||
|
||||
if (__archive_read_consume(a, request) != request)
|
||||
return (ARCHIVE_FATAL);
|
||||
tar->entry_padding = 0;
|
||||
*buff = NULL;
|
||||
@ -666,29 +673,15 @@ archive_read_format_tar_read_data(struct archive_read *a,
|
||||
static int
|
||||
archive_read_format_tar_skip(struct archive_read *a)
|
||||
{
|
||||
int64_t bytes_skipped;
|
||||
int64_t request;
|
||||
struct sparse_block *p;
|
||||
struct tar* tar;
|
||||
|
||||
tar = (struct tar *)(a->format->data);
|
||||
|
||||
/* Do not consume the hole of a sparse file. */
|
||||
request = 0;
|
||||
for (p = tar->sparse_list; p != NULL; p = p->next) {
|
||||
if (!p->hole) {
|
||||
if (p->remaining >= INT64_MAX - request) {
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
request += p->remaining;
|
||||
}
|
||||
}
|
||||
if (request > tar->entry_bytes_remaining)
|
||||
request = tar->entry_bytes_remaining;
|
||||
request += tar->entry_padding + tar->entry_bytes_unconsumed;
|
||||
request = tar->entry_bytes_remaining + tar->entry_padding +
|
||||
tar->entry_bytes_unconsumed;
|
||||
|
||||
bytes_skipped = __archive_read_consume(a, request);
|
||||
if (bytes_skipped < 0)
|
||||
if (__archive_read_consume(a, request) != request)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
tar->entry_bytes_remaining = 0;
|
||||
@ -701,6 +694,22 @@ archive_read_format_tar_skip(struct archive_read *a)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function resets the accumulated state while reading
|
||||
* a header.
|
||||
*/
|
||||
static void
|
||||
tar_reset_header_state(struct tar *tar)
|
||||
{
|
||||
tar->pax_hdrcharset_utf8 = 1;
|
||||
tar->sparse_gnu_attributes_seen = 0;
|
||||
archive_string_empty(&(tar->entry_gname));
|
||||
archive_string_empty(&(tar->entry_pathname));
|
||||
archive_string_empty(&(tar->entry_pathname_override));
|
||||
archive_string_empty(&(tar->entry_uname));
|
||||
archive_string_empty(&tar->entry_linkpath);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function reads and interprets all of the headers associated
|
||||
* with a single entry.
|
||||
@ -726,13 +735,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
static const int32_t seen_x_header = 32; /* Also X */
|
||||
static const int32_t seen_mac_metadata = 512;
|
||||
|
||||
tar->pax_hdrcharset_utf8 = 1;
|
||||
tar->sparse_gnu_attributes_seen = 0;
|
||||
archive_string_empty(&(tar->entry_gname));
|
||||
archive_string_empty(&(tar->entry_pathname));
|
||||
archive_string_empty(&(tar->entry_pathname_override));
|
||||
archive_string_empty(&(tar->entry_uname));
|
||||
archive_string_empty(&tar->entry_linkpath);
|
||||
tar_reset_header_state(tar);
|
||||
|
||||
/* Ensure format is set. */
|
||||
if (a->archive.archive_format_name == NULL) {
|
||||
@ -751,7 +754,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
|
||||
/* Find the next valid header record. */
|
||||
while (1) {
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Read 512-byte header record */
|
||||
h = __archive_read_ahead(a, 512, &bytes);
|
||||
@ -797,7 +802,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
|
||||
/* This is NOT a null block, so it must be a valid header. */
|
||||
if (!checksum(a, h)) {
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Damaged tar archive (bad header checksum)");
|
||||
/* If we've read some critical information (pax headers, etc)
|
||||
@ -936,6 +943,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
err = err_combine(err, err2);
|
||||
/* Note: Other headers can appear again. */
|
||||
seen_headers = seen_mac_metadata;
|
||||
tar_reset_header_state(tar);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1118,8 +1126,8 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Malformed Solaris ACL attribute (unsupported type %"
|
||||
PRIo64 ")", type);
|
||||
"Malformed Solaris ACL attribute (unsupported type %llu)",
|
||||
(unsigned long long)type);
|
||||
archive_string_free(&acl_text);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
@ -1236,7 +1244,7 @@ header_volume(struct archive_read *a, struct tar *tar,
|
||||
|
||||
header = (const struct archive_entry_header_ustar *)h;
|
||||
size = tar_atol(header->size, sizeof(header->size));
|
||||
if (size > (int64_t)pathname_limit) {
|
||||
if (size < 0 || size > (int64_t)pathname_limit) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
to_consume = ((size + 511) & ~511);
|
||||
@ -1255,13 +1263,15 @@ read_bytes_to_string(struct archive_read *a,
|
||||
const void *src;
|
||||
|
||||
/* Fail if we can't make our buffer big enough. */
|
||||
if (archive_string_ensure(as, (size_t)size+1) == NULL) {
|
||||
if (archive_string_ensure(as, size + 1) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Read the body into the string. */
|
||||
src = __archive_read_ahead(a, size, NULL);
|
||||
@ -1272,9 +1282,9 @@ read_bytes_to_string(struct archive_read *a,
|
||||
*unconsumed = 0;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
memcpy(as->s, src, (size_t)size);
|
||||
memcpy(as->s, src, size);
|
||||
as->s[size] = '\0';
|
||||
as->length = (size_t)size;
|
||||
as->length = size;
|
||||
*unconsumed += size;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@ -1293,18 +1303,21 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
|
||||
(void)tar; /* UNUSED */
|
||||
header = (const struct archive_entry_header_ustar *)h;
|
||||
size = tar_atol(header->size, sizeof(header->size));
|
||||
if (size > entry_limit) {
|
||||
if (size < 0 || size > entry_limit) {
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Special header has invalid size: %lld",
|
||||
(long long)size);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if ((size > (int64_t)pathname_limit) || (size < 0)) {
|
||||
if (size > (int64_t)pathname_limit) {
|
||||
archive_string_empty(as);
|
||||
int64_t to_consume = ((size + 511) & ~511);
|
||||
if (to_consume != __archive_read_consume(a, to_consume)) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Special header too large: %d > 1MiB",
|
||||
(int)size);
|
||||
"Special header too large: %lld > 1MiB",
|
||||
(long long)size);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
r = read_bytes_to_string(a, as, size, unconsumed);
|
||||
@ -1712,7 +1725,9 @@ read_mac_metadata_blob(struct archive_read *a,
|
||||
* Q: Is the above idea really possible? Even
|
||||
* when there are GNU or pax extension entries?
|
||||
*/
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
data = __archive_read_ahead(a, msize, NULL);
|
||||
if (data == NULL) {
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
@ -1743,7 +1758,10 @@ header_pax_global(struct archive_read *a, struct tar *tar,
|
||||
|
||||
header = (const struct archive_entry_header_ustar *)h;
|
||||
size = tar_atol(header->size, sizeof(header->size));
|
||||
if (size > entry_limit) {
|
||||
if (size < 0 || size > entry_limit) {
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Special header has invalid size: %lld",
|
||||
(long long)size);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
to_consume = ((size + 511) & ~511);
|
||||
@ -1890,11 +1908,13 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Ignoring oversized pax extensions: %d > %d",
|
||||
(int)ext_size, (int)ext_size_limit);
|
||||
"Ignoring oversized pax extensions: %lld > %lld",
|
||||
(long long)ext_size, (long long)ext_size_limit);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Parse the size/name of each pax attribute in the body */
|
||||
archive_string_init(&attr_name);
|
||||
@ -1988,7 +2008,16 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
|
||||
|
||||
/* Consume size, name, and `=` */
|
||||
*unconsumed += p - attr_start;
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (value_length == 0) {
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Malformed pax attributes");
|
||||
*unconsumed += ext_size + ext_padding;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/* pax_attribute will consume value_length - 1 */
|
||||
r = pax_attribute(a, tar, entry, attr_name.s, archive_strlen(&attr_name), value_length - 1, unconsumed);
|
||||
@ -2004,7 +2033,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
|
||||
err = err_combine(err, r);
|
||||
|
||||
/* Consume the `\n` that follows the pax attribute value. */
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
p = __archive_read_ahead(a, 1, &did_read);
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
@ -2020,7 +2051,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
|
||||
}
|
||||
ext_size -= 1;
|
||||
*unconsumed += 1;
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
*unconsumed += ext_size + ext_padding;
|
||||
|
||||
@ -2199,8 +2232,9 @@ pax_attribute_SCHILY_acl(struct archive_read *a, struct tar *tar,
|
||||
if (value_length > acl_limit) {
|
||||
__archive_read_consume(a, value_length);
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Unreasonably large ACL: %d > %d",
|
||||
(int)value_length, (int)acl_limit);
|
||||
"Unreasonably large ACL: %llu > %llu",
|
||||
(unsigned long long)value_length,
|
||||
(unsigned long long)acl_limit);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
@ -2247,12 +2281,16 @@ pax_attribute_read_time(struct archive_read *a, size_t value_length, int64_t *ps
|
||||
r = read_bytes_to_string(a, &as, value_length, unconsumed);
|
||||
if (r < ARCHIVE_OK) {
|
||||
archive_string_free(&as);
|
||||
*ps = 0;
|
||||
*pn = 0;
|
||||
return (r);
|
||||
}
|
||||
|
||||
pax_time(as.s, archive_strlen(&as), ps, pn);
|
||||
archive_string_free(&as);
|
||||
if (*ps < 0 || *ps == INT64_MAX) {
|
||||
if (*ps == INT64_MIN) {
|
||||
*ps = 0;
|
||||
*pn = 0;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
@ -2272,7 +2310,10 @@ pax_attribute_read_number(struct archive_read *a, size_t value_length, int64_t *
|
||||
|
||||
archive_string_init(&as);
|
||||
r = read_bytes_to_string(a, &as, value_length, &unconsumed);
|
||||
tar_flush_unconsumed(a, &unconsumed);
|
||||
if (tar_flush_unconsumed(a, &unconsumed) != ARCHIVE_OK) {
|
||||
*result = 0;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (r < ARCHIVE_OK) {
|
||||
archive_string_free(&as);
|
||||
*result = 0;
|
||||
@ -2386,8 +2427,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
|
||||
tar->sparse_gnu_minor = 1;
|
||||
if (value_length > sparse_map_limit) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Unreasonably large sparse map: %d > %d",
|
||||
(int)value_length, (int)sparse_map_limit);
|
||||
"Unreasonably large sparse map: %llu > %llu",
|
||||
(unsigned long long)value_length,
|
||||
(unsigned long long)sparse_map_limit);
|
||||
err = ARCHIVE_FAILED;
|
||||
} else {
|
||||
p = __archive_read_ahead(a, value_length, &bytes_read);
|
||||
@ -2494,8 +2536,8 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
|
||||
} else {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"symlink type is very long"
|
||||
"(longest recognized value is 4 bytes, this is %d)",
|
||||
(int)value_length);
|
||||
"(longest recognized value is 4 bytes, this is %llu)",
|
||||
(unsigned long long)value_length);
|
||||
err = ARCHIVE_WARN;
|
||||
}
|
||||
__archive_read_consume(a, value_length);
|
||||
@ -2531,8 +2573,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
|
||||
if (value_length > xattr_limit) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Ignoring unreasonably large security.selinux attribute:"
|
||||
" %d > %d",
|
||||
(int)value_length, (int)xattr_limit);
|
||||
" %llu > %llu",
|
||||
(unsigned long long)value_length,
|
||||
(unsigned long long)xattr_limit);
|
||||
/* TODO: Should this be FAILED instead? */
|
||||
err = ARCHIVE_WARN;
|
||||
} else {
|
||||
@ -2649,8 +2692,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
|
||||
}
|
||||
} else {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Unreasonably large xattr: %d > %d",
|
||||
(int)value_length, (int)xattr_limit);
|
||||
"Unreasonably large xattr: %llu > %llu",
|
||||
(unsigned long long)value_length,
|
||||
(unsigned long long)xattr_limit);
|
||||
err = ARCHIVE_WARN;
|
||||
}
|
||||
__archive_read_consume(a, value_length);
|
||||
@ -2680,8 +2724,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
|
||||
}
|
||||
} else {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Unreasonably large sparse map: %d > %d",
|
||||
(int)value_length, (int)sparse_map_limit);
|
||||
"Unreasonably large sparse map: %llu > %llu",
|
||||
(unsigned long long)value_length,
|
||||
(unsigned long long)sparse_map_limit);
|
||||
err = ARCHIVE_FAILED;
|
||||
}
|
||||
__archive_read_consume(a, value_length);
|
||||
@ -2750,8 +2795,8 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
|
||||
}
|
||||
} else {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"hdrcharset attribute is unreasonably large (%d bytes)",
|
||||
(int)value_length);
|
||||
"hdrcharset attribute is unreasonably large (%llu bytes)",
|
||||
(unsigned long long)value_length);
|
||||
err = ARCHIVE_WARN;
|
||||
}
|
||||
__archive_read_consume(a, value_length);
|
||||
@ -2838,7 +2883,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
|
||||
|
||||
|
||||
/*
|
||||
* parse a decimal time value, which may include a fractional portion
|
||||
* Parse a decimal time value, which may include a fractional portion
|
||||
*
|
||||
* Sets ps to INT64_MIN on error.
|
||||
*/
|
||||
static void
|
||||
pax_time(const char *p, size_t length, int64_t *ps, long *pn)
|
||||
@ -2854,6 +2901,7 @@ pax_time(const char *p, size_t length, int64_t *ps, long *pn)
|
||||
|
||||
if (length <= 0) {
|
||||
*ps = 0;
|
||||
*pn = 0;
|
||||
return;
|
||||
}
|
||||
s = 0;
|
||||
@ -2867,8 +2915,9 @@ pax_time(const char *p, size_t length, int64_t *ps, long *pn)
|
||||
digit = *p - '0';
|
||||
if (s > limit ||
|
||||
(s == limit && digit > last_digit_limit)) {
|
||||
s = INT64_MAX;
|
||||
break;
|
||||
*ps = INT64_MIN;
|
||||
*pn = 0;
|
||||
return;
|
||||
}
|
||||
s = (s * 10) + digit;
|
||||
++p;
|
||||
@ -2914,7 +2963,9 @@ header_gnutar(struct archive_read *a, struct tar *tar,
|
||||
/* Copy filename over (to ensure null termination). */
|
||||
header = (const struct archive_entry_header_gnutar *)h;
|
||||
const char *existing_pathname = archive_entry_pathname(entry);
|
||||
if (existing_pathname == NULL || existing_pathname[0] == '\0') {
|
||||
const wchar_t *existing_wcs_pathname = archive_entry_pathname_w(entry);
|
||||
if ((existing_pathname == NULL || existing_pathname[0] == '\0')
|
||||
&& (existing_wcs_pathname == NULL || existing_wcs_pathname[0] == L'\0')) {
|
||||
if (archive_entry_copy_pathname_l(entry,
|
||||
header->name, sizeof(header->name), tar->sconv) != 0) {
|
||||
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
|
||||
@ -3067,7 +3118,9 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
do {
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
data = __archive_read_ahead(a, 512, &bytes_read);
|
||||
if (data == NULL) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -3229,12 +3282,10 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
|
||||
* Returns length (in bytes) of the sparse data description
|
||||
* that was read.
|
||||
*/
|
||||
static ssize_t
|
||||
static int64_t
|
||||
gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed)
|
||||
{
|
||||
ssize_t bytes_read;
|
||||
int entries;
|
||||
int64_t offset, size, to_skip, remaining;
|
||||
int64_t bytes_read, entries, offset, size, to_skip, remaining;
|
||||
|
||||
/* Clear out the existing sparse list. */
|
||||
gnu_clear_sparse_list(tar);
|
||||
@ -3242,7 +3293,7 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed)
|
||||
remaining = tar->entry_bytes_remaining;
|
||||
|
||||
/* Parse entries. */
|
||||
entries = (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
|
||||
entries = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
|
||||
if (entries < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
/* Parse the individual entries. */
|
||||
@ -3259,15 +3310,17 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
/* Skip rest of block... */
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
bytes_read = tar->entry_bytes_remaining - remaining;
|
||||
to_skip = 0x1ff & -bytes_read;
|
||||
/* Fail if tar->entry_bytes_remaing would get negative */
|
||||
if (to_skip > remaining)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (to_skip != __archive_read_consume(a, to_skip))
|
||||
return (ARCHIVE_FATAL);
|
||||
return ((ssize_t)(bytes_read + to_skip));
|
||||
return (bytes_read + to_skip);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3485,7 +3538,9 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
|
||||
const char *s;
|
||||
void *p;
|
||||
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
t = __archive_read_ahead(a, 1, &bytes_read);
|
||||
if (bytes_read <= 0 || t == NULL)
|
||||
|
||||
@ -405,7 +405,7 @@ _warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
|
||||
/* it's our lucky day, no work, we can leave early */
|
||||
*buf = NULL;
|
||||
*bsz = 0U;
|
||||
*off = w->cntoff + 4U/*for \r\n\r\n separator*/;
|
||||
*off = w->cntoff;
|
||||
w->unconsumed = 0U;
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
|
||||
@ -930,7 +930,7 @@ xar_read_data(struct archive_read *a,
|
||||
abort_read_data:
|
||||
*buff = NULL;
|
||||
*size = 0;
|
||||
*offset = xar->total;
|
||||
*offset = (int64_t)xar->entry_total;
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
||||
@ -78,6 +78,12 @@
|
||||
#include "archive_crc32.h"
|
||||
#endif
|
||||
|
||||
/* length of local file header, not including filename and extra */
|
||||
#define ZIP_LOCHDR_LEN 30U
|
||||
|
||||
/* maximum length of Mac metadata in MiB */
|
||||
#define ZIP_MAX_METADATA 10U
|
||||
|
||||
struct zip_entry {
|
||||
struct archive_rb_node node;
|
||||
struct zip_entry *next;
|
||||
@ -933,7 +939,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
zip->init_default_conversion = 1;
|
||||
}
|
||||
|
||||
if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) {
|
||||
if ((p = __archive_read_ahead(a, ZIP_LOCHDR_LEN, NULL)) == NULL) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated ZIP file header");
|
||||
return (ARCHIVE_FATAL);
|
||||
@ -969,7 +975,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
filename_length = archive_le16dec(p + 26);
|
||||
extra_length = archive_le16dec(p + 28);
|
||||
|
||||
__archive_read_consume(a, 30);
|
||||
__archive_read_consume(a, ZIP_LOCHDR_LEN);
|
||||
|
||||
/* Read the filename. */
|
||||
if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
|
||||
@ -3015,8 +3021,8 @@ init_WinZip_AES_decryption(struct archive_read *a)
|
||||
p, salt_len, 1000, derived_key, key_len * 2 + 2);
|
||||
if (r != 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Decryption is unsupported due to lack of "
|
||||
"crypto library");
|
||||
r == CRYPTOR_STUB_FUNCTION ? "Decryption is unsupported due "
|
||||
"to lack of crypto library" : "Failed to process passphrase");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
@ -3637,7 +3643,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset)
|
||||
{
|
||||
uint16_t disk_num;
|
||||
uint32_t cd_size, cd_offset;
|
||||
|
||||
|
||||
disk_num = archive_le16dec(p + 4);
|
||||
cd_size = archive_le32dec(p + 12);
|
||||
cd_offset = archive_le32dec(p + 16);
|
||||
@ -4097,7 +4103,7 @@ zip_get_local_file_header_size(struct archive_read *a, size_t extra)
|
||||
const char *p;
|
||||
ssize_t filename_length, extra_length;
|
||||
|
||||
if ((p = __archive_read_ahead(a, extra + 30, NULL)) == NULL) {
|
||||
if ((p = __archive_read_ahead(a, extra + ZIP_LOCHDR_LEN, NULL)) == NULL) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated ZIP file header");
|
||||
return (ARCHIVE_WARN);
|
||||
@ -4111,7 +4117,7 @@ zip_get_local_file_header_size(struct archive_read *a, size_t extra)
|
||||
filename_length = archive_le16dec(p + 26);
|
||||
extra_length = archive_le16dec(p + 28);
|
||||
|
||||
return (30 + filename_length + extra_length);
|
||||
return (ZIP_LOCHDR_LEN + filename_length + extra_length);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4148,16 +4154,16 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
if (rsrc->uncompressed_size > (4 * 1024 * 1024)) {
|
||||
if (rsrc->uncompressed_size > ZIP_MAX_METADATA * 1048576U) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Mac metadata is too large: %jd > 4M bytes",
|
||||
(intmax_t)rsrc->uncompressed_size);
|
||||
"Mac metadata is too large: %jd > %u MiB",
|
||||
(intmax_t)rsrc->uncompressed_size, ZIP_MAX_METADATA);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
if (rsrc->compressed_size > (4 * 1024 * 1024)) {
|
||||
if (rsrc->compressed_size > ZIP_MAX_METADATA * 1048576U) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Mac metadata is too large: %jd > 4M bytes",
|
||||
(intmax_t)rsrc->compressed_size);
|
||||
"Mac metadata is too large: %jd > %u MiB",
|
||||
(intmax_t)rsrc->compressed_size, ZIP_MAX_METADATA);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
|
||||
@ -2015,7 +2015,7 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n,
|
||||
/* We must allocate memory even if there is no data for conversion
|
||||
* or copy. This simulates archive_string_append behavior. */
|
||||
if (length == 0) {
|
||||
int tn = 1;
|
||||
size_t tn = 1;
|
||||
if (sc != NULL && (sc->flag & SCONV_TO_UTF16))
|
||||
tn = 2;
|
||||
if (archive_string_ensure(as, as->length + tn) == NULL)
|
||||
@ -2054,6 +2054,26 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n,
|
||||
return (r);
|
||||
}
|
||||
|
||||
struct archive_string *
|
||||
archive_string_dirname(struct archive_string *as)
|
||||
{
|
||||
/* strip trailing separators */
|
||||
while (as->length > 1 && as->s[as->length - 1] == '/')
|
||||
as->length--;
|
||||
/* strip final component */
|
||||
while (as->length > 0 && as->s[as->length - 1] != '/')
|
||||
as->length--;
|
||||
/* empty path -> cwd */
|
||||
if (as->length == 0)
|
||||
return (archive_strcat(as, "."));
|
||||
/* strip separator(s) */
|
||||
while (as->length > 1 && as->s[as->length - 1] == '/')
|
||||
as->length--;
|
||||
/* terminate */
|
||||
as->s[as->length] = '\0';
|
||||
return (as);
|
||||
}
|
||||
|
||||
#if HAVE_ICONV
|
||||
|
||||
/*
|
||||
@ -2752,7 +2772,8 @@ archive_string_append_unicode(struct archive_string *as, const void *_p,
|
||||
char *p, *endp;
|
||||
uint32_t uc;
|
||||
size_t w;
|
||||
int n, ret = 0, ts, tm;
|
||||
size_t ts, tm;
|
||||
int n, ret = 0;
|
||||
int (*parse)(uint32_t *, const char *, size_t);
|
||||
size_t (*unparse)(char *, size_t, uint32_t);
|
||||
|
||||
|
||||
@ -192,6 +192,10 @@ void archive_string_vsprintf(struct archive_string *, const char *,
|
||||
void archive_string_sprintf(struct archive_string *, const char *, ...)
|
||||
__LA_PRINTF(2, 3);
|
||||
|
||||
/* Equivalent to dirname(3) */
|
||||
struct archive_string *
|
||||
archive_string_dirname(struct archive_string *);
|
||||
|
||||
/* Translates from MBS to Unicode. */
|
||||
/* Returns non-zero if conversion failed in any way. */
|
||||
int archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
||||
|
||||
@ -116,8 +116,14 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
|
||||
|
||||
long_flag = '\0';
|
||||
switch(*p) {
|
||||
case 'j':
|
||||
case 'l':
|
||||
if (p[1] == 'l') {
|
||||
long_flag = 'L';
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'j':
|
||||
case 'z':
|
||||
long_flag = *p;
|
||||
p++;
|
||||
@ -136,14 +142,16 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
|
||||
switch(long_flag) {
|
||||
case 'j': s = va_arg(ap, intmax_t); break;
|
||||
case 'l': s = va_arg(ap, long); break;
|
||||
case 'L': s = va_arg(ap, long long); break;
|
||||
case 'z': s = va_arg(ap, ssize_t); break;
|
||||
default: s = va_arg(ap, int); break;
|
||||
}
|
||||
append_int(as, s, 10);
|
||||
append_int(as, s, 10);
|
||||
break;
|
||||
case 's':
|
||||
switch(long_flag) {
|
||||
case 'l':
|
||||
case 'L':
|
||||
pw = va_arg(ap, wchar_t *);
|
||||
if (pw == NULL)
|
||||
pw = L"(null)";
|
||||
@ -172,6 +180,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
|
||||
switch(long_flag) {
|
||||
case 'j': u = va_arg(ap, uintmax_t); break;
|
||||
case 'l': u = va_arg(ap, unsigned long); break;
|
||||
case 'L': u = va_arg(ap, unsigned long long); break;
|
||||
case 'z': u = va_arg(ap, size_t); break;
|
||||
default: u = va_arg(ap, unsigned int); break;
|
||||
}
|
||||
|
||||
@ -77,7 +77,9 @@
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
static int archive_utility_string_sort_helper(char **, unsigned int);
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
static int __LA_LIBC_CC archive_utility_string_sort_helper(const void *, const void *);
|
||||
#endif
|
||||
|
||||
/* Generic initialization of 'struct archive' objects. */
|
||||
int
|
||||
@ -443,11 +445,39 @@ __archive_mkstemp(wchar_t *template)
|
||||
#else
|
||||
|
||||
static int
|
||||
get_tempdir(struct archive_string *temppath)
|
||||
__archive_issetugid(void)
|
||||
{
|
||||
const char *tmp;
|
||||
#ifdef HAVE_ISSETUGID
|
||||
return (issetugid());
|
||||
#elif HAVE_GETRESUID
|
||||
uid_t ruid, euid, suid;
|
||||
gid_t rgid, egid, sgid;
|
||||
if (getresuid(&ruid, &euid, &suid) != 0)
|
||||
return (-1);
|
||||
if (ruid != euid || ruid != suid)
|
||||
return (1);
|
||||
if (getresgid(&ruid, &egid, &sgid) != 0)
|
||||
return (-1);
|
||||
if (rgid != egid || rgid != sgid)
|
||||
return (1);
|
||||
#elif HAVE_GETEUID
|
||||
if (geteuid() != getuid())
|
||||
return (1);
|
||||
#if HAVE_GETEGID
|
||||
if (getegid() != getgid())
|
||||
return (1);
|
||||
#endif
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
tmp = getenv("TMPDIR");
|
||||
int
|
||||
__archive_get_tempdir(struct archive_string *temppath)
|
||||
{
|
||||
const char *tmp = NULL;
|
||||
|
||||
if (__archive_issetugid() == 0)
|
||||
tmp = getenv("TMPDIR");
|
||||
if (tmp == NULL)
|
||||
#ifdef _PATH_TMP
|
||||
tmp = _PATH_TMP;
|
||||
@ -474,7 +504,7 @@ __archive_mktemp(const char *tmpdir)
|
||||
|
||||
archive_string_init(&temp_name);
|
||||
if (tmpdir == NULL) {
|
||||
if (get_tempdir(&temp_name) != ARCHIVE_OK)
|
||||
if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
|
||||
goto exit_tmpfile;
|
||||
} else {
|
||||
archive_strcpy(&temp_name, tmpdir);
|
||||
@ -536,7 +566,7 @@ __archive_mktempx(const char *tmpdir, char *template)
|
||||
if (template == NULL) {
|
||||
archive_string_init(&temp_name);
|
||||
if (tmpdir == NULL) {
|
||||
if (get_tempdir(&temp_name) != ARCHIVE_OK)
|
||||
if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
|
||||
goto exit_tmpfile;
|
||||
} else
|
||||
archive_strcpy(&temp_name, tmpdir);
|
||||
@ -629,74 +659,28 @@ __archive_ensure_cloexec_flag(int fd)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/*
|
||||
* Utility function to sort a group of strings using quicksort.
|
||||
* Utility functions to sort a group of strings using quicksort.
|
||||
*/
|
||||
static int
|
||||
archive_utility_string_sort_helper(char **strings, unsigned int n)
|
||||
__LA_LIBC_CC
|
||||
archive_utility_string_sort_helper(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned int i, lesser_count, greater_count;
|
||||
char **lesser, **greater, **tmp, *pivot;
|
||||
int retval1, retval2;
|
||||
const char * const * const s1 = p1;
|
||||
const char * const * const s2 = p2;
|
||||
|
||||
/* A list of 0 or 1 elements is already sorted */
|
||||
if (n <= 1)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
lesser_count = greater_count = 0;
|
||||
lesser = greater = NULL;
|
||||
pivot = strings[0];
|
||||
for (i = 1; i < n; i++)
|
||||
{
|
||||
if (strcmp(strings[i], pivot) < 0)
|
||||
{
|
||||
lesser_count++;
|
||||
tmp = realloc(lesser, lesser_count * sizeof(*tmp));
|
||||
if (!tmp) {
|
||||
free(greater);
|
||||
free(lesser);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
lesser = tmp;
|
||||
lesser[lesser_count - 1] = strings[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
greater_count++;
|
||||
tmp = realloc(greater, greater_count * sizeof(*tmp));
|
||||
if (!tmp) {
|
||||
free(greater);
|
||||
free(lesser);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
greater = tmp;
|
||||
greater[greater_count - 1] = strings[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* quicksort(lesser) */
|
||||
retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
|
||||
for (i = 0; i < lesser_count; i++)
|
||||
strings[i] = lesser[i];
|
||||
free(lesser);
|
||||
|
||||
/* pivot */
|
||||
strings[lesser_count] = pivot;
|
||||
|
||||
/* quicksort(greater) */
|
||||
retval2 = archive_utility_string_sort_helper(greater, greater_count);
|
||||
for (i = 0; i < greater_count; i++)
|
||||
strings[lesser_count + 1 + i] = greater[i];
|
||||
free(greater);
|
||||
|
||||
return (retval1 < retval2) ? retval1 : retval2;
|
||||
return strcmp(*s1, *s2);
|
||||
}
|
||||
|
||||
int
|
||||
archive_utility_string_sort(char **strings)
|
||||
{
|
||||
unsigned int size = 0;
|
||||
while (strings[size] != NULL)
|
||||
size_t size = 0;
|
||||
while (strings[size] != NULL)
|
||||
size++;
|
||||
return archive_utility_string_sort_helper(strings, size);
|
||||
qsort(strings, size, sizeof(char *),
|
||||
archive_utility_string_sort_helper);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -134,31 +134,31 @@ archive_libb2_version(struct archive_string* str)
|
||||
static void
|
||||
archive_crypto_version(struct archive_string* str)
|
||||
{
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto) || defined(ARCHIVE_DIGEST_USE_Apple_CommonCrypto)
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto)
|
||||
archive_strcat(str, " CommonCrypto/");
|
||||
archive_strcat(str, archive_commoncrypto_version());
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_CNG) || defined(ARCHIVE_DIGEST_USE_CNG)
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_CNG)
|
||||
archive_strcat(str, " cng/");
|
||||
archive_strcat(str, archive_cng_version());
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_MBED) || defined(ARCHIVE_DIGEST_USE_MBED)
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_MBED)
|
||||
archive_strcat(str, " mbedtls/");
|
||||
archive_strcat(str, archive_mbedtls_version());
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_NETTLE) || defined(ARCHIVE_DIGEST_USE_NETTLE)
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_NETTLE)
|
||||
archive_strcat(str, " nettle/");
|
||||
archive_strcat(str, archive_nettle_version());
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_OPENSSL) || defined(ARCHIVE_DIGEST_USE_OPENSSL)
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_OPENSSL)
|
||||
archive_strcat(str, " openssl/");
|
||||
archive_strcat(str, archive_openssl_version());
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_LIBMD) || defined(ARCHIVE_DIGEST_USE_LIBMD)
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_LIBMD)
|
||||
archive_strcat(str, " libmd/");
|
||||
archive_strcat(str, archive_libmd_version());
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT) || defined(ARCHIVE_DIGEST_USE_WINCRYPT)
|
||||
#if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT)
|
||||
archive_strcat(str, " WinCrypt/");
|
||||
archive_strcat(str, archive_wincrypt_version());
|
||||
#endif
|
||||
@ -333,7 +333,7 @@ archive_libbsdxml_version(void)
|
||||
const char *
|
||||
archive_libxml2_version(void)
|
||||
{
|
||||
#if HAVE_LIBXML_XMLREADER_H && HAVE_LIBXML2
|
||||
#if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2
|
||||
return LIBXML_DOTTED_VERSION;
|
||||
#else
|
||||
return NULL;
|
||||
@ -439,11 +439,11 @@ archive_wincrypt_version(void)
|
||||
if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
|
||||
return NULL;
|
||||
}
|
||||
DWORD length, version;
|
||||
if (!CryptGetProvParam(prov, PP_VERSION, &version, &length, 0)) {
|
||||
DWORD version, length = sizeof(version);
|
||||
if (!CryptGetProvParam(prov, PP_VERSION, (BYTE *)&version, &length, 0)) {
|
||||
return NULL;
|
||||
} else {
|
||||
char major = version >> 8;
|
||||
char major = (version >> 8) & 0xFF;
|
||||
char minor = version & 0xFF;
|
||||
static char wincrypt_version[6];
|
||||
snprintf(wincrypt_version, 6, "%hhd.%hhd", major, minor);
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
|
||||
#include "archive_platform.h"
|
||||
#include "archive_platform_stat.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_time_private.h"
|
||||
@ -313,6 +314,10 @@ __la_open(const char *path, int flags, ...)
|
||||
pmode = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
ws = NULL;
|
||||
|
||||
/* _(w)sopen_s fails if we provide any other modes */
|
||||
pmode = pmode & (_S_IREAD | _S_IWRITE);
|
||||
|
||||
if ((flags & ~O_BINARY) == O_RDONLY) {
|
||||
/*
|
||||
* When we open a directory, _open function returns
|
||||
@ -374,7 +379,7 @@ __la_open(const char *path, int flags, ...)
|
||||
TODO: Fix mode of new file. */
|
||||
r = _open(path, flags);
|
||||
#else
|
||||
r = _open(path, flags, pmode);
|
||||
_sopen_s(&r, path, flags, _SH_DENYNO, pmode);
|
||||
#endif
|
||||
if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
|
||||
/* Simulate other POSIX system action to pass our test suite. */
|
||||
@ -395,7 +400,7 @@ __la_open(const char *path, int flags, ...)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
r = _wopen(ws, flags, pmode);
|
||||
_wsopen_s(&r, ws, flags, _SH_DENYNO, pmode);
|
||||
if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
|
||||
/* Simulate other POSIX system action to pass our test suite. */
|
||||
attr = GetFileAttributesW(ws);
|
||||
@ -410,6 +415,93 @@ __la_open(const char *path, int flags, ...)
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
__la_wopen(const wchar_t *path, int flags, ...)
|
||||
{
|
||||
va_list ap;
|
||||
wchar_t *fullpath;
|
||||
int r, pmode;
|
||||
DWORD attr;
|
||||
|
||||
va_start(ap, flags);
|
||||
pmode = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
fullpath = NULL;
|
||||
|
||||
/* _(w)sopen_s fails if we provide any other modes */
|
||||
pmode = pmode & (_S_IREAD | _S_IWRITE);
|
||||
|
||||
if ((flags & ~O_BINARY) == O_RDONLY) {
|
||||
/*
|
||||
* When we open a directory, _open function returns
|
||||
* "Permission denied" error.
|
||||
*/
|
||||
attr = GetFileAttributesW(path);
|
||||
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
|
||||
if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
|
||||
#endif
|
||||
{
|
||||
fullpath = __la_win_permissive_name_w(path);
|
||||
if (fullpath == NULL) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
path = fullpath;
|
||||
attr = GetFileAttributesW(fullpath);
|
||||
}
|
||||
if (attr == (DWORD)-1) {
|
||||
la_dosmaperr(GetLastError());
|
||||
free(fullpath);
|
||||
return (-1);
|
||||
}
|
||||
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
HANDLE handle;
|
||||
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
|
||||
if (fullpath != NULL)
|
||||
handle = CreateFileW(fullpath, 0, 0, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS |
|
||||
FILE_ATTRIBUTE_READONLY,
|
||||
NULL);
|
||||
else
|
||||
handle = CreateFileW(path, 0, 0, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS |
|
||||
FILE_ATTRIBUTE_READONLY,
|
||||
NULL);
|
||||
#else /* !WINAPI_PARTITION_DESKTOP */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
|
||||
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
handle = CreateFile2(fullpath, 0, 0,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#endif /* !WINAPI_PARTITION_DESKTOP */
|
||||
free(fullpath);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
return (-1);
|
||||
}
|
||||
r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
_wsopen_s(&r, path, flags, _SH_DENYNO, pmode);
|
||||
if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
|
||||
/* Simulate other POSIX system action to pass our test suite. */
|
||||
attr = GetFileAttributesW(path);
|
||||
if (attr == (DWORD)-1)
|
||||
la_dosmaperr(GetLastError());
|
||||
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
errno = EISDIR;
|
||||
else
|
||||
errno = EACCES;
|
||||
}
|
||||
free(fullpath);
|
||||
return (r);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
__la_read(int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
@ -561,6 +653,8 @@ copy_stat(struct stat *st, struct ustat *us)
|
||||
st->st_mode = us->st_mode;
|
||||
st->st_nlink = us->st_nlink;
|
||||
st->st_size = (off_t)us->st_size;
|
||||
if (st->st_size < 0 || (uint64_t)st->st_size != us->st_size)
|
||||
st->st_size = 0;
|
||||
st->st_uid = us->st_uid;
|
||||
st->st_dev = us->st_dev;
|
||||
st->st_rdev = us->st_rdev;
|
||||
@ -630,6 +724,53 @@ __la_stat(const char *path, struct stat *st)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_seek_stat(la_seek_stat_t *st, struct ustat *us)
|
||||
{
|
||||
st->st_mtime = us->st_mtime;
|
||||
st->st_gid = us->st_gid;
|
||||
st->st_ino = getino(us);
|
||||
st->st_mode = us->st_mode;
|
||||
st->st_nlink = us->st_nlink;
|
||||
st->st_size = (la_seek_t)us->st_size;
|
||||
if (st->st_size < 0 || (uint64_t)st->st_size != us->st_size)
|
||||
st->st_size = -1;
|
||||
st->st_uid = us->st_uid;
|
||||
st->st_dev = us->st_dev;
|
||||
st->st_rdev = us->st_rdev;
|
||||
}
|
||||
|
||||
int
|
||||
__la_seek_fstat(int fd, la_seek_stat_t *st)
|
||||
{
|
||||
struct ustat u;
|
||||
int ret;
|
||||
|
||||
ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
|
||||
copy_seek_stat(st, &u);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
__la_seek_stat(const char *path, la_seek_stat_t *st)
|
||||
{
|
||||
HANDLE handle;
|
||||
struct ustat u;
|
||||
int ret;
|
||||
|
||||
handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
return (-1);
|
||||
}
|
||||
ret = __hstat(handle, &u);
|
||||
CloseHandle(handle);
|
||||
copy_seek_stat(st, &u);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This waitpid is limited implementation.
|
||||
*/
|
||||
@ -641,13 +782,14 @@ __la_waitpid(HANDLE child, int *status, int option)
|
||||
(void)option;/* UNUSED */
|
||||
do {
|
||||
if (GetExitCodeProcess(child, &cs) == 0) {
|
||||
CloseHandle(child);
|
||||
la_dosmaperr(GetLastError());
|
||||
CloseHandle(child);
|
||||
*status = 0;
|
||||
return (-1);
|
||||
}
|
||||
} while (cs == STILL_ACTIVE);
|
||||
|
||||
CloseHandle(child);
|
||||
*status = (int)(cs & 0xff);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -72,6 +72,8 @@
|
||||
#include <windows.h>
|
||||
//#define EFTYPE 7
|
||||
|
||||
#include "archive_platform_stat.h"
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
#pragma warn -8068 /* Constant out of range in comparison. */
|
||||
#pragma warn -8072 /* Suspicious pointer arithmetic. */
|
||||
@ -106,6 +108,7 @@
|
||||
#endif
|
||||
#define lstat __la_stat
|
||||
#define open __la_open
|
||||
#define _wopen __la_wopen
|
||||
#define read __la_read
|
||||
#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
|
||||
#define setmode _setmode
|
||||
@ -261,6 +264,9 @@
|
||||
#define F_OK 0 /* Test for existence of file */
|
||||
#endif
|
||||
|
||||
/* Functions to circumvent off_t limitations */
|
||||
int __la_seek_fstat(int fd, la_seek_stat_t *st);
|
||||
int __la_seek_stat(const char *path, la_seek_stat_t *st);
|
||||
|
||||
/* Replacement POSIX function */
|
||||
extern int __la_fstat(int fd, struct stat *st);
|
||||
@ -269,6 +275,7 @@ extern int __la_lstat(const char *path, struct stat *st);
|
||||
extern __int64 __la_lseek(int fd, __int64 offset, int whence);
|
||||
#endif
|
||||
extern int __la_open(const char *path, int flags, ...);
|
||||
extern int __la_wopen(const wchar_t *path, int flags, ...);
|
||||
extern ssize_t __la_read(int fd, void *buf, size_t nbytes);
|
||||
extern int __la_stat(const char *path, struct stat *st);
|
||||
extern pid_t __la_waitpid(HANDLE child, int *status, int option);
|
||||
|
||||
@ -360,7 +360,6 @@ archive_write_client_open(struct archive_write_filter *f)
|
||||
struct archive_none *state;
|
||||
void *buffer;
|
||||
size_t buffer_size;
|
||||
int ret;
|
||||
|
||||
f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
|
||||
f->bytes_in_last_block =
|
||||
@ -385,13 +384,7 @@ archive_write_client_open(struct archive_write_filter *f)
|
||||
|
||||
if (a->client_opener == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
ret = a->client_opener(f->archive, a->client_data);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
free(state->buffer);
|
||||
free(state);
|
||||
f->data = NULL;
|
||||
}
|
||||
return (ret);
|
||||
return (a->client_opener(f->archive, a->client_data));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -480,6 +473,7 @@ static int
|
||||
archive_write_client_free(struct archive_write_filter *f)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)f->archive;
|
||||
struct archive_none *state = (struct archive_none *)f->data;
|
||||
|
||||
if (a->client_freer)
|
||||
(*a->client_freer)(&a->archive, a->client_data);
|
||||
@ -492,6 +486,13 @@ archive_write_client_free(struct archive_write_filter *f)
|
||||
a->passphrase = NULL;
|
||||
}
|
||||
|
||||
/* Free state. */
|
||||
if (state != NULL) {
|
||||
free(state->buffer);
|
||||
free(state);
|
||||
f->data = NULL;
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -548,8 +549,6 @@ archive_write_client_close(struct archive_write_filter *f)
|
||||
}
|
||||
if (a->client_closer)
|
||||
(*a->client_closer)(&a->archive, a->client_data);
|
||||
free(state->buffer);
|
||||
free(state);
|
||||
|
||||
/* Clear the close handler myself not to be called again. */
|
||||
f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
|
||||
@ -807,7 +806,10 @@ _archive_write_finish_entry(struct archive *_a)
|
||||
if (a->archive.state & ARCHIVE_STATE_DATA
|
||||
&& a->format_finish_entry != NULL)
|
||||
ret = (a->format_finish_entry)(a);
|
||||
a->archive.state = ARCHIVE_STATE_HEADER;
|
||||
if (ret == ARCHIVE_FATAL)
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
else
|
||||
a->archive.state = ARCHIVE_STATE_HEADER;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -819,6 +821,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)_a;
|
||||
const size_t max_write = INT_MAX;
|
||||
ssize_t ret;
|
||||
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||
ARCHIVE_STATE_DATA, "archive_write_data");
|
||||
@ -826,7 +829,10 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s)
|
||||
if (s > max_write)
|
||||
s = max_write;
|
||||
archive_clear_error(&a->archive);
|
||||
return ((a->format_write_data)(a, buff, s));
|
||||
ret = (a->format_write_data)(a, buff, s);
|
||||
if (ret == ARCHIVE_FATAL)
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static struct archive_write_filter *
|
||||
|
||||
@ -281,6 +281,10 @@ static int
|
||||
archive_compressor_bzip2_free(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
|
||||
/* May already have been called, but not necessarily. */
|
||||
(void)BZ2_bzCompressEnd(&(data->stream));
|
||||
|
||||
free(data->compressed);
|
||||
free(data);
|
||||
f->data = NULL;
|
||||
|
||||
@ -191,7 +191,8 @@ static int
|
||||
archive_compressor_gzip_open(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
int ret;
|
||||
int ret = ARCHIVE_OK;
|
||||
int init_success;
|
||||
|
||||
if (data->compressed == NULL) {
|
||||
size_t bs = 65536, bpb;
|
||||
@ -221,44 +222,66 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
|
||||
data->compressed[0] = 0x1f; /* GZip signature bytes */
|
||||
data->compressed[1] = 0x8b;
|
||||
data->compressed[2] = 0x08; /* "Deflate" compression */
|
||||
data->compressed[3] = data->original_filename == NULL ? 0 : 0x8;
|
||||
data->compressed[3] = 0x00; /* Flags */
|
||||
if (data->timestamp >= 0) {
|
||||
time_t t = time(NULL);
|
||||
data->compressed[4] = (uint8_t)(t)&0xff; /* Timestamp */
|
||||
data->compressed[5] = (uint8_t)(t>>8)&0xff;
|
||||
data->compressed[6] = (uint8_t)(t>>16)&0xff;
|
||||
data->compressed[7] = (uint8_t)(t>>24)&0xff;
|
||||
} else
|
||||
} else {
|
||||
memset(&data->compressed[4], 0, 4);
|
||||
if (data->compression_level == 9)
|
||||
data->compressed[8] = 2;
|
||||
else if(data->compression_level == 1)
|
||||
data->compressed[8] = 4;
|
||||
else
|
||||
data->compressed[8] = 0;
|
||||
}
|
||||
if (data->compression_level == 9) {
|
||||
data->compressed[8] = 2;
|
||||
} else if(data->compression_level == 1) {
|
||||
data->compressed[8] = 4;
|
||||
} else {
|
||||
data->compressed[8] = 0;
|
||||
}
|
||||
data->compressed[9] = 3; /* OS=Unix */
|
||||
data->stream.next_out += 10;
|
||||
data->stream.avail_out -= 10;
|
||||
|
||||
if (data->original_filename != NULL) {
|
||||
strcpy((char*)data->compressed + 10, data->original_filename);
|
||||
data->stream.next_out += strlen(data->original_filename) + 1;
|
||||
data->stream.avail_out -= strlen(data->original_filename) + 1;
|
||||
/* Limit "original filename" to 32k or the
|
||||
* remaining space in the buffer, whichever is smaller.
|
||||
*/
|
||||
int ofn_length = strlen(data->original_filename);
|
||||
int ofn_max_length = 32768;
|
||||
int ofn_space_available = data->compressed
|
||||
+ data->compressed_buffer_size
|
||||
- data->stream.next_out
|
||||
- 1;
|
||||
if (ofn_max_length > ofn_space_available) {
|
||||
ofn_max_length = ofn_space_available;
|
||||
}
|
||||
if (ofn_length < ofn_max_length) {
|
||||
data->compressed[3] |= 0x8;
|
||||
strcpy((char*)data->compressed + 10,
|
||||
data->original_filename);
|
||||
data->stream.next_out += ofn_length + 1;
|
||||
data->stream.avail_out -= ofn_length + 1;
|
||||
} else {
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Gzip 'Original Filename' ignored because it is too long");
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
|
||||
f->write = archive_compressor_gzip_write;
|
||||
|
||||
/* Initialize compression library. */
|
||||
ret = deflateInit2(&(data->stream),
|
||||
init_success = deflateInit2(&(data->stream),
|
||||
data->compression_level,
|
||||
Z_DEFLATED,
|
||||
-15 /* < 0 to suppress zlib header */,
|
||||
8,
|
||||
Z_DEFAULT_STRATEGY);
|
||||
|
||||
if (ret == Z_OK) {
|
||||
if (init_success == Z_OK) {
|
||||
f->data = data;
|
||||
return (ARCHIVE_OK);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Library setup failed: clean up. */
|
||||
@ -266,7 +289,7 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
|
||||
"initializing compression library");
|
||||
|
||||
/* Override the error message if we know what really went wrong. */
|
||||
switch (ret) {
|
||||
switch (init_success) {
|
||||
case Z_STREAM_ERROR:
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Internal error initializing "
|
||||
|
||||
@ -330,6 +330,7 @@ __archive_write_program_close(struct archive_write_filter *f,
|
||||
struct archive_write_program_data *data)
|
||||
{
|
||||
int ret, status;
|
||||
pid_t pid;
|
||||
ssize_t bytes_read;
|
||||
|
||||
if (data->child == 0)
|
||||
@ -373,14 +374,12 @@ cleanup:
|
||||
close(data->child_stdin);
|
||||
if (data->child_stdout != -1)
|
||||
close(data->child_stdout);
|
||||
while (waitpid(data->child, &status, 0) == -1 && errno == EINTR)
|
||||
continue;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
CloseHandle(data->child);
|
||||
#endif
|
||||
do {
|
||||
pid = waitpid(data->child, &status, 0);
|
||||
} while (pid == -1 && errno == EINTR);
|
||||
data->child = 0;
|
||||
|
||||
if (status != 0) {
|
||||
if (pid < 0 || status != 0) {
|
||||
archive_set_error(f->archive, EIO,
|
||||
"Error closing program: %s", data->program_name);
|
||||
ret = ARCHIVE_FATAL;
|
||||
|
||||
@ -391,6 +391,8 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
|
||||
|
||||
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
|
||||
|
||||
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_checksumFlag, 1);
|
||||
|
||||
#if ZSTD_VERSION_NUMBER >= MINVER_LONG
|
||||
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
|
||||
#endif
|
||||
|
||||
@ -412,12 +412,14 @@ static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
|
||||
static int
|
||||
la_mktemp(struct archive_write_disk *a)
|
||||
{
|
||||
struct archive_string *tmp = &a->_tmpname_data;
|
||||
int oerrno, fd;
|
||||
mode_t mode;
|
||||
|
||||
archive_string_empty(&a->_tmpname_data);
|
||||
archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name);
|
||||
a->tmpname = a->_tmpname_data.s;
|
||||
archive_strcpy(tmp, a->name);
|
||||
archive_string_dirname(tmp);
|
||||
archive_strcat(tmp, "/tar.XXXXXXXX");
|
||||
a->tmpname = tmp->s;
|
||||
|
||||
fd = __archive_mkstemp(a->tmpname);
|
||||
if (fd == -1)
|
||||
@ -2204,7 +2206,7 @@ restore_entry(struct archive_write_disk *a)
|
||||
(void)clear_nochange_fflags(a);
|
||||
|
||||
if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
|
||||
S_ISREG(a->st.st_mode)) {
|
||||
S_ISREG(a->mode)) {
|
||||
/* Use a temporary file to extract */
|
||||
if ((a->fd = la_mktemp(a)) == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
@ -3930,10 +3932,14 @@ clear_nochange_fflags(struct archive_write_disk *a)
|
||||
#ifdef UF_APPEND
|
||||
| UF_APPEND
|
||||
#endif
|
||||
#ifdef EXT2_APPEND_FL
|
||||
#if defined(FS_APPEND_FL)
|
||||
| FS_APPEND_FL
|
||||
#elif defined(EXT2_APPEND_FL)
|
||||
| EXT2_APPEND_FL
|
||||
#endif
|
||||
#ifdef EXT2_IMMUTABLE_FL
|
||||
#if defined(FS_IMMUTABLE_FL)
|
||||
| FS_IMMUTABLE_FL
|
||||
#elif defined(EXT2_IMMUTABLE_FL)
|
||||
| EXT2_IMMUTABLE_FL
|
||||
#endif
|
||||
;
|
||||
@ -4283,8 +4289,10 @@ create_tempdatafork(struct archive_write_disk *a, const char *pathname)
|
||||
int tmpfd;
|
||||
|
||||
archive_string_init(&tmpdatafork);
|
||||
archive_strcpy(&tmpdatafork, "tar.md.XXXXXX");
|
||||
tmpfd = mkstemp(tmpdatafork.s);
|
||||
archive_strcpy(&tmpdatafork, pathname);
|
||||
archive_string_dirname(&tmpdatafork);
|
||||
archive_strcat(&tmpdatafork, "/tar.XXXXXXXX");
|
||||
tmpfd = __archive_mkstemp(tmpdatafork.s);
|
||||
if (tmpfd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to mkstemp");
|
||||
@ -4363,8 +4371,10 @@ 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, "tar.mmd.XXXXXX");
|
||||
fd = mkstemp(tmp.s);
|
||||
archive_strcpy(&tmp, pathname);
|
||||
archive_string_dirname(&tmp);
|
||||
archive_strcat(&tmp, "/tar.XXXXXXXX");
|
||||
fd = __archive_mkstemp(tmp.s);
|
||||
|
||||
if (fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
|
||||
@ -408,7 +408,11 @@ permissive_name_w(struct archive_write_disk *a)
|
||||
wn = _wcsdup(wnp);
|
||||
if (wn == NULL)
|
||||
return (-1);
|
||||
archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1);
|
||||
if (archive_wstring_ensure(&(a->_name_data),
|
||||
4 + wcslen(wn) + 1) == NULL) {
|
||||
free(wn);
|
||||
return (-1);
|
||||
}
|
||||
a->name = a->_name_data.s;
|
||||
/* Prepend "\\?\" */
|
||||
archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
|
||||
@ -438,8 +442,11 @@ permissive_name_w(struct archive_write_disk *a)
|
||||
wn = _wcsdup(wnp);
|
||||
if (wn == NULL)
|
||||
return (-1);
|
||||
archive_wstring_ensure(&(a->_name_data),
|
||||
8 + wcslen(wn) + 1);
|
||||
if (archive_wstring_ensure(&(a->_name_data),
|
||||
8 + wcslen(wn) + 1) == NULL) {
|
||||
free(wn);
|
||||
return (-1);
|
||||
}
|
||||
a->name = a->_name_data.s;
|
||||
/* Prepend "\\?\UNC\" */
|
||||
archive_wstrncpy(&(a->_name_data),
|
||||
@ -471,10 +478,16 @@ permissive_name_w(struct archive_write_disk *a)
|
||||
*/
|
||||
if (wnp[0] == L'\\') {
|
||||
wn = _wcsdup(wnp);
|
||||
if (wn == NULL)
|
||||
if (wn == NULL) {
|
||||
free(wsp);
|
||||
return (-1);
|
||||
archive_wstring_ensure(&(a->_name_data),
|
||||
4 + 2 + wcslen(wn) + 1);
|
||||
}
|
||||
if (archive_wstring_ensure(&(a->_name_data),
|
||||
4 + 2 + wcslen(wn) + 1) == NULL) {
|
||||
free(wsp);
|
||||
free(wn);
|
||||
return (-1);
|
||||
}
|
||||
a->name = a->_name_data.s;
|
||||
/* Prepend "\\?\" and drive name. */
|
||||
archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
|
||||
@ -486,9 +499,16 @@ permissive_name_w(struct archive_write_disk *a)
|
||||
}
|
||||
|
||||
wn = _wcsdup(wnp);
|
||||
if (wn == NULL)
|
||||
if (wn == NULL) {
|
||||
free(wsp);
|
||||
return (-1);
|
||||
archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
|
||||
}
|
||||
if (archive_wstring_ensure(&(a->_name_data),
|
||||
4 + l + 1 + wcslen(wn) + 1) == NULL) {
|
||||
free(wsp);
|
||||
free(wn);
|
||||
return (-1);
|
||||
}
|
||||
a->name = a->_name_data.s;
|
||||
/* Prepend "\\?\" and drive name if not already added. */
|
||||
if (l > 3 && wsp[0] == L'\\' && wsp[1] == L'\\' &&
|
||||
@ -1598,7 +1618,7 @@ restore_entry(struct archive_write_disk *a)
|
||||
(void)clear_nochange_fflags(a);
|
||||
}
|
||||
if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
|
||||
S_ISREG(st_mode)) {
|
||||
S_ISREG(a->mode)) {
|
||||
int fd = la_mktemp(a);
|
||||
|
||||
if (fd == -1) {
|
||||
|
||||
@ -122,7 +122,7 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
|
||||
mine = (struct write_fd_data *)client_data;
|
||||
for (;;) {
|
||||
bytesWritten = write(mine->fd, buff, length);
|
||||
if (bytesWritten <= 0) {
|
||||
if (bytesWritten < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
archive_set_error(a, errno, "Write error");
|
||||
|
||||
@ -85,16 +85,12 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
|
||||
size_t bytesWritten;
|
||||
|
||||
mine = client_data;
|
||||
for (;;) {
|
||||
bytesWritten = fwrite(buff, 1, length, mine->f);
|
||||
if (bytesWritten <= 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
archive_set_error(a, errno, "Write error");
|
||||
return (-1);
|
||||
}
|
||||
return (bytesWritten);
|
||||
bytesWritten = fwrite(buff, 1, length, mine->f);
|
||||
if (bytesWritten != length) {
|
||||
archive_set_error(a, errno, "Write error");
|
||||
return (-1);
|
||||
}
|
||||
return (bytesWritten);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@ -108,6 +108,7 @@ open_filename(struct archive *a, int mbs_fn, const void *filename)
|
||||
else
|
||||
r = archive_mstring_copy_wcs(&mine->filename, filename);
|
||||
if (r < 0) {
|
||||
free(mine);
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
@ -190,6 +191,8 @@ file_open(struct archive *a, void *client_data)
|
||||
archive_set_error(a, errno, "Couldn't stat '%s'", mbs);
|
||||
else
|
||||
archive_set_error(a, errno, "Couldn't stat '%ls'", wcs);
|
||||
close(mine->fd);
|
||||
mine->fd = -1;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@ -227,7 +230,7 @@ file_write(struct archive *a, void *client_data, const void *buff,
|
||||
mine = (struct write_file_data *)client_data;
|
||||
for (;;) {
|
||||
bytesWritten = write(mine->fd, buff, length);
|
||||
if (bytesWritten <= 0) {
|
||||
if (bytesWritten < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
archive_set_error(a, errno, "Write error");
|
||||
|
||||
@ -686,7 +686,7 @@ write_to_temp(struct archive_write *a, const void *buff, size_t s)
|
||||
ws = write(zip->temp_fd, p, s);
|
||||
if (ws < 0) {
|
||||
archive_set_error(&(a->archive), errno,
|
||||
"fwrite function failed");
|
||||
"write function failed");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
s -= ws;
|
||||
|
||||
@ -1167,7 +1167,12 @@ archive_write_set_format_iso9660(struct archive *_a)
|
||||
iso9660->primary.rootent->parent = iso9660->primary.rootent;
|
||||
iso9660->cur_dirent = iso9660->primary.rootent;
|
||||
archive_string_init(&(iso9660->cur_dirstr));
|
||||
archive_string_ensure(&(iso9660->cur_dirstr), 1);
|
||||
if (archive_string_ensure(&(iso9660->cur_dirstr), 1) == NULL) {
|
||||
free(iso9660);
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
iso9660->cur_dirstr.s[0] = 0;
|
||||
iso9660->sconv_to_utf16be = NULL;
|
||||
iso9660->sconv_from_utf16be = NULL;
|
||||
@ -5666,9 +5671,15 @@ isoent_tree(struct archive_write *a, struct isoent **isoentpp)
|
||||
* inserted. */
|
||||
iso9660->cur_dirent = dent;
|
||||
archive_string_empty(&(iso9660->cur_dirstr));
|
||||
archive_string_ensure(&(iso9660->cur_dirstr),
|
||||
if (archive_string_ensure(&(iso9660->cur_dirstr),
|
||||
archive_strlen(&(dent->file->parentdir)) +
|
||||
archive_strlen(&(dent->file->basename)) + 2);
|
||||
archive_strlen(&(dent->file->basename)) + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory");
|
||||
_isoent_free(isoent);
|
||||
*isoentpp = NULL;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (archive_strlen(&(dent->file->parentdir)) +
|
||||
archive_strlen(&(dent->file->basename)) == 0)
|
||||
iso9660->cur_dirstr.s[0] = 0;
|
||||
|
||||
@ -1927,7 +1927,7 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out the position which points the last position of
|
||||
* Find out the position which points to the last position of
|
||||
* path separator('/').
|
||||
*/
|
||||
slash = NULL;
|
||||
@ -2024,7 +2024,7 @@ mtree_entry_add_child_tail(struct mtree_entry *parent,
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a entry from a parent entry with the name.
|
||||
* Find an entry from a parent entry with given name.
|
||||
*/
|
||||
static struct mtree_entry *
|
||||
mtree_entry_find_child(struct mtree_entry *parent, const char *child_name)
|
||||
@ -2148,10 +2148,10 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
|
||||
|
||||
/* Find next sub directory. */
|
||||
if (!np->dir_info) {
|
||||
/* NOT Directory! */
|
||||
/* NOT a directory! */
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"`%s' is not directory, we cannot insert `%s' ",
|
||||
"`%s' is not a directory, we cannot insert `%s' ",
|
||||
np->pathname.s, file->pathname.s);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
@ -2209,9 +2209,13 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
|
||||
* inserted. */
|
||||
mtree->cur_dirent = dent;
|
||||
archive_string_empty(&(mtree->cur_dirstr));
|
||||
archive_string_ensure(&(mtree->cur_dirstr),
|
||||
if (archive_string_ensure(&(mtree->cur_dirstr),
|
||||
archive_strlen(&(dent->parentdir)) +
|
||||
archive_strlen(&(dent->basename)) + 2);
|
||||
archive_strlen(&(dent->basename)) + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (archive_strlen(&(dent->parentdir)) +
|
||||
archive_strlen(&(dent->basename)) == 0)
|
||||
mtree->cur_dirstr.s[0] = 0;
|
||||
@ -2239,10 +2243,7 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
|
||||
}
|
||||
|
||||
same_entry:
|
||||
/*
|
||||
* We have already has the entry the filename of which is
|
||||
* the same.
|
||||
*/
|
||||
/* We already have an entry with same filename. */
|
||||
r = mtree_entry_exchange_same_entry(a, np, file);
|
||||
if (r < ARCHIVE_WARN)
|
||||
return (r);
|
||||
@ -2260,13 +2261,13 @@ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
|
||||
|
||||
if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Found duplicate entries `%s' and its file type is "
|
||||
"different",
|
||||
"Found duplicate entries for `%s' with "
|
||||
"differing file types.",
|
||||
np->pathname.s);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
/* Update the existent mtree entry's attributes by the new one's. */
|
||||
/* Update the existing mtree entry's attributes by the new one's. */
|
||||
archive_string_empty(&np->symlink);
|
||||
archive_string_concat(&np->symlink, &file->symlink);
|
||||
archive_string_empty(&np->uname);
|
||||
|
||||
@ -689,7 +689,7 @@ write_to_temp(struct archive_write *a, const void *buff, size_t s)
|
||||
ws = write(xar->temp_fd, p, s);
|
||||
if (ws < 0) {
|
||||
archive_set_error(&(a->archive), errno,
|
||||
"fwrite function failed");
|
||||
"write function failed");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
s -= ws;
|
||||
@ -1000,13 +1000,13 @@ xmlwrite_heap(struct archive_write *a, struct xml_writer *writer,
|
||||
const char *encname;
|
||||
int r;
|
||||
|
||||
r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
|
||||
r = xmlwrite_fstring(a, writer, "length", "%ju", (uintmax_t)heap->length);
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
|
||||
r = xmlwrite_fstring(a, writer, "offset", "%ju", (uintmax_t)heap->temp_offset);
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
|
||||
r = xmlwrite_fstring(a, writer, "size", "%ju", (uintmax_t)heap->size);
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
switch (heap->compression) {
|
||||
@ -1356,7 +1356,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer,
|
||||
* Make a inode entry, "<inode>".
|
||||
*/
|
||||
r = xmlwrite_fstring(a, writer, "inode",
|
||||
"%jd", archive_entry_ino64(file->entry));
|
||||
"%jd", (intmax_t)archive_entry_ino64(file->entry));
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (archive_entry_dev(file->entry) != 0) {
|
||||
@ -1378,7 +1378,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer,
|
||||
* Make a user entry, "<uid>" and "<user>.
|
||||
*/
|
||||
r = xmlwrite_fstring(a, writer, "uid",
|
||||
"%d", archive_entry_uid(file->entry));
|
||||
"%jd", (intmax_t)archive_entry_uid(file->entry));
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
|
||||
@ -1404,7 +1404,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer,
|
||||
* Make a group entry, "<gid>" and "<group>.
|
||||
*/
|
||||
r = xmlwrite_fstring(a, writer, "gid",
|
||||
"%d", archive_entry_gid(file->entry));
|
||||
"%jd", (intmax_t)archive_entry_gid(file->entry));
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
|
||||
@ -3418,8 +3418,8 @@ static int
|
||||
xml_writer_get_final_content_and_length(struct xml_writer *ctx,
|
||||
const char **out, size_t *size)
|
||||
{
|
||||
*out = (const char*)ctx->bp->content;
|
||||
*size = (size_t)ctx->bp->use;
|
||||
*out = (const char*)xmlBufferContent(ctx->bp);
|
||||
*size = (size_t)xmlBufferLength(ctx->bp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@ -1856,7 +1856,10 @@ archive_write_zip_finish_entry(struct archive_write *a)
|
||||
}
|
||||
ret = __archive_write_output(a, zip->buf, remainder);
|
||||
if (ret != ARCHIVE_OK)
|
||||
{
|
||||
deflateEnd(&zip->stream.deflate);
|
||||
return (ret);
|
||||
}
|
||||
zip->entry_compressed_written += remainder;
|
||||
zip->written_bytes += remainder;
|
||||
zip->stream.deflate.next_out = zip->buf;
|
||||
@ -1898,7 +1901,10 @@ archive_write_zip_finish_entry(struct archive_write *a)
|
||||
}
|
||||
ret = __archive_write_output(a, zip->buf, remainder);
|
||||
if (ret != ARCHIVE_OK)
|
||||
{
|
||||
BZ2_bzCompressEnd(&zip->stream.bzip2);
|
||||
return (ret);
|
||||
}
|
||||
zip->entry_compressed_written += remainder;
|
||||
zip->written_bytes += remainder;
|
||||
zip->stream.bzip2.next_out = (char*)zip->buf;
|
||||
@ -1940,13 +1946,17 @@ archive_write_zip_finish_entry(struct archive_write *a)
|
||||
}
|
||||
ret = __archive_write_output(a, zip->buf, remainder);
|
||||
if (ret != ARCHIVE_OK)
|
||||
{
|
||||
ZSTD_freeCStream(zip->stream.zstd.context);
|
||||
return (ret);
|
||||
}
|
||||
zip->entry_compressed_written += remainder;
|
||||
zip->written_bytes += remainder;
|
||||
zip->stream.zstd.out.dst = zip->buf;
|
||||
if (zip->stream.zstd.out.pos != zip->stream.zstd.out.size)
|
||||
finishing = 0;
|
||||
zip->stream.zstd.out.dst = zip->buf;
|
||||
zip->stream.zstd.out.size = zip->len_buf;
|
||||
zip->stream.zstd.out.pos = 0;
|
||||
} while (finishing);
|
||||
ZSTD_freeCStream(zip->stream.zstd.context);
|
||||
break;
|
||||
@ -1984,7 +1994,10 @@ archive_write_zip_finish_entry(struct archive_write *a)
|
||||
}
|
||||
ret = __archive_write_output(a, zip->buf, remainder);
|
||||
if (ret != ARCHIVE_OK)
|
||||
{
|
||||
lzma_end(&zip->stream.lzma.context);
|
||||
return (ret);
|
||||
}
|
||||
zip->entry_compressed_written += remainder;
|
||||
zip->written_bytes += remainder;
|
||||
zip->stream.lzma.context.next_out = zip->buf;
|
||||
@ -2434,13 +2447,19 @@ init_winzip_aes_encryption(struct archive_write *a)
|
||||
"Can't generate random number for encryption");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_pbkdf2_sha1(passphrase, strlen(passphrase),
|
||||
ret = archive_pbkdf2_sha1(passphrase, strlen(passphrase),
|
||||
salt, salt_len, 1000, derived_key, key_len * 2 + 2);
|
||||
if (ret != 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
ret == CRYPTOR_STUB_FUNCTION ? "Encryption is unsupported due to "
|
||||
"lack of crypto library" : "Failed to process passphrase");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
|
||||
if (ret != 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Decryption is unsupported due to lack of crypto library");
|
||||
"Failed to initialize AES CTR mode");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Joerg Sonnenberger
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -76,7 +76,15 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
{
|
||||
pid_t child = -1;
|
||||
int stdin_pipe[2], stdout_pipe[2], tmp;
|
||||
|
||||
#if !defined(POSIX_SPAWN_CLOEXEC_DEFAULT) && \
|
||||
(HAVE_FORK || HAVE_VFORK) && \
|
||||
(HAVE_CLOSEFROM || HAVE_CLOSE_RANGE || defined(_SC_OPEN_MAX))
|
||||
#undef HAVE_POSIX_SPAWNP
|
||||
#endif
|
||||
|
||||
#if HAVE_POSIX_SPAWNP
|
||||
posix_spawnattr_t attr;
|
||||
posix_spawn_file_actions_t actions;
|
||||
int r;
|
||||
#endif
|
||||
@ -107,11 +115,21 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
|
||||
#if HAVE_POSIX_SPAWNP
|
||||
|
||||
r = posix_spawn_file_actions_init(&actions);
|
||||
r = posix_spawnattr_init(&attr);
|
||||
if (r != 0) {
|
||||
errno = r;
|
||||
goto stdout_opened;
|
||||
}
|
||||
r = posix_spawn_file_actions_init(&actions);
|
||||
if (r != 0) {
|
||||
errno = r;
|
||||
goto attr_inited;
|
||||
}
|
||||
#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
|
||||
r = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT);
|
||||
if (r != 0)
|
||||
goto actions_inited;
|
||||
#endif
|
||||
r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[1]);
|
||||
if (r != 0)
|
||||
goto actions_inited;
|
||||
@ -136,11 +154,12 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
if (r != 0)
|
||||
goto actions_inited;
|
||||
}
|
||||
r = posix_spawnp(&child, cmdline->path, &actions, NULL,
|
||||
r = posix_spawnp(&child, cmdline->path, &actions, &attr,
|
||||
cmdline->argv, NULL);
|
||||
if (r != 0)
|
||||
goto actions_inited;
|
||||
posix_spawn_file_actions_destroy(&actions);
|
||||
posix_spawnattr_destroy(&attr);
|
||||
|
||||
#else /* HAVE_POSIX_SPAWNP */
|
||||
|
||||
@ -162,6 +181,16 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
_exit(254);
|
||||
if (stdout_pipe[1] != 1 /* stdout */)
|
||||
close(stdout_pipe[1]);
|
||||
|
||||
#if HAVE_CLOSEFROM
|
||||
closefrom(3);
|
||||
#elif HAVE_CLOSE_RANGE
|
||||
close_range(3, ~0U, 0);
|
||||
#elif defined(_SC_OPEN_MAX)
|
||||
for (int i = sysconf(_SC_OPEN_MAX); i > 3;)
|
||||
close(--i);
|
||||
#endif
|
||||
|
||||
execvp(cmdline->path, cmdline->argv);
|
||||
_exit(254);
|
||||
}
|
||||
@ -183,6 +212,8 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
actions_inited:
|
||||
errno = r;
|
||||
posix_spawn_file_actions_destroy(&actions);
|
||||
attr_inited:
|
||||
posix_spawnattr_destroy(&attr);
|
||||
#endif
|
||||
stdout_opened:
|
||||
close(stdout_pipe[0]);
|
||||
|
||||
34
libarchive/module.modulemap
Normal file
34
libarchive/module.modulemap
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Clang Module Map for libarchive
|
||||
*
|
||||
* What this is:
|
||||
* This file tells the Clang compiler how to treat libarchive as a "module" -
|
||||
* a self-contained unit of code that can be imported all at once instead of
|
||||
* including individual header files. Think of it like a package definition.
|
||||
*
|
||||
* How it works:
|
||||
* - When you write `@import CArchive` (Objective-C) or `import CArchive` (Swift),
|
||||
* the compiler uses this file to know which headers belong to libarchive
|
||||
* - Instead of processing each #include separately, the compiler can load a
|
||||
* pre-compiled version of the entire library, making builds faster
|
||||
* - This also provides better dependency tracking and can catch issues like
|
||||
* conflicting macro definitions between libraries
|
||||
*
|
||||
* When to update:
|
||||
* Update this file whenever:
|
||||
* - New public header files are added to libarchive's libarchive/ directory
|
||||
* - Public headers are removed or renamed
|
||||
* - The library's API structure changes significantly
|
||||
*
|
||||
* You typically don't need to update this for:
|
||||
* - Internal implementation changes
|
||||
* - Private/internal header modifications
|
||||
* - Documentation updates
|
||||
*
|
||||
* NOTE: This only affects projects using Clang with modules enabled. Traditional
|
||||
* #include-based builds will continue to work normally with or without this file.
|
||||
*/
|
||||
module CArchive {
|
||||
header "archive.h"
|
||||
header "archive_entry.h"
|
||||
}
|
||||
@ -108,6 +108,7 @@ IF(ENABLE_TEST)
|
||||
test_read_format_7zip_encryption_data.c
|
||||
test_read_format_7zip_encryption_header.c
|
||||
test_read_format_7zip_encryption_partially.c
|
||||
test_read_format_7zip_issue2765.c
|
||||
test_read_format_7zip_malformed.c
|
||||
test_read_format_7zip_packinfo_digests.c
|
||||
test_read_format_ar.c
|
||||
@ -168,14 +169,17 @@ IF(ENABLE_TEST)
|
||||
test_read_format_rar5.c
|
||||
test_read_format_raw.c
|
||||
test_read_format_tar.c
|
||||
test_read_format_tar_V_negative_size.c
|
||||
test_read_format_tar_concatenated.c
|
||||
test_read_format_tar_empty_filename.c
|
||||
test_read_format_tar_empty_with_gnulabel.c
|
||||
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_mac_metadata.c
|
||||
test_read_format_tar_pax_g_large.c
|
||||
test_read_format_tar_pax_large_attr.c
|
||||
test_read_format_tar_pax_negative_time.c
|
||||
test_read_format_tbz.c
|
||||
test_read_format_tgz.c
|
||||
test_read_format_tlz.c
|
||||
@ -208,6 +212,7 @@ IF(ENABLE_TEST)
|
||||
test_read_format_zip_zip64.c
|
||||
test_read_format_zip_with_invalid_traditional_eocd.c
|
||||
test_read_large.c
|
||||
test_read_pax_empty_val_no_nl.c
|
||||
test_read_pax_xattr_rht_security_selinux.c
|
||||
test_read_pax_xattr_schily.c
|
||||
test_read_pax_truncated.c
|
||||
|
||||
@ -145,6 +145,13 @@ static struct archive_test_acl_t acls_bad[] = {
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
|
||||
|
||||
/* Multiple types */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW | ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_NFS4, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
|
||||
};
|
||||
|
||||
DEFINE_TEST(test_acl_nfs4)
|
||||
|
||||
@ -94,6 +94,11 @@ static struct archive_test_acl_t acls_nfs4[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
|
||||
/* Invalid type codes */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
};
|
||||
|
||||
DEFINE_TEST(test_acl_posix1e)
|
||||
|
||||
@ -39,6 +39,8 @@ DEFINE_TEST(test_archive_parse_date)
|
||||
assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0);
|
||||
assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138);
|
||||
assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980);
|
||||
assertEqualInt(get_date(now, "2038-06-01 00:01:02 UTC"),
|
||||
sizeof(time_t) <= 4 ? -1 : 2158963262);
|
||||
assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000);
|
||||
assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460);
|
||||
assertEqualInt(get_date(now, "now - 2 hours"),
|
||||
|
||||
@ -202,7 +202,7 @@ static int64_t
|
||||
file_skip(struct archive *a, void *data, int64_t request)
|
||||
{
|
||||
struct mydata *mydata = (struct mydata *)data;
|
||||
int64_t result = lseek(mydata->fd, SEEK_CUR, request);
|
||||
int64_t result = lseek(mydata->fd, request, SEEK_CUR);
|
||||
if (result >= 0)
|
||||
return result;
|
||||
archive_set_error(a, errno, "Error seeking in '%s'", mydata->filename);
|
||||
|
||||
@ -353,6 +353,43 @@ test_archive_string_sprintf(void)
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
test_archive_string_dirname(void)
|
||||
{
|
||||
static struct pair { const char *str, *exp; } pairs[] = {
|
||||
{ "", "." },
|
||||
{ "/", "/" },
|
||||
{ "//", "/" },
|
||||
{ "///", "/" },
|
||||
{ "./", "." },
|
||||
{ ".", "." },
|
||||
{ "..", "." },
|
||||
{ "foo", "." },
|
||||
{ "foo/", "." },
|
||||
{ "foo//", "." },
|
||||
{ "foo/bar", "foo" },
|
||||
{ "foo/bar/", "foo" },
|
||||
{ "foo/bar//", "foo" },
|
||||
{ "foo//bar", "foo" },
|
||||
{ "foo//bar/", "foo" },
|
||||
{ "foo//bar//", "foo" },
|
||||
{ "/foo", "/" },
|
||||
{ "//foo", "/" },
|
||||
{ "//foo/", "/" },
|
||||
{ "//foo//", "/" },
|
||||
{ 0 },
|
||||
};
|
||||
struct pair *pair;
|
||||
struct archive_string s;
|
||||
|
||||
archive_string_init(&s);
|
||||
for (pair = pairs; pair->str; pair++) {
|
||||
archive_strcpy(&s, pair->str);
|
||||
archive_string_dirname(&s);
|
||||
assertEqualString(pair->exp, s.s);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string)
|
||||
{
|
||||
test_archive_string_ensure();
|
||||
@ -364,6 +401,7 @@ DEFINE_TEST(test_archive_string)
|
||||
test_archive_string_concat();
|
||||
test_archive_string_copy();
|
||||
test_archive_string_sprintf();
|
||||
test_archive_string_dirname();
|
||||
}
|
||||
|
||||
static const char *strings[] =
|
||||
|
||||
@ -991,6 +991,7 @@ DEFINE_TEST(test_archive_string_update_utf8_koi8)
|
||||
static const char koi8_string[] = "\xD0\xD2\xC9";
|
||||
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
|
||||
struct archive_mstring mstr;
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
memset(&mstr, 0, sizeof(mstr));
|
||||
@ -999,6 +1000,15 @@ DEFINE_TEST(test_archive_string_update_utf8_koi8)
|
||||
skipping("KOI8-R locale not available on this system.");
|
||||
return;
|
||||
}
|
||||
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 KOI8-R to UTF-8.");
|
||||
archive_write_free(a);
|
||||
return;
|
||||
}
|
||||
archive_write_free(a);
|
||||
|
||||
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
|
||||
|
||||
|
||||
@ -98,6 +98,8 @@ DEFINE_TEST(test_compat_lz4)
|
||||
verify("test_compat_lz4_3.tar.lz4.uu", n);
|
||||
/* This sample has been compressed with -B4 option. */
|
||||
verify("test_compat_lz4_B4.tar.lz4.uu", n2);
|
||||
/* This sample has been compresed with -B4, and has two skippable frames at the start. */
|
||||
verify("test_compat_lz4_skippable_frames_B4.tar.lz4.uu", n2);
|
||||
/* This sample has been compressed with -B5 option. */
|
||||
verify("test_compat_lz4_B5.tar.lz4.uu", n2);
|
||||
/* This sample has been compressed with -B6 option. */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user