mirror of
https://git.freebsd.org/src.git
synced 2026-01-16 23:02:24 +00:00
Update vendor/libarchive to 3.7.5
Security fixes: #2158 rpm: calculate huge header sizes correctly #2160 util: fix out of boundary access in mktemp functions #2168 uu: stop processing if lines are too long #2174 lzop: prevent integer overflow #2172 rar4: protect copy_from_lzss_window_to_unp() (CVE-2024-20696) #2175 unzip: unify EOF handling #2179 rar4: fix out of boundary access with large files #2203 rar4: fix OOB access with unicode filenames #2210 rar4: add boundary checks to rgb filter #2248 rar4: fix OOB in delta filter #2249 rar4: fix OOB in audio filter #2256 fix multiple vulnerabilities identified by SAST #2258 cpio: ignore out-of-range gid/uid/size/ino and harden AFIO parsing #2265 rar5: clear 'data ready' cache on window buffer reallocs #2269 rar4: fix CVE-2024-26256 (CVE-2024-26256) Important bugfixes: #2150 xar: fix another infinite loop and expat error handling #2173 shar: check strdup return value #2161 lha: fix integer truncation on 32-bit systems #2245 7zip: fix issue when skipping first file in 7zip archive that is a multiple of 65536 bytes #2259 rar5: don't try to read rediculously long names #2290 ar: fix archive entries having no type Obtained from: libarchive Vendor commit: 12ecf8418ab3595d66cdea1abadcea8b6a9d288b CVE: CVE-2024-20696, CVE-2024-26256
This commit is contained in:
parent
ed3e988642
commit
2022efa030
117 changed files with 4232 additions and 1296 deletions
|
|
@ -12,7 +12,7 @@ FreeBSD_task:
|
|||
freebsd_instance:
|
||||
image_family: freebsd-14-0
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-2
|
||||
image_family: freebsd-13-3
|
||||
prepare_script:
|
||||
- ./build/ci/cirrus_ci/ci.sh prepare
|
||||
configure_script:
|
||||
|
|
|
|||
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@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- name: Install dependencies
|
||||
run: ./build/ci/github_actions/macos.sh prepare
|
||||
- name: Autogen
|
||||
|
|
@ -57,7 +57,7 @@ jobs:
|
|||
bs: [autotools, cmake]
|
||||
crypto: [mbedtls, nettle, openssl]
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- name: Update apt cache
|
||||
run: sudo apt-get update
|
||||
- name: Install dependencies
|
||||
|
|
@ -98,7 +98,7 @@ jobs:
|
|||
Ubuntu-distcheck:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- name: Update package definitions
|
||||
run: sudo apt-get update
|
||||
- name: Install dependencies
|
||||
|
|
@ -125,7 +125,7 @@ jobs:
|
|||
matrix:
|
||||
be: [mingw-gcc, msvc]
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- name: Install mingw
|
||||
if: ${{ matrix.be=='mingw-gcc' }}
|
||||
run: choco install mingw
|
||||
|
|
|
|||
8
.github/workflows/codeql.yml
vendored
8
.github/workflows/codeql.yml
vendored
|
|
@ -26,18 +26,18 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
|
||||
uses: github/codeql-action/init@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
|
||||
uses: github/codeql-action/autobuild@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
|
||||
uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
|
|
|||
6
.github/workflows/scorecard.yml
vendored
6
.github/workflows/scorecard.yml
vendored
|
|
@ -29,12 +29,12 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
|
|
@ -60,6 +60,6 @@ jobs:
|
|||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
|
||||
uses: github/codeql-action/upload-sarif@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -63,8 +63,10 @@ CMakeCache.txt
|
|||
CMakeFiles/
|
||||
DartConfiguration.tcl
|
||||
cmake.tmp/
|
||||
cmake-*/
|
||||
.vs/
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
doc/html/*.html
|
||||
doc/man/*.1
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
#
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
|
||||
if(APPLE AND CMAKE_VERSION VERSION_LESS "3.17.0")
|
||||
message(WARNING "CMake>=3.17.0 required to make the generated shared library have the same Mach-O headers as autotools")
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0065)
|
||||
cmake_policy(SET CMP0065 NEW) #3.4 don't use `-rdynamic` with executables
|
||||
endif()
|
||||
|
|
@ -83,9 +87,21 @@ SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
|
|||
# libarchive 3.1 == interface version 13
|
||||
math(EXPR INTERFACE_VERSION "13 + ${_minor}")
|
||||
|
||||
# Set SOVERSION == Interface version
|
||||
# ?? Should there be more here ??
|
||||
SET(SOVERSION "${INTERFACE_VERSION}")
|
||||
# Set SOVERSION so it matches libtool's conventions
|
||||
# libtool accepts a string "current:revision:age"; in libarchive, that's set to
|
||||
# - current: ${INTERFACE_VERSION} = 13 + ${_minor}
|
||||
# - revision: ${_revision}
|
||||
# - age: ${_minor}
|
||||
# Since libtool computes SOVERSION as "current - age", it's just '13' again
|
||||
math(EXPR SOVERSION "${INTERFACE_VERSION} - ${_minor}")
|
||||
set(SOVERSION_FULL "${SOVERSION}.${_trimmed_minor}.${_trimmed_revision}")
|
||||
|
||||
# Override CMake's default shared library versioning scheme, which uses SOVERSION and VERSION,
|
||||
# to match libtool's conventions (see https://github.com/mesonbuild/meson/issues/1451)
|
||||
# - compatibility version: current + 1 = ${INTERFACE_VERSION} + 1
|
||||
# - current version: ${current + 1}.${revision}
|
||||
math(EXPR MACHO_COMPATIBILITY_VERSION "${INTERFACE_VERSION} + 1")
|
||||
set(MACHO_CURRENT_VERSION "${MACHO_COMPATIBILITY_VERSION}.${_revision}")
|
||||
|
||||
# Enable CMAKE_PUSH_CHECK_STATE() and CMAKE_POP_CHECK_STATE() macros
|
||||
# saving and restoring the state of the variables.
|
||||
|
|
@ -107,7 +123,7 @@ endif ()
|
|||
# aggressive about diagnosing build problems; this can get
|
||||
# relaxed somewhat in final shipping versions.
|
||||
IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
|
||||
CMAKE_C_COMPILER_ID MATCHES "^Clang$")
|
||||
CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
|
||||
SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
|
||||
#################################################################
|
||||
# Set compile flags for all build types.
|
||||
|
|
@ -144,7 +160,7 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
|
|||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
|
||||
ENDIF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
|
||||
CMAKE_C_COMPILER_ID MATCHES "^Clang$")
|
||||
CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
|
||||
IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
|
||||
SET(CMAKE_C_COMPILER "xlc_r")
|
||||
SET(CMAKE_REQUIRED_FLAGS "-qflag=e:e -qformat=sec")
|
||||
|
|
@ -443,7 +459,10 @@ SET(ADDITIONAL_LIBS "")
|
|||
# Find ZLIB
|
||||
#
|
||||
IF(ENABLE_ZLIB)
|
||||
FIND_PACKAGE(ZLIB)
|
||||
# Require zlib >= 1.2.1, see: https://github.com/libarchive/libarchive/issues/615
|
||||
# zlib 1.2.0 should also work, but it is difficult to test for. Let's require
|
||||
# zlib >= 1.2.1 for consistency with the autoconf build.
|
||||
FIND_PACKAGE(ZLIB 1.2.1)
|
||||
ELSE()
|
||||
SET(ZLIB_FOUND FALSE) # Override cached value
|
||||
ENDIF()
|
||||
|
|
@ -743,7 +762,6 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
|
|||
LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
|
||||
|
|
@ -2174,6 +2192,11 @@ IF(APPLE)
|
|||
ADD_DEFINITIONS(-Wno-deprecated-declarations)
|
||||
ENDIF(APPLE)
|
||||
|
||||
OPTION(DONT_FAIL_ON_CRC_ERROR "Ignore CRC errors during parsing (For fuzzing)" OFF)
|
||||
IF(DONT_FAIL_ON_CRC_ERROR)
|
||||
ADD_DEFINITIONS(-DDONT_FAIL_ON_CRC_ERROR=1)
|
||||
ENDIF(DONT_FAIL_ON_CRC_ERROR)
|
||||
|
||||
IF(ENABLE_TEST)
|
||||
ADD_CUSTOM_TARGET(run_all_tests)
|
||||
ENDIF(ENABLE_TEST)
|
||||
|
|
|
|||
11
Makefile.am
11
Makefile.am
|
|
@ -371,6 +371,7 @@ libarchive_test_SOURCES= \
|
|||
libarchive/test/test_acl_platform_posix1e.c \
|
||||
libarchive/test/test_acl_posix1e.c \
|
||||
libarchive/test/test_acl_text.c \
|
||||
libarchive/test/test_ar_mode.c \
|
||||
libarchive/test/test_archive_api_feature.c \
|
||||
libarchive/test/test_archive_clear_error.c \
|
||||
libarchive/test/test_archive_cmdline.c \
|
||||
|
|
@ -380,6 +381,7 @@ libarchive_test_SOURCES= \
|
|||
libarchive/test/test_archive_match_path.c \
|
||||
libarchive/test/test_archive_match_time.c \
|
||||
libarchive/test/test_archive_pathmatch.c \
|
||||
libarchive/test/test_archive_read.c \
|
||||
libarchive/test/test_archive_read_add_passphrase.c \
|
||||
libarchive/test/test_archive_read_close_twice.c \
|
||||
libarchive/test/test_archive_read_close_twice_open_fd.c \
|
||||
|
|
@ -486,6 +488,7 @@ libarchive_test_SOURCES= \
|
|||
libarchive/test/test_read_format_gtar_lzma.c \
|
||||
libarchive/test/test_read_format_gtar_sparse.c \
|
||||
libarchive/test/test_read_format_gtar_sparse_skip_entry.c \
|
||||
libarchive/test/test_read_format_huge_rpm.c \
|
||||
libarchive/test/test_read_format_iso_Z.c \
|
||||
libarchive/test/test_read_format_iso_multi_extent.c \
|
||||
libarchive/test/test_read_format_iso_xorriso.c \
|
||||
|
|
@ -520,6 +523,7 @@ libarchive_test_SOURCES= \
|
|||
libarchive/test/test_read_format_tar_empty_with_gnulabel.c \
|
||||
libarchive/test/test_read_format_tar_filename.c \
|
||||
libarchive/test/test_read_format_tar_invalid_pax_size.c \
|
||||
libarchive/test/test_read_format_tar_pax_large_attr.c \
|
||||
libarchive/test/test_read_format_tbz.c \
|
||||
libarchive/test/test_read_format_tgz.c \
|
||||
libarchive/test/test_read_format_tlz.c \
|
||||
|
|
@ -643,6 +647,7 @@ libarchive_test_SOURCES= \
|
|||
libarchive/test/test_write_format_zip_file_zip64.c \
|
||||
libarchive/test/test_write_format_zip_large.c \
|
||||
libarchive/test/test_write_format_zip_stream.c \
|
||||
libarchive/test/test_write_format_zip_windows_path.c \
|
||||
libarchive/test/test_write_format_zip_zip64.c \
|
||||
libarchive/test/test_write_open_memory.c \
|
||||
libarchive/test/test_write_read_format_zip.c \
|
||||
|
|
@ -786,6 +791,7 @@ libarchive_test_EXTRA_DIST=\
|
|||
libarchive/test/test_read_format_7zip_encryption.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_encryption_header.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_encryption_partially.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_extract_second.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_lzma1.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \
|
||||
|
|
@ -827,8 +833,10 @@ libarchive_test_EXTRA_DIST=\
|
|||
libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tar.uu \
|
||||
libarchive/test/test_read_format_gtar_sparse_1_17_posix10_modified.tar.uu \
|
||||
libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu \
|
||||
libarchive/test/test_read_format_huge_rpm.rpm.uu \
|
||||
libarchive/test/test_read_format_iso.iso.Z.uu \
|
||||
libarchive/test/test_read_format_iso_2.iso.Z.uu \
|
||||
libarchive/test/test_read_format_iso_3.iso.Z.uu \
|
||||
libarchive/test/test_read_format_iso_joliet.iso.Z.uu \
|
||||
libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu \
|
||||
libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu \
|
||||
|
|
@ -919,6 +927,7 @@ libarchive_test_EXTRA_DIST=\
|
|||
libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \
|
||||
libarchive/test/test_read_format_rar5_data_ready_pointer_leak.rar.uu \
|
||||
libarchive/test/test_read_format_raw.bufr.uu \
|
||||
libarchive/test/test_read_format_raw.data.gz.uu \
|
||||
libarchive/test/test_read_format_raw.data.Z.uu \
|
||||
|
|
@ -929,11 +938,13 @@ libarchive_test_EXTRA_DIST=\
|
|||
libarchive/test/test_read_format_tar_empty_pax.tar.Z.uu \
|
||||
libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \
|
||||
libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu \
|
||||
libarchive/test/test_read_format_tar_pax_large_attr.tar.Z.uu \
|
||||
libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \
|
||||
libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
|
||||
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
|
||||
libarchive/test/test_read_format_warc.warc.uu \
|
||||
libarchive/test/test_read_format_xar_doublelink.xar.uu \
|
||||
libarchive/test/test_read_format_xar_duplicate_filename_node.xar.uu \
|
||||
libarchive/test/test_read_format_zip.zip.uu \
|
||||
libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \
|
||||
libarchive/test/test_read_format_zip_7z_deflate.zip.uu \
|
||||
|
|
|
|||
2
NEWS
2
NEWS
|
|
@ -1,3 +1,5 @@
|
|||
Sep 13, 2024: libarchive 3.7.5 released
|
||||
|
||||
Apr 26, 2024: libarchive 3.7.4 released
|
||||
|
||||
Apr 08, 2024: libarchive 3.7.3 released
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
#!/bin/sh
|
||||
if [ "$1" = "prepare" ]
|
||||
then
|
||||
set -x
|
||||
brew uninstall openssl@1.0.2t > /dev/null
|
||||
brew uninstall python@2.7.17 > /dev/null
|
||||
brew untap local/openssl > /dev/null
|
||||
brew untap local/python2 > /dev/null
|
||||
brew update > /dev/null
|
||||
brew upgrade > /dev/null
|
||||
set -x -e
|
||||
for pkg in \
|
||||
#Uncommenting these adds a full minute to the CI time
|
||||
#brew update > /dev/null
|
||||
#brew upgrade > /dev/null
|
||||
|
||||
# This does an upgrade if the package is already installed
|
||||
brew install \
|
||||
autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
|
|
@ -20,7 +18,4 @@ then
|
|||
zstd \
|
||||
libxml2 \
|
||||
openssl
|
||||
do
|
||||
brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg
|
||||
done
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1132,9 +1132,6 @@ typedef uint64_t uintmax_t;
|
|||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#cmakedefine HAVE_SYS_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#cmakedefine HAVE_SYS_QUEUE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/richacl.h> header file. */
|
||||
#cmakedefine HAVE_SYS_RICHACL_H 1
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3007004
|
||||
3007005
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ expands files to standard output.
|
|||
.Nm
|
||||
typically takes a filename as an argument or reads standard input when used in a
|
||||
pipe.
|
||||
In both cases decompressed data it written to standard output.
|
||||
In both cases decompressed data is written to standard output.
|
||||
.Sh EXAMPLES
|
||||
To decompress a file:
|
||||
.Pp
|
||||
|
|
|
|||
30
configure.ac
30
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.7.4])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3007004])
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.7.5])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3007005])
|
||||
|
||||
dnl bsdtar and bsdcpio versioning tracks libarchive
|
||||
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
|
||||
|
|
@ -113,8 +113,8 @@ AC_PROG_CC
|
|||
AM_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
LT_INIT([win32-dll])
|
||||
AC_CHECK_TOOL([STRIP],[strip])
|
||||
AC_PROG_MKDIR_P
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ AC_CHECK_HEADERS([locale.h membership.h paths.h poll.h pthread.h pwd.h])
|
|||
AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h])
|
||||
AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
|
||||
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/ea.h sys/extattr.h])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h sys/queue.h])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
|
||||
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/richacl.h])
|
||||
AC_CHECK_HEADERS([sys/select.h sys/statfs.h sys/statvfs.h sys/sysmacros.h])
|
||||
AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h sys/xattr.h])
|
||||
|
|
@ -380,8 +380,23 @@ AC_ARG_WITH([zlib],
|
|||
AS_HELP_STRING([--without-zlib], [Don't build support for gzip through zlib]))
|
||||
|
||||
if test "x$with_zlib" != "xno"; then
|
||||
AC_CHECK_HEADERS([zlib.h])
|
||||
AC_CHECK_LIB(z,inflate)
|
||||
old_LIBS="$LIBS"
|
||||
LIBS="$LIBS -lz"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <zlib.h>
|
||||
#if !defined(ZLIB_VERNUM)
|
||||
// zlib 1.2.0 should work too, but it's difficult to test for.
|
||||
// zlib 1.2.1 onwards have ZLIB_VERNUM, which is easy to check.
|
||||
#error zlib >= 1.2.1 is required.
|
||||
#endif
|
||||
// Check that there's an inflate function.
|
||||
int main(int argc, char **argv) { inflate(NULL, 0); return 0; }
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_ZLIB_H], [1], [Define to 1 if you have zlib >= 1.2.1])
|
||||
AC_MSG_RESULT([found a suitable version of zlib (>= 1.2.1)])
|
||||
],
|
||||
[AC_MSG_RESULT([could not find a suitable version of zlib (>= 1.2.1)])
|
||||
LIBS="$old_LIBS"])
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([bz2lib],
|
||||
|
|
@ -777,7 +792,6 @@ AX_COMPILE_CHECK_SIZEOF(long)
|
|||
AC_CHECK_HEADERS_ONCE([sys/time.h])
|
||||
|
||||
# Checks for library functions.
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_HEADER_MAJOR
|
||||
AC_FUNC_FSEEKO
|
||||
AC_FUNC_MEMCMP
|
||||
|
|
|
|||
|
|
@ -308,17 +308,22 @@ again:
|
|||
* Returns NULL if no error, otherwise returns error string for display.
|
||||
*
|
||||
*/
|
||||
const char *
|
||||
owner_parse(const char *spec, int *uid, int *gid)
|
||||
int
|
||||
owner_parse(const char *spec, struct cpio_owner *owner, const char **errmsg)
|
||||
{
|
||||
static char errbuff[128];
|
||||
const char *u, *ue, *g;
|
||||
|
||||
*uid = -1;
|
||||
*gid = -1;
|
||||
owner->uid = -1;
|
||||
owner->gid = -1;
|
||||
|
||||
if (spec[0] == '\0')
|
||||
return ("Invalid empty user/group spec");
|
||||
owner->uname = NULL;
|
||||
owner->gname = NULL;
|
||||
|
||||
if (spec[0] == '\0') {
|
||||
*errmsg = "Invalid empty user/group spec";
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Split spec into [user][:.][group]
|
||||
|
|
@ -347,23 +352,29 @@ owner_parse(const char *spec, int *uid, int *gid)
|
|||
|
||||
user = (char *)malloc(ue - u + 1);
|
||||
if (user == NULL)
|
||||
return ("Couldn't allocate memory");
|
||||
goto alloc_error;
|
||||
memcpy(user, u, ue - u);
|
||||
user[ue - u] = '\0';
|
||||
if ((pwent = getpwnam(user)) != NULL) {
|
||||
*uid = pwent->pw_uid;
|
||||
owner->uid = pwent->pw_uid;
|
||||
owner->uname = strdup(pwent->pw_name);
|
||||
if (owner->uname == NULL) {
|
||||
free(user);
|
||||
goto alloc_error;
|
||||
}
|
||||
if (*ue != '\0')
|
||||
*gid = pwent->pw_gid;
|
||||
owner->gid = pwent->pw_gid;
|
||||
} else {
|
||||
char *end;
|
||||
errno = 0;
|
||||
*uid = (int)strtoul(user, &end, 10);
|
||||
owner->uid = (int)strtoul(user, &end, 10);
|
||||
if (errno || *end != '\0') {
|
||||
snprintf(errbuff, sizeof(errbuff),
|
||||
"Couldn't lookup user ``%s''", user);
|
||||
errbuff[sizeof(errbuff) - 1] = '\0';
|
||||
free(user);
|
||||
return (errbuff);
|
||||
*errmsg = errbuff;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
free(user);
|
||||
|
|
@ -372,18 +383,28 @@ owner_parse(const char *spec, int *uid, int *gid)
|
|||
if (*g != '\0') {
|
||||
struct group *grp;
|
||||
if ((grp = getgrnam(g)) != NULL) {
|
||||
*gid = grp->gr_gid;
|
||||
owner->gid = grp->gr_gid;
|
||||
owner->gname = strdup(grp->gr_name);
|
||||
if (owner->gname == NULL) {
|
||||
free(owner->uname);
|
||||
owner->uname = NULL;
|
||||
goto alloc_error;
|
||||
}
|
||||
} else {
|
||||
char *end;
|
||||
errno = 0;
|
||||
*gid = (int)strtoul(g, &end, 10);
|
||||
owner->gid = (int)strtoul(g, &end, 10);
|
||||
if (errno || *end != '\0') {
|
||||
snprintf(errbuff, sizeof(errbuff),
|
||||
"Couldn't lookup group ``%s''", g);
|
||||
errbuff[sizeof(errbuff) - 1] = '\0';
|
||||
return (errbuff);
|
||||
*errmsg = errbuff;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
return (0);
|
||||
alloc_error:
|
||||
*errmsg = "Couldn't allocate memory";
|
||||
return (-1);
|
||||
}
|
||||
|
|
|
|||
46
cpio/cpio.c
46
cpio/cpio.c
|
|
@ -132,9 +132,9 @@ main(int argc, char *argv[])
|
|||
static char buff[16384];
|
||||
struct cpio _cpio; /* Allocated on stack. */
|
||||
struct cpio *cpio;
|
||||
struct cpio_owner owner;
|
||||
const char *errmsg;
|
||||
char *tptr;
|
||||
int uid, gid;
|
||||
int opt, t;
|
||||
|
||||
cpio = &_cpio;
|
||||
|
|
@ -142,6 +142,7 @@ main(int argc, char *argv[])
|
|||
cpio->buff = buff;
|
||||
cpio->buff_size = sizeof(buff);
|
||||
|
||||
|
||||
#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
|
||||
{ /* Ignore SIGPIPE signals. */
|
||||
struct sigaction sa;
|
||||
|
|
@ -161,7 +162,9 @@ main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
cpio->uid_override = -1;
|
||||
cpio->uname_override = NULL;
|
||||
cpio->gid_override = -1;
|
||||
cpio->gname_override = NULL;
|
||||
cpio->argv = argv;
|
||||
cpio->argc = argc;
|
||||
cpio->mode = '\0';
|
||||
|
|
@ -320,21 +323,21 @@ main(int argc, char *argv[])
|
|||
cpio->quiet = 1;
|
||||
break;
|
||||
case 'R': /* GNU cpio, also --owner */
|
||||
/* TODO: owner_parse should return uname/gname
|
||||
* also; use that to set [ug]name_override. */
|
||||
errmsg = owner_parse(cpio->argument, &uid, &gid);
|
||||
if (errmsg) {
|
||||
errmsg = NULL;
|
||||
if (owner_parse(cpio->argument, &owner, &errmsg) != 0) {
|
||||
if (!errmsg)
|
||||
errmsg = "Error parsing owner";
|
||||
lafe_warnc(-1, "%s", errmsg);
|
||||
usage();
|
||||
}
|
||||
if (uid != -1) {
|
||||
cpio->uid_override = uid;
|
||||
cpio->uname_override = NULL;
|
||||
}
|
||||
if (gid != -1) {
|
||||
cpio->gid_override = gid;
|
||||
cpio->gname_override = NULL;
|
||||
}
|
||||
if (owner.uid != -1)
|
||||
cpio->uid_override = owner.uid;
|
||||
if (owner.uname != NULL)
|
||||
cpio->uname_override = owner.uname;
|
||||
if (owner.gid != -1)
|
||||
cpio->gid_override = owner.gid;
|
||||
if (owner.gname != NULL)
|
||||
cpio->gname_override = owner.gname;
|
||||
break;
|
||||
case 'r': /* POSIX 1997 */
|
||||
cpio->option_rename = 1;
|
||||
|
|
@ -439,11 +442,14 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
archive_match_free(cpio->matching);
|
||||
free_cache(cpio->gname_cache);
|
||||
free_cache(cpio->uname_cache);
|
||||
free(cpio->uname_override);
|
||||
free_cache(cpio->gname_cache);
|
||||
free(cpio->gname_override);
|
||||
archive_read_close(cpio->archive_read_disk);
|
||||
archive_read_free(cpio->archive_read_disk);
|
||||
free(cpio->destdir);
|
||||
|
||||
passphrase_free(cpio->ppbuff);
|
||||
return (cpio->return_value);
|
||||
}
|
||||
|
|
@ -728,14 +734,14 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
|
|||
return (r);
|
||||
}
|
||||
|
||||
if (cpio->uid_override >= 0) {
|
||||
if (cpio->uid_override >= 0)
|
||||
archive_entry_set_uid(entry, cpio->uid_override);
|
||||
if (cpio->gname_override != NULL)
|
||||
archive_entry_set_uname(entry, cpio->uname_override);
|
||||
}
|
||||
if (cpio->gid_override >= 0) {
|
||||
if (cpio->gid_override >= 0)
|
||||
archive_entry_set_gid(entry, cpio->gid_override);
|
||||
if (cpio->gname_override != NULL)
|
||||
archive_entry_set_gname(entry, cpio->gname_override);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a destination path for this entry.
|
||||
|
|
@ -1015,8 +1021,12 @@ mode_in(struct cpio *cpio)
|
|||
fprintf(stderr, ".");
|
||||
if (cpio->uid_override >= 0)
|
||||
archive_entry_set_uid(entry, cpio->uid_override);
|
||||
if (cpio->uname_override != NULL)
|
||||
archive_entry_set_uname(entry, cpio->uname_override);
|
||||
if (cpio->gid_override >= 0)
|
||||
archive_entry_set_gid(entry, cpio->gid_override);
|
||||
if (cpio->gname_override != NULL)
|
||||
archive_entry_set_gname(entry, cpio->gname_override);
|
||||
r = archive_write_header(ext, entry);
|
||||
if (r != ARCHIVE_OK) {
|
||||
fprintf(stderr, "%s: %s\n",
|
||||
|
|
|
|||
|
|
@ -94,8 +94,14 @@ struct cpio {
|
|||
char *ppbuff;
|
||||
};
|
||||
|
||||
const char *owner_parse(const char *, int *, int *);
|
||||
struct cpio_owner {
|
||||
int uid;
|
||||
int gid;
|
||||
char *uname;
|
||||
char *gname;
|
||||
};
|
||||
|
||||
int owner_parse(const char *, struct cpio_owner *, const char **);
|
||||
|
||||
/* Fake short equivalents for long options that otherwise lack them. */
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ DEFINE_TEST(test_option_c)
|
|||
assert(is_octal(e, 76)); /* Entire header is octal digits. */
|
||||
assertEqualMem(e + 0, "070707", 6); /* Magic */
|
||||
assert(is_octal(e + 6, 6)); /* dev */
|
||||
dev = from_octal(e + 6, 6);
|
||||
dev = (int)from_octal(e + 6, 6);
|
||||
assert(is_octal(e + 12, 6)); /* ino */
|
||||
ino = from_octal(e + 12, 6);
|
||||
ino = (int)from_octal(e + 12, 6);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Group members bits and others bits do not work. */
|
||||
assertEqualMem(e + 18, "100666", 6); /* Mode */
|
||||
|
|
@ -129,10 +129,10 @@ DEFINE_TEST(test_option_c)
|
|||
assertEqualMem(e + 18, "100644", 6); /* Mode */
|
||||
#endif
|
||||
if (uid < 0)
|
||||
uid = from_octal(e + 24, 6);
|
||||
uid = (int)from_octal(e + 24, 6);
|
||||
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
|
||||
assert(is_octal(e + 30, 6)); /* gid */
|
||||
gid = from_octal(e + 30, 6);
|
||||
gid = (int)from_octal(e + 30, 6);
|
||||
assertEqualMem(e + 36, "000001", 6); /* nlink */
|
||||
failure("file entries should not have rdev set (dev field was 0%o)",
|
||||
dev);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ DEFINE_TEST(test_option_t)
|
|||
char *p;
|
||||
int r;
|
||||
time_t mtime;
|
||||
char date[32];
|
||||
char date[48];
|
||||
char date2[32];
|
||||
struct tm *tmptr;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
|
||||
|
|
@ -89,6 +89,7 @@ DEFINE_TEST(test_option_t)
|
|||
mtime = 1;
|
||||
#ifdef HAVE_LOCALE_H
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_TIME, "");
|
||||
#endif
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
tmptr = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
|
||||
|
|
@ -99,10 +100,10 @@ DEFINE_TEST(test_option_t)
|
|||
#endif
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
strftime(date2, sizeof(date2)-1, "%b %d %Y", tmptr);
|
||||
_snprintf(date, sizeof(date)-1, "%12.12s file", date2);
|
||||
_snprintf(date, sizeof(date)-1, "%12s file", date2);
|
||||
#else
|
||||
strftime(date2, sizeof(date2)-1, "%b %e %Y", tmptr);
|
||||
snprintf(date, sizeof(date)-1, "%12.12s file", date2);
|
||||
snprintf(date, sizeof(date)-1, "%12s file", date2);
|
||||
#endif
|
||||
assertEqualMem(p + 42, date, strlen(date));
|
||||
free(p);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,14 @@ int_in_list(int i, const int *l, size_t n)
|
|||
failure("%d", i);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
free_cpio_owner(struct cpio_owner *owner) {
|
||||
owner->uid = -1;
|
||||
owner->gid = -1;
|
||||
free(owner->uname);
|
||||
free(owner->gname);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFINE_TEST(test_owner_parse)
|
||||
|
|
@ -62,49 +70,58 @@ DEFINE_TEST(test_owner_parse)
|
|||
#if !defined(ROOT)
|
||||
skipping("No uid/gid configuration for this OS");
|
||||
#else
|
||||
int uid, gid;
|
||||
struct cpio_owner owner;
|
||||
const char *errstr;
|
||||
|
||||
assert(NULL == owner_parse(ROOT, &uid, &gid));
|
||||
assert(int_in_list(uid, root_uids,
|
||||
assert(0 == owner_parse(ROOT, &owner, &errstr));
|
||||
assert(int_in_list(owner.uid, root_uids,
|
||||
sizeof(root_uids)/sizeof(root_uids[0])));
|
||||
assertEqualInt(-1, gid);
|
||||
assertEqualInt(-1, owner.gid);
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
|
||||
assert(NULL == owner_parse(ROOT ":", &uid, &gid));
|
||||
assert(int_in_list(uid, root_uids,
|
||||
assert(0 == owner_parse(ROOT ":", &owner, &errstr));
|
||||
assert(int_in_list(owner.uid, root_uids,
|
||||
sizeof(root_uids)/sizeof(root_uids[0])));
|
||||
assert(int_in_list(gid, root_gids,
|
||||
assert(int_in_list(owner.gid, root_gids,
|
||||
sizeof(root_gids)/sizeof(root_gids[0])));
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
assert(NULL == owner_parse(ROOT ".", &uid, &gid));
|
||||
assert(int_in_list(uid, root_uids,
|
||||
assert(0 == owner_parse(ROOT ".", &owner, &errstr));
|
||||
assert(int_in_list(owner.uid, root_uids,
|
||||
sizeof(root_uids)/sizeof(root_uids[0])));
|
||||
assert(int_in_list(gid, root_gids,
|
||||
assert(int_in_list(owner.gid, root_gids,
|
||||
sizeof(root_gids)/sizeof(root_gids[0])));
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
assert(NULL == owner_parse("111", &uid, &gid));
|
||||
assertEqualInt(111, uid);
|
||||
assertEqualInt(-1, gid);
|
||||
assert(0 == owner_parse("111", &owner, &errstr));
|
||||
assertEqualInt(111, owner.uid);
|
||||
assertEqualInt(-1, owner.gid);
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
assert(NULL == owner_parse("112:", &uid, &gid));
|
||||
assertEqualInt(112, uid);
|
||||
assert(0 == owner_parse("112:", &owner, &errstr));
|
||||
assertEqualInt(112, owner.uid);
|
||||
/* Can't assert gid, since we don't know gid for user #112. */
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
assert(NULL == owner_parse("113.", &uid, &gid));
|
||||
assertEqualInt(113, uid);
|
||||
assert(0 == owner_parse("113.", &owner, &errstr));
|
||||
assertEqualInt(113, owner.uid);
|
||||
/* Can't assert gid, since we don't know gid for user #113. */
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
assert(NULL == owner_parse(":114", &uid, &gid));
|
||||
assertEqualInt(-1, uid);
|
||||
assertEqualInt(114, gid);
|
||||
assert(0 == owner_parse(":114", &owner, &errstr));
|
||||
assertEqualInt(-1, owner.uid);
|
||||
assertEqualInt(114, owner.gid);
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
assert(NULL == owner_parse(".115", &uid, &gid));
|
||||
assertEqualInt(-1, uid);
|
||||
assertEqualInt(115, gid);
|
||||
assert(0 == owner_parse(".115", &owner, &errstr));
|
||||
assertEqualInt(-1, owner.uid);
|
||||
assertEqualInt(115, owner.gid);
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
assert(NULL == owner_parse("116:117", &uid, &gid));
|
||||
assertEqualInt(116, uid);
|
||||
assertEqualInt(117, gid);
|
||||
assert(0 == owner_parse("116:117", &owner, &errstr));
|
||||
assertEqualInt(116, owner.uid);
|
||||
assertEqualInt(117, owner.gid);
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
/*
|
||||
* TODO: Lookup current user/group name, build strings and
|
||||
|
|
@ -112,9 +129,20 @@ DEFINE_TEST(test_owner_parse)
|
|||
* users.
|
||||
*/
|
||||
|
||||
assert(NULL != owner_parse(":nonexistentgroup", &uid, &gid));
|
||||
assert(NULL != owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
|
||||
assert(NULL !=
|
||||
owner_parse("nonexistentuser:nonexistentgroup", &uid, &gid));
|
||||
errstr = NULL;
|
||||
assert(0 != owner_parse(":nonexistentgroup", &owner, &errstr));
|
||||
assertEqualString(errstr, "Couldn't lookup group ``nonexistentgroup''");
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
errstr = NULL;
|
||||
assert(0 != owner_parse(ROOT ":nonexistentgroup", &owner, &errstr));
|
||||
assertEqualString(errstr, "Couldn't lookup group ``nonexistentgroup''");
|
||||
free_cpio_owner(&owner);
|
||||
|
||||
errstr = NULL;
|
||||
assert(0 != owner_parse("nonexistentuser:nonexistentgroup", &owner,
|
||||
&errstr));
|
||||
assertEqualString(errstr, "Couldn't lookup user ``nonexistentuser''");
|
||||
free_cpio_owner(&owner);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,7 +247,11 @@ IF(BUILD_SHARED_LIBS)
|
|||
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
|
||||
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
|
||||
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
|
||||
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
|
||||
SET_TARGET_PROPERTIES(archive PROPERTIES
|
||||
VERSION ${SOVERSION_FULL}
|
||||
SOVERSION ${SOVERSION}
|
||||
MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
|
||||
MACHO_CURRENT_VERSION ${MACHO_CURRENT_VERSION})
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
|
||||
# archive_static is a static library
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3007004
|
||||
#define ARCHIVE_VERSION_NUMBER 3007005
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
|
|
@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
|
|||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.7.4"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.7.5"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static int is_nfs4_flags(const char *start, const char *end,
|
|||
int *result);
|
||||
static int is_nfs4_perms(const char *start, const char *end,
|
||||
int *result);
|
||||
static void next_field(const char **p, const char **start,
|
||||
static void next_field(const char **p, size_t *l, const char **start,
|
||||
const char **end, char *sep);
|
||||
static void append_entry(char **p, const char *prefix, int type,
|
||||
int tag, int flags, const char *name, int perm, int id);
|
||||
|
|
@ -1619,6 +1619,13 @@ next_field_w(const wchar_t **wp, const wchar_t **start,
|
|||
int
|
||||
archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
int want_type, struct archive_string_conv *sc)
|
||||
{
|
||||
return archive_acl_from_text_nl(acl, text, strlen(text), want_type, sc);
|
||||
}
|
||||
|
||||
int
|
||||
archive_acl_from_text_nl(struct archive_acl *acl, const char *text,
|
||||
size_t length, int want_type, struct archive_string_conv *sc)
|
||||
{
|
||||
struct {
|
||||
const char *start;
|
||||
|
|
@ -1649,7 +1656,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
|||
ret = ARCHIVE_OK;
|
||||
types = 0;
|
||||
|
||||
while (text != NULL && *text != '\0') {
|
||||
while (text != NULL && length > 0 && *text != '\0') {
|
||||
/*
|
||||
* Parse the fields out of the next entry,
|
||||
* advance 'text' to start of next entry.
|
||||
|
|
@ -1657,7 +1664,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
|||
fields = 0;
|
||||
do {
|
||||
const char *start, *end;
|
||||
next_field(&text, &start, &end, &sep);
|
||||
next_field(&text, &length, &start, &end, &sep);
|
||||
if (fields < numfields) {
|
||||
field[fields].start = start;
|
||||
field[fields].end = end;
|
||||
|
|
@ -2047,7 +2054,7 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
|
|||
}
|
||||
|
||||
/*
|
||||
* Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
|
||||
* Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *p is updated
|
||||
* to point to just after the separator. *start points to the first
|
||||
* character of the matched text and *end just after the last
|
||||
* character of the matched identifier. In particular *end - *start
|
||||
|
|
@ -2055,42 +2062,42 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
|
|||
* whitespace.
|
||||
*/
|
||||
static void
|
||||
next_field(const char **p, const char **start,
|
||||
next_field(const char **p, size_t *l, const char **start,
|
||||
const char **end, char *sep)
|
||||
{
|
||||
/* Skip leading whitespace to find start of field. */
|
||||
while (**p == ' ' || **p == '\t' || **p == '\n') {
|
||||
while (*l > 0 && (**p == ' ' || **p == '\t' || **p == '\n')) {
|
||||
(*p)++;
|
||||
(*l)--;
|
||||
}
|
||||
*start = *p;
|
||||
|
||||
/* Scan for the separator. */
|
||||
while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
|
||||
**p != '#') {
|
||||
/* Locate end of field, trim trailing whitespace if necessary */
|
||||
while (*l > 0 && **p != ' ' && **p != '\t' && **p != '\n' && **p != ',' && **p != ':' && **p != '#') {
|
||||
(*p)++;
|
||||
(*l)--;
|
||||
}
|
||||
*end = *p;
|
||||
|
||||
/* Scan for the separator. */
|
||||
while (*l > 0 && **p != ',' && **p != ':' && **p != '\n' && **p != '#') {
|
||||
(*p)++;
|
||||
(*l)--;
|
||||
}
|
||||
*sep = **p;
|
||||
|
||||
/* Locate end of field, trim trailing whitespace if necessary */
|
||||
if (*p == *start) {
|
||||
*end = *p;
|
||||
} else {
|
||||
*end = *p - 1;
|
||||
while (**end == ' ' || **end == '\t' || **end == '\n') {
|
||||
(*end)--;
|
||||
}
|
||||
(*end)++;
|
||||
}
|
||||
|
||||
/* Handle in-field comments */
|
||||
if (*sep == '#') {
|
||||
while (**p != '\0' && **p != ',' && **p != '\n') {
|
||||
while (*l > 0 && **p != ',' && **p != '\n') {
|
||||
(*p)++;
|
||||
(*l)--;
|
||||
}
|
||||
*sep = **p;
|
||||
}
|
||||
|
||||
/* Adjust scanner location. */
|
||||
if (**p != '\0')
|
||||
/* Skip separator. */
|
||||
if (*l > 0) {
|
||||
(*p)++;
|
||||
(*l)--;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,5 +77,7 @@ int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */,
|
|||
int /* type */);
|
||||
int archive_acl_from_text_l(struct archive_acl *, const char * /* text */,
|
||||
int /* type */, struct archive_string_conv *);
|
||||
int archive_acl_from_text_nl(struct archive_acl *, const char * /* text */,
|
||||
size_t /* size of text */, int /* type */, struct archive_string_conv *);
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
* When zlib is unavailable, we should still be able to validate
|
||||
* uncompressed zip archives. That requires us to be able to compute
|
||||
|
|
@ -46,6 +48,9 @@ crc32(unsigned long crc, const void *_p, size_t len)
|
|||
static volatile int crc_tbl_inited = 0;
|
||||
static unsigned long crc_tbl[256];
|
||||
|
||||
if (_p == NULL)
|
||||
return (0);
|
||||
|
||||
if (!crc_tbl_inited) {
|
||||
for (b = 0; b < 256; ++b) {
|
||||
crc2 = b;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@
|
|||
static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
|
||||
static const wchar_t *ae_wcstofflags(const wchar_t *stringp,
|
||||
unsigned long *setp, unsigned long *clrp);
|
||||
static const char *ae_strtofflags(const char *stringp,
|
||||
static const char *ae_strtofflags(const char *stringp, size_t length,
|
||||
unsigned long *setp, unsigned long *clrp);
|
||||
|
||||
#ifndef HAVE_WCSCPY
|
||||
|
|
@ -157,10 +157,9 @@ archive_entry_clear(struct archive_entry *entry)
|
|||
return (NULL);
|
||||
archive_mstring_clean(&entry->ae_fflags_text);
|
||||
archive_mstring_clean(&entry->ae_gname);
|
||||
archive_mstring_clean(&entry->ae_hardlink);
|
||||
archive_mstring_clean(&entry->ae_linkname);
|
||||
archive_mstring_clean(&entry->ae_pathname);
|
||||
archive_mstring_clean(&entry->ae_sourcepath);
|
||||
archive_mstring_clean(&entry->ae_symlink);
|
||||
archive_mstring_clean(&entry->ae_uname);
|
||||
archive_entry_copy_mac_metadata(entry, NULL, 0);
|
||||
archive_acl_clear(&entry->acl);
|
||||
|
|
@ -195,10 +194,9 @@ archive_entry_clone(struct archive_entry *entry)
|
|||
* character sets are different? XXX */
|
||||
archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
|
||||
archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
|
||||
archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
|
||||
archive_mstring_copy(&entry2->ae_linkname, &entry->ae_linkname);
|
||||
archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
|
||||
archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
|
||||
archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
|
||||
entry2->ae_set = entry->ae_set;
|
||||
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
||||
|
||||
|
|
@ -477,6 +475,15 @@ _archive_entry_gname_l(struct archive_entry *entry,
|
|||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_link_to_hardlink(struct archive_entry *entry)
|
||||
{
|
||||
if ((entry->ae_set & AE_SET_SYMLINK) != 0) {
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
}
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_entry_hardlink(struct archive_entry *entry)
|
||||
{
|
||||
|
|
@ -484,7 +491,7 @@ archive_entry_hardlink(struct archive_entry *entry)
|
|||
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
|
||||
return (NULL);
|
||||
if (archive_mstring_get_mbs(
|
||||
entry->archive, &entry->ae_hardlink, &p) == 0)
|
||||
entry->archive, &entry->ae_linkname, &p) == 0)
|
||||
return (p);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
|
|
@ -498,7 +505,7 @@ archive_entry_hardlink_utf8(struct archive_entry *entry)
|
|||
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
|
||||
return (NULL);
|
||||
if (archive_mstring_get_utf8(
|
||||
entry->archive, &entry->ae_hardlink, &p) == 0)
|
||||
entry->archive, &entry->ae_linkname, &p) == 0)
|
||||
return (p);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
|
|
@ -512,13 +519,19 @@ archive_entry_hardlink_w(struct archive_entry *entry)
|
|||
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
|
||||
return (NULL);
|
||||
if (archive_mstring_get_wcs(
|
||||
entry->archive, &entry->ae_hardlink, &p) == 0)
|
||||
entry->archive, &entry->ae_linkname, &p) == 0)
|
||||
return (p);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_hardlink_is_set(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_set & AE_SET_HARDLINK) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
_archive_entry_hardlink_l(struct archive_entry *entry,
|
||||
const char **p, size_t *len, struct archive_string_conv *sc)
|
||||
|
|
@ -528,7 +541,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
|
|||
*len = 0;
|
||||
return (0);
|
||||
}
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
|
||||
}
|
||||
|
||||
la_int64_t
|
||||
|
|
@ -648,32 +661,50 @@ archive_entry_perm_is_set(struct archive_entry *entry)
|
|||
return (entry->ae_set & AE_SET_PERM);
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_rdev_is_set(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_set & AE_SET_RDEV);
|
||||
}
|
||||
|
||||
dev_t
|
||||
archive_entry_rdev(struct archive_entry *entry)
|
||||
{
|
||||
if (entry->ae_stat.aest_rdev_is_broken_down)
|
||||
return ae_makedev(entry->ae_stat.aest_rdevmajor,
|
||||
entry->ae_stat.aest_rdevminor);
|
||||
else
|
||||
return (entry->ae_stat.aest_rdev);
|
||||
if (archive_entry_rdev_is_set(entry)) {
|
||||
if (entry->ae_stat.aest_rdev_is_broken_down)
|
||||
return ae_makedev(entry->ae_stat.aest_rdevmajor,
|
||||
entry->ae_stat.aest_rdevminor);
|
||||
else
|
||||
return (entry->ae_stat.aest_rdev);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dev_t
|
||||
archive_entry_rdevmajor(struct archive_entry *entry)
|
||||
{
|
||||
if (entry->ae_stat.aest_rdev_is_broken_down)
|
||||
return (entry->ae_stat.aest_rdevmajor);
|
||||
else
|
||||
return major(entry->ae_stat.aest_rdev);
|
||||
if (archive_entry_rdev_is_set(entry)) {
|
||||
if (entry->ae_stat.aest_rdev_is_broken_down)
|
||||
return (entry->ae_stat.aest_rdevmajor);
|
||||
else
|
||||
return major(entry->ae_stat.aest_rdev);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dev_t
|
||||
archive_entry_rdevminor(struct archive_entry *entry)
|
||||
{
|
||||
if (entry->ae_stat.aest_rdev_is_broken_down)
|
||||
return (entry->ae_stat.aest_rdevminor);
|
||||
else
|
||||
return minor(entry->ae_stat.aest_rdev);
|
||||
if (archive_entry_rdev_is_set(entry)) {
|
||||
if (entry->ae_stat.aest_rdev_is_broken_down)
|
||||
return (entry->ae_stat.aest_rdevminor);
|
||||
else
|
||||
return minor(entry->ae_stat.aest_rdev);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
la_int64_t
|
||||
|
|
@ -717,13 +748,22 @@ archive_entry_symlink(struct archive_entry *entry)
|
|||
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
|
||||
return (NULL);
|
||||
if (archive_mstring_get_mbs(
|
||||
entry->archive, &entry->ae_symlink, &p) == 0)
|
||||
entry->archive, &entry->ae_linkname, &p) == 0)
|
||||
return (p);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_link_to_symlink(struct archive_entry *entry)
|
||||
{
|
||||
if ((entry->ae_set & AE_SET_HARDLINK) != 0) {
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
}
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_symlink_type(struct archive_entry *entry)
|
||||
{
|
||||
|
|
@ -737,7 +777,7 @@ archive_entry_symlink_utf8(struct archive_entry *entry)
|
|||
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
|
||||
return (NULL);
|
||||
if (archive_mstring_get_utf8(
|
||||
entry->archive, &entry->ae_symlink, &p) == 0)
|
||||
entry->archive, &entry->ae_linkname, &p) == 0)
|
||||
return (p);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
|
|
@ -751,7 +791,7 @@ archive_entry_symlink_w(struct archive_entry *entry)
|
|||
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
|
||||
return (NULL);
|
||||
if (archive_mstring_get_wcs(
|
||||
entry->archive, &entry->ae_symlink, &p) == 0)
|
||||
entry->archive, &entry->ae_linkname, &p) == 0)
|
||||
return (p);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
|
|
@ -767,7 +807,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
|
|||
*len = 0;
|
||||
return (0);
|
||||
}
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
|
||||
}
|
||||
|
||||
la_int64_t
|
||||
|
|
@ -864,10 +904,17 @@ archive_entry_set_fflags(struct archive_entry *entry,
|
|||
|
||||
const char *
|
||||
archive_entry_copy_fflags_text(struct archive_entry *entry,
|
||||
const char *flags)
|
||||
const char *flags)
|
||||
{
|
||||
archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
|
||||
return (ae_strtofflags(flags,
|
||||
return archive_entry_copy_fflags_text_len(entry, flags, strlen(flags));
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_entry_copy_fflags_text_len(struct archive_entry *entry,
|
||||
const char *flags, size_t flags_length)
|
||||
{
|
||||
archive_mstring_copy_mbs_len(&entry->ae_fflags_text, flags, flags_length);
|
||||
return (ae_strtofflags(flags, flags_length,
|
||||
&entry->ae_fflags_set, &entry->ae_fflags_clear));
|
||||
}
|
||||
|
||||
|
|
@ -883,6 +930,9 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
|
|||
void
|
||||
archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
|
||||
{
|
||||
if (g < 0) {
|
||||
g = 0;
|
||||
}
|
||||
entry->stat_valid = 0;
|
||||
entry->ae_stat.aest_gid = g;
|
||||
entry->ae_set |= AE_SET_GID;
|
||||
|
|
@ -933,6 +983,9 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
|
|||
void
|
||||
archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
|
||||
{
|
||||
if (ino < 0) {
|
||||
ino = 0;
|
||||
}
|
||||
entry->stat_valid = 0;
|
||||
entry->ae_set |= AE_SET_INO;
|
||||
entry->ae_stat.aest_ino = ino;
|
||||
|
|
@ -941,6 +994,9 @@ archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
|
|||
void
|
||||
archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
|
||||
{
|
||||
if (ino < 0) {
|
||||
ino = 0;
|
||||
}
|
||||
entry->stat_valid = 0;
|
||||
entry->ae_set |= AE_SET_INO;
|
||||
entry->ae_stat.aest_ino = ino;
|
||||
|
|
@ -949,17 +1005,24 @@ archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
|
|||
void
|
||||
archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
||||
if (target != NULL)
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
else
|
||||
if (target == NULL) {
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
if (entry->ae_set & AE_SET_SYMLINK) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
archive_mstring_copy_utf8(&entry->ae_hardlink, target);
|
||||
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
||||
return;
|
||||
archive_mstring_copy_utf8(&entry->ae_linkname, target);
|
||||
if (target != NULL)
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
else
|
||||
|
|
@ -969,7 +1032,9 @@ archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
|
|||
void
|
||||
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
||||
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
||||
return;
|
||||
archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
||||
if (target != NULL)
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
else
|
||||
|
|
@ -979,7 +1044,9 @@ archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
|
|||
void
|
||||
archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
|
||||
{
|
||||
archive_mstring_copy_wcs(&entry->ae_hardlink, target);
|
||||
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
||||
return;
|
||||
archive_mstring_copy_wcs(&entry->ae_linkname, target);
|
||||
if (target != NULL)
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
else
|
||||
|
|
@ -989,12 +1056,14 @@ archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target
|
|||
int
|
||||
archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
||||
return (0);
|
||||
if (target != NULL)
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
else
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
if (archive_mstring_update_utf8(entry->archive,
|
||||
&entry->ae_hardlink, target) == 0)
|
||||
&entry->ae_linkname, target) == 0)
|
||||
return (1);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
|
|
@ -1007,7 +1076,9 @@ _archive_entry_copy_hardlink_l(struct archive_entry *entry,
|
|||
{
|
||||
int r;
|
||||
|
||||
r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
|
||||
if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
||||
return (0);
|
||||
r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
|
||||
target, len, sc);
|
||||
if (target != NULL && r == 0)
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
|
|
@ -1098,51 +1169,50 @@ archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
|
|||
void
|
||||
archive_entry_set_link(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
if (entry->ae_set & AE_SET_SYMLINK)
|
||||
archive_mstring_copy_mbs(&entry->ae_symlink, target);
|
||||
else
|
||||
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
||||
archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
||||
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
if (entry->ae_set & AE_SET_SYMLINK)
|
||||
archive_mstring_copy_utf8(&entry->ae_symlink, target);
|
||||
else
|
||||
archive_mstring_copy_utf8(&entry->ae_hardlink, target);
|
||||
archive_mstring_copy_utf8(&entry->ae_linkname, target);
|
||||
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set symlink if symlink is already set, else set hardlink. */
|
||||
void
|
||||
archive_entry_copy_link(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
if (entry->ae_set & AE_SET_SYMLINK)
|
||||
archive_mstring_copy_mbs(&entry->ae_symlink, target);
|
||||
else
|
||||
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
||||
archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
||||
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set symlink if symlink is already set, else set hardlink. */
|
||||
void
|
||||
archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
|
||||
{
|
||||
if (entry->ae_set & AE_SET_SYMLINK)
|
||||
archive_mstring_copy_wcs(&entry->ae_symlink, target);
|
||||
else
|
||||
archive_mstring_copy_wcs(&entry->ae_hardlink, target);
|
||||
archive_mstring_copy_wcs(&entry->ae_linkname, target);
|
||||
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
int r;
|
||||
if (entry->ae_set & AE_SET_SYMLINK)
|
||||
r = archive_mstring_update_utf8(entry->archive,
|
||||
&entry->ae_symlink, target);
|
||||
else
|
||||
r = archive_mstring_update_utf8(entry->archive,
|
||||
&entry->ae_hardlink, target);
|
||||
r = archive_mstring_update_utf8(entry->archive,
|
||||
&entry->ae_linkname, target);
|
||||
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
if (r == 0)
|
||||
return (1);
|
||||
if (errno == ENOMEM)
|
||||
|
|
@ -1156,12 +1226,11 @@ _archive_entry_copy_link_l(struct archive_entry *entry,
|
|||
{
|
||||
int r;
|
||||
|
||||
if (entry->ae_set & AE_SET_SYMLINK)
|
||||
r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
|
||||
target, len, sc);
|
||||
else
|
||||
r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
|
||||
r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
|
||||
target, len, sc);
|
||||
if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
||||
entry->ae_set |= AE_SET_HARDLINK;
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
|
@ -1255,6 +1324,9 @@ archive_entry_set_rdev(struct archive_entry *entry, dev_t m)
|
|||
entry->stat_valid = 0;
|
||||
entry->ae_stat.aest_rdev = m;
|
||||
entry->ae_stat.aest_rdev_is_broken_down = 0;
|
||||
entry->ae_stat.aest_rdevmajor = 0;
|
||||
entry->ae_stat.aest_rdevminor = 0;
|
||||
entry->ae_set |= AE_SET_RDEV;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1262,7 +1334,9 @@ archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
|
|||
{
|
||||
entry->stat_valid = 0;
|
||||
entry->ae_stat.aest_rdev_is_broken_down = 1;
|
||||
entry->ae_stat.aest_rdev = 0;
|
||||
entry->ae_stat.aest_rdevmajor = m;
|
||||
entry->ae_set |= AE_SET_RDEV;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1270,12 +1344,17 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
|
|||
{
|
||||
entry->stat_valid = 0;
|
||||
entry->ae_stat.aest_rdev_is_broken_down = 1;
|
||||
entry->ae_stat.aest_rdev = 0;
|
||||
entry->ae_stat.aest_rdevminor = m;
|
||||
entry->ae_set |= AE_SET_RDEV;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
|
||||
{
|
||||
if (s < 0) {
|
||||
s = 0;
|
||||
}
|
||||
entry->stat_valid = 0;
|
||||
entry->ae_stat.aest_size = s;
|
||||
entry->ae_set |= AE_SET_SIZE;
|
||||
|
|
@ -1303,11 +1382,14 @@ archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path
|
|||
void
|
||||
archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
|
||||
{
|
||||
archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
|
||||
if (linkname != NULL)
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
else
|
||||
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
||||
return;
|
||||
archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
if (linkname == NULL)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
else
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1319,42 +1401,54 @@ archive_entry_set_symlink_type(struct archive_entry *entry, int type)
|
|||
void
|
||||
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
|
||||
{
|
||||
archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
|
||||
if (linkname != NULL)
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
else
|
||||
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
||||
return;
|
||||
archive_mstring_copy_utf8(&entry->ae_linkname, linkname);
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
if (linkname == NULL)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
else
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
|
||||
{
|
||||
archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
|
||||
if (linkname != NULL)
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
else
|
||||
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
||||
return;
|
||||
archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
if (linkname == NULL)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
else
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
|
||||
{
|
||||
archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
|
||||
if (linkname != NULL)
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
else
|
||||
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
||||
return;
|
||||
archive_mstring_copy_wcs(&entry->ae_linkname, linkname);
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
if (linkname == NULL)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
else
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname)
|
||||
{
|
||||
if (linkname != NULL)
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
else
|
||||
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
||||
return (0);
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
if (linkname == NULL)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
else
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
if (archive_mstring_update_utf8(entry->archive,
|
||||
&entry->ae_symlink, linkname) == 0)
|
||||
&entry->ae_linkname, linkname) == 0)
|
||||
return (1);
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
|
|
@ -1367,18 +1461,24 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
|
|||
{
|
||||
int r;
|
||||
|
||||
r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
|
||||
if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
||||
return (0);
|
||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||
r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
|
||||
linkname, len, sc);
|
||||
if (linkname != NULL && r == 0)
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
else
|
||||
if (linkname == NULL || r != 0)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
else
|
||||
entry->ae_set |= AE_SET_SYMLINK;
|
||||
return (r);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
|
||||
{
|
||||
if (u < 0) {
|
||||
u = 0;
|
||||
}
|
||||
entry->stat_valid = 0;
|
||||
entry->ae_stat.aest_uid = u;
|
||||
entry->ae_set |= AE_SET_UID;
|
||||
|
|
@ -2031,7 +2131,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
|
|||
* provided string.
|
||||
*/
|
||||
static const char *
|
||||
ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
||||
ae_strtofflags(const char *s, size_t l, unsigned long *setp, unsigned long *clrp)
|
||||
{
|
||||
const char *start, *end;
|
||||
const struct flag *flag;
|
||||
|
|
@ -2042,15 +2142,19 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
|||
start = s;
|
||||
failed = NULL;
|
||||
/* Find start of first token. */
|
||||
while (*start == '\t' || *start == ' ' || *start == ',')
|
||||
while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
|
||||
start++;
|
||||
while (*start != '\0') {
|
||||
l--;
|
||||
}
|
||||
while (l > 0) {
|
||||
size_t length;
|
||||
/* Locate end of token. */
|
||||
end = start;
|
||||
while (*end != '\0' && *end != '\t' &&
|
||||
*end != ' ' && *end != ',')
|
||||
while (l > 0 && *end != '\t' &&
|
||||
*end != ' ' && *end != ',') {
|
||||
end++;
|
||||
l--;
|
||||
}
|
||||
length = end - start;
|
||||
for (flag = fileflags; flag->name != NULL; flag++) {
|
||||
size_t flag_length = strlen(flag->name);
|
||||
|
|
@ -2074,8 +2178,10 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
|||
|
||||
/* Find start of next token. */
|
||||
start = end;
|
||||
while (*start == '\t' || *start == ' ' || *start == ',')
|
||||
while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
|
||||
start++;
|
||||
l--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3007004
|
||||
#define ARCHIVE_VERSION_NUMBER 3007005
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
|
@ -259,9 +259,11 @@ __LA_DECL int archive_entry_gid_is_set(struct archive_entry *);
|
|||
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_set_link_to_hardlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_hardlink_is_set(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
|
||||
|
|
@ -275,6 +277,7 @@ __LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
|
|||
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
|
||||
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_perm_is_set(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_rdev_is_set(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
|
||||
|
|
@ -283,6 +286,7 @@ __LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
|
|||
__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_set_link_to_symlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
|
||||
|
|
@ -324,6 +328,8 @@ __LA_DECL void archive_entry_set_fflags(struct archive_entry *,
|
|||
/* Note that all recognized tokens are processed, regardless. */
|
||||
__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
|
||||
const char *);
|
||||
__LA_DECL const char *archive_entry_copy_fflags_text_len(struct archive_entry *,
|
||||
const char *, size_t);
|
||||
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
|
||||
const wchar_t *);
|
||||
__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);
|
||||
|
|
|
|||
|
|
@ -201,16 +201,26 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
|
|||
le = find_entry(res, *e);
|
||||
if (le != NULL) {
|
||||
archive_entry_unset_size(*e);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
archive_entry_copy_hardlink_w(*e,
|
||||
archive_entry_pathname_w(le->canonical));
|
||||
#else
|
||||
archive_entry_copy_hardlink(*e,
|
||||
archive_entry_pathname(le->canonical));
|
||||
#endif
|
||||
} else
|
||||
insert_entry(res, *e);
|
||||
return;
|
||||
case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
|
||||
le = find_entry(res, *e);
|
||||
if (le != NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
archive_entry_copy_hardlink_w(*e,
|
||||
archive_entry_pathname_w(le->canonical));
|
||||
#else
|
||||
archive_entry_copy_hardlink(*e,
|
||||
archive_entry_pathname(le->canonical));
|
||||
#endif
|
||||
} else
|
||||
insert_entry(res, *e);
|
||||
return;
|
||||
|
|
@ -229,8 +239,13 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
|
|||
le->entry = t;
|
||||
/* Make the old entry into a hardlink. */
|
||||
archive_entry_unset_size(*e);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
archive_entry_copy_hardlink_w(*e,
|
||||
archive_entry_pathname_w(le->canonical));
|
||||
#else
|
||||
archive_entry_copy_hardlink(*e,
|
||||
archive_entry_pathname(le->canonical));
|
||||
#endif
|
||||
/* If we ran out of links, return the
|
||||
* final entry as well. */
|
||||
if (le->links == 0) {
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ character strings at the same time.
|
|||
.Fn archive_entry_set_XXX
|
||||
is an alias for
|
||||
.Fn archive_entry_copy_XXX .
|
||||
The strings are copied, and don't need to outlive the call.
|
||||
.Ss File Flags
|
||||
File flags are transparently converted between a bitmap
|
||||
representation and a textual format.
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ struct archive_entry {
|
|||
#define AE_SET_FILETYPE 1024
|
||||
#define AE_SET_UID 2048
|
||||
#define AE_SET_GID 4096
|
||||
#define AE_SET_RDEV 8192
|
||||
|
||||
/*
|
||||
* Use aes here so that we get transparent mbs<->wcs conversions.
|
||||
|
|
@ -157,9 +158,8 @@ struct archive_entry {
|
|||
unsigned long ae_fflags_set; /* Bitmap fflags */
|
||||
unsigned long ae_fflags_clear;
|
||||
struct archive_mstring ae_gname; /* Name of owning group */
|
||||
struct archive_mstring ae_hardlink; /* Name of target for hardlink */
|
||||
struct archive_mstring ae_linkname; /* Name of target for hardlink or symlink */
|
||||
struct archive_mstring ae_pathname; /* Name of entry */
|
||||
struct archive_mstring ae_symlink; /* symlink contents */
|
||||
struct archive_mstring ae_uname; /* Name of owner */
|
||||
|
||||
/* Not used within libarchive; useful for some clients. */
|
||||
|
|
|
|||
|
|
@ -671,7 +671,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
|
|||
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0)));
|
||||
}
|
||||
|
||||
do
|
||||
while (numPs != 0)
|
||||
{
|
||||
/* Create Child */
|
||||
CTX_PTR c1; /* = AllocContext(p); */
|
||||
|
|
@ -692,8 +692,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
|
|||
SetSuccessor(ps[--numPs], REF(c1));
|
||||
c = c1;
|
||||
}
|
||||
while (numPs != 0);
|
||||
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@
|
|||
#define ARCHIVE_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_ICONV_H
|
||||
#include <iconv.h>
|
||||
|
|
|
|||
|
|
@ -1382,7 +1382,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
|
|||
if (filter->client_avail <= 0) {
|
||||
if (filter->end_of_file) {
|
||||
if (avail != NULL)
|
||||
*avail = 0;
|
||||
*avail = filter->avail;
|
||||
return (NULL);
|
||||
}
|
||||
bytes_read = (filter->vtable->read)(filter,
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ archive_read_append_filter(struct archive *_a, int code)
|
|||
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||
|
||||
bidder = a->bidders;
|
||||
for (i = 0; i < number_bidders; i++, bidder++)
|
||||
for (i = 1; i < number_bidders; i++, bidder++)
|
||||
{
|
||||
if (!bidder->name || !strcmp(bidder->name, str))
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -520,6 +520,7 @@ setup_xattr(struct archive_read_disk *a,
|
|||
if (size == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't read extended attribute");
|
||||
free(value);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1955,6 +1955,8 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
|
|||
t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
|
||||
return (t->visit_type);
|
||||
}
|
||||
/* Top stack item needs a regular visit. */
|
||||
t->current = t->stack;
|
||||
t->findData = &t->_findData;
|
||||
pattern = NULL;
|
||||
} else if (!FindNextFileW(t->d, &t->_findData)) {
|
||||
|
|
|
|||
|
|
@ -291,7 +291,8 @@ consume_header(struct archive_read_filter *self)
|
|||
if (p == NULL)
|
||||
goto truncated;
|
||||
len = archive_be32dec(p);
|
||||
__archive_read_filter_consume(self->upstream, len + 4 + 4);
|
||||
__archive_read_filter_consume(self->upstream,
|
||||
(int64_t)len + 4 + 4);
|
||||
}
|
||||
state->flags = flags;
|
||||
state->in_stream = 1;
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
|
||||
struct rpm {
|
||||
int64_t total_in;
|
||||
size_t hpos;
|
||||
size_t hlen;
|
||||
uint64_t hpos;
|
||||
uint64_t hlen;
|
||||
unsigned char header[16];
|
||||
enum {
|
||||
ST_LEAD, /* Skipping 'Lead' section. */
|
||||
|
|
@ -53,7 +53,8 @@ struct rpm {
|
|||
} state;
|
||||
int first_header;
|
||||
};
|
||||
#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
|
||||
#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
|
||||
#define RPM_MIN_HEAD_SIZE 16 /* Minimum size of 'Head'. */
|
||||
|
||||
static int rpm_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
|
|
@ -63,6 +64,8 @@ static ssize_t rpm_filter_read(struct archive_read_filter *,
|
|||
const void **);
|
||||
static int rpm_filter_close(struct archive_read_filter *);
|
||||
|
||||
static inline size_t rpm_limit_bytes(uint64_t, size_t);
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Deprecated; remove in libarchive 4.0 */
|
||||
int
|
||||
|
|
@ -155,15 +158,21 @@ rpm_bidder_init(struct archive_read_filter *self)
|
|||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
rpm_limit_bytes(uint64_t bytes, size_t max)
|
||||
{
|
||||
return (bytes > max ? max : (size_t)bytes);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
rpm_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
{
|
||||
struct rpm *rpm;
|
||||
const unsigned char *b;
|
||||
ssize_t avail_in, total;
|
||||
size_t used, n;
|
||||
uint32_t section;
|
||||
uint32_t bytes;
|
||||
ssize_t avail_in, total, used;
|
||||
size_t n;
|
||||
uint64_t section;
|
||||
uint64_t bytes;
|
||||
|
||||
rpm = (struct rpm *)self->data;
|
||||
*buff = NULL;
|
||||
|
|
@ -197,15 +206,14 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
|
|||
}
|
||||
break;
|
||||
case ST_HEADER:
|
||||
n = 16 - rpm->hpos;
|
||||
if (n > avail_in - used)
|
||||
n = avail_in - used;
|
||||
n = rpm_limit_bytes(RPM_MIN_HEAD_SIZE - rpm->hpos,
|
||||
avail_in - used);
|
||||
memcpy(rpm->header+rpm->hpos, b, n);
|
||||
b += n;
|
||||
used += n;
|
||||
rpm->hpos += n;
|
||||
|
||||
if (rpm->hpos == 16) {
|
||||
if (rpm->hpos == RPM_MIN_HEAD_SIZE) {
|
||||
if (rpm->header[0] != 0x8e ||
|
||||
rpm->header[1] != 0xad ||
|
||||
rpm->header[2] != 0xe8 ||
|
||||
|
|
@ -219,21 +227,20 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
|
|||
}
|
||||
rpm->state = ST_ARCHIVE;
|
||||
*buff = rpm->header;
|
||||
total = rpm->hpos;
|
||||
total = RPM_MIN_HEAD_SIZE;
|
||||
break;
|
||||
}
|
||||
/* Calculate 'Header' length. */
|
||||
section = archive_be32dec(rpm->header+8);
|
||||
bytes = archive_be32dec(rpm->header+12);
|
||||
rpm->hlen = 16 + section * 16 + bytes;
|
||||
rpm->hlen = rpm->hpos + section * 16 + bytes;
|
||||
rpm->state = ST_HEADER_DATA;
|
||||
rpm->first_header = 0;
|
||||
}
|
||||
break;
|
||||
case ST_HEADER_DATA:
|
||||
n = rpm->hlen - rpm->hpos;
|
||||
if (n > avail_in - used)
|
||||
n = avail_in - used;
|
||||
n = rpm_limit_bytes(rpm->hlen - rpm->hpos,
|
||||
avail_in - used);
|
||||
b += n;
|
||||
used += n;
|
||||
rpm->hpos += n;
|
||||
|
|
@ -241,7 +248,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
|
|||
rpm->state = ST_PADDING;
|
||||
break;
|
||||
case ST_PADDING:
|
||||
while (used < (size_t)avail_in) {
|
||||
while (used < avail_in) {
|
||||
if (*b != 0) {
|
||||
/* Read next header. */
|
||||
rpm->state = ST_HEADER;
|
||||
|
|
@ -259,7 +266,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
|
|||
used = avail_in;
|
||||
break;
|
||||
}
|
||||
if (used == (size_t)avail_in) {
|
||||
if (used == avail_in) {
|
||||
rpm->total_in += used;
|
||||
__archive_read_filter_consume(self->upstream, used);
|
||||
b = NULL;
|
||||
|
|
|
|||
|
|
@ -43,11 +43,13 @@
|
|||
/* Maximum lookahead during bid phase */
|
||||
#define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */
|
||||
|
||||
#define UUENCODE_MAX_LINE_LENGTH 34*1024 /* in bytes */
|
||||
|
||||
struct uudecode {
|
||||
int64_t total;
|
||||
unsigned char *in_buff;
|
||||
#define IN_BUFF_SIZE (1024)
|
||||
int in_cnt;
|
||||
ssize_t in_cnt;
|
||||
size_t in_allocated;
|
||||
unsigned char *out_buff;
|
||||
#define OUT_BUFF_SIZE (64 * 1024)
|
||||
|
|
@ -484,6 +486,12 @@ read_more:
|
|||
goto finish;
|
||||
}
|
||||
if (uudecode->in_cnt) {
|
||||
if (uudecode->in_cnt > UUENCODE_MAX_LINE_LENGTH) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Invalid format data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
/*
|
||||
* If there is remaining data which is saved by
|
||||
* previous calling, use it first.
|
||||
|
|
@ -498,7 +506,7 @@ read_more:
|
|||
uudecode->in_cnt = 0;
|
||||
}
|
||||
for (;used < avail_in; d += llen, used += llen) {
|
||||
int64_t l, body;
|
||||
ssize_t l, body;
|
||||
|
||||
b = d;
|
||||
len = get_line(b, avail_in - used, &nl);
|
||||
|
|
@ -533,7 +541,7 @@ read_more:
|
|||
return (ARCHIVE_FATAL);
|
||||
if (uudecode->in_buff != b)
|
||||
memmove(uudecode->in_buff, b, len);
|
||||
uudecode->in_cnt = (int)len;
|
||||
uudecode->in_cnt = len;
|
||||
if (total == 0) {
|
||||
/* Do not return 0; it means end-of-file.
|
||||
* We should try to read bytes more. */
|
||||
|
|
|
|||
|
|
@ -877,10 +877,9 @@ archive_read_format_7zip_read_data(struct archive_read *a,
|
|||
if (zip->end_of_entry)
|
||||
return (ARCHIVE_EOF);
|
||||
|
||||
const uint64_t max_read_size = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
|
||||
size_t bytes_to_read = max_read_size;
|
||||
size_t bytes_to_read = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
|
||||
if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) {
|
||||
bytes_to_read = zip->entry_bytes_remaining;
|
||||
bytes_to_read = (size_t)zip->entry_bytes_remaining;
|
||||
}
|
||||
bytes = read_stream(a, buff, bytes_to_read, 0);
|
||||
if (bytes < 0)
|
||||
|
|
@ -1063,8 +1062,8 @@ ppmd_read(void *p)
|
|||
*/
|
||||
ssize_t bytes_avail = 0;
|
||||
const uint8_t* data = __archive_read_ahead(a,
|
||||
zip->ppstream.stream_in+1, &bytes_avail);
|
||||
if(bytes_avail < zip->ppstream.stream_in+1) {
|
||||
(size_t)zip->ppstream.stream_in+1, &bytes_avail);
|
||||
if(data == NULL || bytes_avail < zip->ppstream.stream_in+1) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated 7z file data");
|
||||
|
|
@ -1766,6 +1765,10 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
|
|||
}
|
||||
zip->stream_valid = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD_H
|
||||
if (zip->zstdstream_valid)
|
||||
ZSTD_freeDStream(zip->zstd_dstream);
|
||||
#endif
|
||||
if (zip->ppmd7_valid) {
|
||||
__archive_ppmd7_functions.Ppmd7_Free(
|
||||
|
|
@ -2308,7 +2311,7 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
|
|||
usizes = ss->unpackSizes;
|
||||
for (i = 0; i < numFolders; i++) {
|
||||
unsigned pack;
|
||||
uint64_t sum;
|
||||
uint64_t size, sum;
|
||||
|
||||
if (f[i].numUnpackStreams == 0)
|
||||
continue;
|
||||
|
|
@ -2318,10 +2321,15 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
|
|||
for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
|
||||
if (parse_7zip_uint64(a, usizes) < 0)
|
||||
return (-1);
|
||||
if (*usizes > UINT64_MAX - sum)
|
||||
return (-1);
|
||||
sum += *usizes++;
|
||||
}
|
||||
}
|
||||
*usizes++ = folder_uncompressed_size(&f[i]) - sum;
|
||||
size = folder_uncompressed_size(&f[i]);
|
||||
if (size < sum)
|
||||
return (-1);
|
||||
*usizes++ = size - sum;
|
||||
}
|
||||
|
||||
if (type == kSize) {
|
||||
|
|
@ -2415,6 +2423,8 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
|
|||
packPos = si->pi.pos;
|
||||
for (i = 0; i < si->pi.numPackStreams; i++) {
|
||||
si->pi.positions[i] = packPos;
|
||||
if (packPos > UINT64_MAX - si->pi.sizes[i])
|
||||
return (-1);
|
||||
packPos += si->pi.sizes[i];
|
||||
if (packPos > zip->header_offset)
|
||||
return (-1);
|
||||
|
|
@ -2436,6 +2446,10 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
|
|||
f = si->ci.folders;
|
||||
for (i = 0; i < si->ci.numFolders; i++) {
|
||||
f[i].packIndex = packIndex;
|
||||
if (f[i].numPackedStreams > UINT32_MAX)
|
||||
return (-1);
|
||||
if (packIndex > UINT32_MAX - (uint32_t)f[i].numPackedStreams)
|
||||
return (-1);
|
||||
packIndex += (uint32_t)f[i].numPackedStreams;
|
||||
if (packIndex > si->pi.numPackStreams)
|
||||
return (-1);
|
||||
|
|
@ -3000,7 +3014,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
|
|||
/* CRC check. */
|
||||
if (crc32(0, (const unsigned char *)p + 12, 20)
|
||||
!= archive_le32dec(p + 8)) {
|
||||
#ifdef DONT_FAIL_ON_CRC_ERROR
|
||||
#ifndef DONT_FAIL_ON_CRC_ERROR
|
||||
archive_set_error(&a->archive, -1, "Header CRC error");
|
||||
return (ARCHIVE_FATAL);
|
||||
#endif
|
||||
|
|
@ -3142,7 +3156,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
|
|||
/* Copy mode. */
|
||||
|
||||
*buff = __archive_read_ahead(a, minimum, &bytes_avail);
|
||||
if (bytes_avail <= 0) {
|
||||
if (*buff == NULL) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated 7-Zip file data");
|
||||
|
|
@ -3448,7 +3462,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
|
|||
/*
|
||||
* Skip the bytes we already has skipped in skip_stream().
|
||||
*/
|
||||
while (skip_bytes) {
|
||||
while (1) {
|
||||
ssize_t skipped;
|
||||
|
||||
if (zip->uncompressed_buffer_bytes_remaining == 0) {
|
||||
|
|
@ -3468,6 +3482,10 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip_bytes)
|
||||
break;
|
||||
|
||||
skipped = get_uncompressed_data(
|
||||
a, buff, (size_t)skip_bytes, 0);
|
||||
if (skipped < 0)
|
||||
|
|
|
|||
|
|
@ -439,9 +439,9 @@ archive_read_format_ar_read_header(struct archive_read *a,
|
|||
if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
|
||||
/* Broken header. */
|
||||
return (ARCHIVE_EOF);
|
||||
|
||||
|
||||
unconsumed = 60;
|
||||
|
||||
|
||||
ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
|
||||
|
||||
if (unconsumed)
|
||||
|
|
@ -458,7 +458,6 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
|
|||
uint64_t n;
|
||||
|
||||
/* Copy remaining header */
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_mtime(entry,
|
||||
(time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
|
||||
archive_entry_set_uid(entry,
|
||||
|
|
@ -467,6 +466,7 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
|
|||
(gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size));
|
||||
archive_entry_set_mode(entry,
|
||||
(mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size));
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
n = ar_atol10(h + AR_size_offset, AR_size_size);
|
||||
|
||||
ar->entry_offset = 0;
|
||||
|
|
|
|||
|
|
@ -1682,7 +1682,7 @@ cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
|
|||
cfdata->uncompressed_size - cab->xstrm.total_out;
|
||||
|
||||
d = __archive_read_ahead(a, 1, &bytes_avail);
|
||||
if (bytes_avail <= 0) {
|
||||
if (d == NULL) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated CAB file data");
|
||||
|
|
|
|||
|
|
@ -834,6 +834,7 @@ static int
|
|||
header_afiol(struct archive_read *a, struct cpio *cpio,
|
||||
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
|
||||
{
|
||||
int64_t t;
|
||||
const void *h;
|
||||
const char *header;
|
||||
|
||||
|
|
@ -850,7 +851,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
|
|||
|
||||
archive_entry_set_dev(entry,
|
||||
(dev_t)atol16(header + afiol_dev_offset, afiol_dev_size));
|
||||
archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
|
||||
t = atol16(header + afiol_ino_offset, afiol_ino_size);
|
||||
if (t < 0) {
|
||||
archive_set_error(&a->archive, 0, "Nonsensical ino value");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_entry_set_ino(entry, t);
|
||||
archive_entry_set_mode(entry,
|
||||
(mode_t)atol8(header + afiol_mode_offset, afiol_mode_size));
|
||||
archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
|
||||
|
|
@ -863,8 +869,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
|
|||
*namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size);
|
||||
*name_pad = 0; /* No padding of filename. */
|
||||
|
||||
cpio->entry_bytes_remaining =
|
||||
atol16(header + afiol_filesize_offset, afiol_filesize_size);
|
||||
t = atol16(header + afiol_filesize_offset, afiol_filesize_size);
|
||||
if (t < 0) {
|
||||
archive_set_error(&a->archive, 0, "Nonsensical file size");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
cpio->entry_bytes_remaining = t;
|
||||
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
|
||||
cpio->entry_padding = 0;
|
||||
__archive_read_consume(a, afiol_header_size);
|
||||
|
|
@ -1002,7 +1012,7 @@ be4(const unsigned char *p)
|
|||
static int64_t
|
||||
atol8(const char *p, unsigned char_cnt)
|
||||
{
|
||||
int64_t l;
|
||||
uint64_t l;
|
||||
int digit;
|
||||
|
||||
l = 0;
|
||||
|
|
@ -1010,18 +1020,18 @@ atol8(const char *p, unsigned char_cnt)
|
|||
if (*p >= '0' && *p <= '7')
|
||||
digit = *p - '0';
|
||||
else
|
||||
return (l);
|
||||
return ((int64_t)l);
|
||||
p++;
|
||||
l <<= 3;
|
||||
l |= digit;
|
||||
}
|
||||
return (l);
|
||||
return ((int64_t)l);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
atol16(const char *p, unsigned char_cnt)
|
||||
{
|
||||
int64_t l;
|
||||
uint64_t l;
|
||||
int digit;
|
||||
|
||||
l = 0;
|
||||
|
|
@ -1033,12 +1043,12 @@ atol16(const char *p, unsigned char_cnt)
|
|||
else if (*p >= '0' && *p <= '9')
|
||||
digit = *p - '0';
|
||||
else
|
||||
return (l);
|
||||
return ((int64_t)l);
|
||||
p++;
|
||||
l <<= 4;
|
||||
l |= digit;
|
||||
}
|
||||
return (l);
|
||||
return ((int64_t)l);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -402,6 +402,9 @@ static int isJolietSVD(struct iso9660 *, const unsigned char *);
|
|||
static int isSVD(struct iso9660 *, const unsigned char *);
|
||||
static int isEVD(struct iso9660 *, const unsigned char *);
|
||||
static int isPVD(struct iso9660 *, const unsigned char *);
|
||||
static int isRootDirectoryRecord(const unsigned char *);
|
||||
static int isValid723Integer(const unsigned char *);
|
||||
static int isValid733Integer(const unsigned char *);
|
||||
static int next_cache_entry(struct archive_read *, struct iso9660 *,
|
||||
struct file_info **);
|
||||
static int next_entry_seek(struct archive_read *, struct iso9660 *,
|
||||
|
|
@ -773,8 +776,9 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
|
|||
|
||||
/* Read Root Directory Record in Volume Descriptor. */
|
||||
p = h + SVD_root_directory_record_offset;
|
||||
if (p[DR_length_offset] != 34)
|
||||
if (!isRootDirectoryRecord(p)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (48);
|
||||
}
|
||||
|
|
@ -851,8 +855,9 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
|
|||
|
||||
/* Read Root Directory Record in Volume Descriptor. */
|
||||
p = h + PVD_root_directory_record_offset;
|
||||
if (p[DR_length_offset] != 34)
|
||||
if (!isRootDirectoryRecord(p)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (48);
|
||||
}
|
||||
|
|
@ -882,21 +887,43 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
|
|||
if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
|
||||
return (0);
|
||||
|
||||
/* Volume space size must be encoded according to 7.3.3 */
|
||||
if (!isValid733Integer(h + PVD_volume_space_size_offset)) {
|
||||
return (0);
|
||||
}
|
||||
volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
|
||||
if (volume_block <= SYSTEM_AREA_BLOCK+4)
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
|
||||
return (0);
|
||||
|
||||
/* Volume set size must be encoded according to 7.2.3 */
|
||||
if (!isValid723Integer(h + PVD_volume_set_size_offset)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Volume sequence number must be encoded according to 7.2.3 */
|
||||
if (!isValid723Integer(h + PVD_volume_sequence_number_offset)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Logical block size must be > 0. */
|
||||
/* I've looked at Ecma 119 and can't find any stronger
|
||||
* restriction on this field. */
|
||||
if (!isValid723Integer(h + PVD_logical_block_size_offset)) {
|
||||
return (0);
|
||||
}
|
||||
logical_block_size =
|
||||
archive_le16dec(h + PVD_logical_block_size_offset);
|
||||
if (logical_block_size <= 0)
|
||||
return (0);
|
||||
|
||||
volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
|
||||
if (volume_block <= SYSTEM_AREA_BLOCK+4)
|
||||
/* Path Table size must be encoded according to 7.3.3 */
|
||||
if (!isValid733Integer(h + PVD_path_table_size_offset)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* File structure version must be 1 for ISO9660/ECMA119. */
|
||||
if (h[PVD_file_structure_version_offset] != 1)
|
||||
|
|
@ -935,8 +962,9 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
|
|||
|
||||
/* Read Root Directory Record in Volume Descriptor. */
|
||||
p = h + PVD_root_directory_record_offset;
|
||||
if (p[DR_length_offset] != 34)
|
||||
if (!isRootDirectoryRecord(p)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!iso9660->primary.location) {
|
||||
iso9660->logical_block_size = logical_block_size;
|
||||
|
|
@ -951,6 +979,51 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
|
|||
return (48);
|
||||
}
|
||||
|
||||
static int
|
||||
isRootDirectoryRecord(const unsigned char *p) {
|
||||
int flags;
|
||||
|
||||
/* ECMA119/ISO9660 requires that the root directory record be _exactly_ 34 bytes.
|
||||
* However, we've seen images that have root directory records up to 68 bytes. */
|
||||
if (p[DR_length_offset] < 34 || p[DR_length_offset] > 68) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* The root directory location must be a 7.3.3 32-bit integer. */
|
||||
if (!isValid733Integer(p + DR_extent_offset)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* The root directory size must be a 7.3.3 integer. */
|
||||
if (!isValid733Integer(p + DR_size_offset)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* According to the standard, certain bits must be one or zero:
|
||||
* Bit 1: must be 1 (this is a directory)
|
||||
* Bit 2: must be 0 (not an associated file)
|
||||
* Bit 3: must be 0 (doesn't use extended attribute record)
|
||||
* Bit 7: must be 0 (final directory record for this file)
|
||||
*/
|
||||
flags = p[DR_flags_offset];
|
||||
if ((flags & 0x8E) != 0x02) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Volume sequence number must be a 7.2.3 integer. */
|
||||
if (!isValid723Integer(p + DR_volume_sequence_number_offset)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Root directory name is a single zero byte... */
|
||||
if (p[DR_name_len_offset] != 1 || p[DR_name_offset] != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Nothing looked wrong, so let's accept it. */
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
read_children(struct archive_read *a, struct file_info *parent)
|
||||
{
|
||||
|
|
@ -1212,7 +1285,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
|
|||
}
|
||||
}
|
||||
if (iso9660->utf16be_previous_path == NULL) {
|
||||
iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
|
||||
iso9660->utf16be_previous_path = calloc(1, UTF16_NAME_MAX);
|
||||
if (iso9660->utf16be_previous_path == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory");
|
||||
|
|
@ -3033,7 +3106,7 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
new_pending_files = (struct file_info **)
|
||||
malloc(new_size * sizeof(new_pending_files[0]));
|
||||
calloc(new_size, sizeof(new_pending_files[0]));
|
||||
if (new_pending_files == NULL) {
|
||||
archive_set_error(&a->archive,
|
||||
ENOMEM, "Out of memory");
|
||||
|
|
@ -3127,6 +3200,32 @@ toi(const void *p, int n)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ECMA119/ISO9660 stores multi-byte integers in one of
|
||||
* three different formats:
|
||||
* * Little-endian (specified in section 7.2.1 and 7.3.1)
|
||||
* * Big-endian (specified in section 7.2.2 and 7.3.2)
|
||||
* * Both (specified in section 7.2.3 and 7.3.3)
|
||||
*
|
||||
* For values that follow section 7.2.3 (16-bit) or 7.3.3 (32-bit), we
|
||||
* can check that the little-endian and big-endian forms agree with
|
||||
* each other. This helps us avoid trying to decode files that are
|
||||
* not really ISO images.
|
||||
*/
|
||||
static int
|
||||
isValid723Integer(const unsigned char *p) {
|
||||
return (p[0] == p[3] && p[1] == p[2]);
|
||||
}
|
||||
|
||||
static int
|
||||
isValid733Integer(const unsigned char *p)
|
||||
{
|
||||
return (p[0] == p[7]
|
||||
&& p[1] == p[6]
|
||||
&& p[2] == p[5]
|
||||
&& p[3] == p[4]);
|
||||
}
|
||||
|
||||
static time_t
|
||||
isodate7(const unsigned char *v)
|
||||
{
|
||||
|
|
@ -3164,7 +3263,7 @@ isodate17(const unsigned char *v)
|
|||
tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
|
||||
+ (v[2] - '0') * 10 + (v[3] - '0')
|
||||
- 1900;
|
||||
tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
|
||||
tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0') - 1;
|
||||
tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
|
||||
tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
|
||||
tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ static int lha_read_file_header_1(struct archive_read *, struct lha *);
|
|||
static int lha_read_file_header_2(struct archive_read *, struct lha *);
|
||||
static int lha_read_file_header_3(struct archive_read *, struct lha *);
|
||||
static int lha_read_file_extended_header(struct archive_read *,
|
||||
struct lha *, uint16_t *, int, size_t, size_t *);
|
||||
struct lha *, uint16_t *, int, uint64_t, size_t *);
|
||||
static size_t lha_check_header_format(const void *);
|
||||
static int lha_skip_sfx(struct archive_read *);
|
||||
static time_t lha_dos_time(const unsigned char *);
|
||||
|
|
@ -945,7 +945,7 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
|
|||
|
||||
/* Read extended headers */
|
||||
err2 = lha_read_file_extended_header(a, lha, NULL, 2,
|
||||
(size_t)(lha->compsize + 2), &extdsize);
|
||||
(uint64_t)(lha->compsize + 2), &extdsize);
|
||||
if (err2 < ARCHIVE_WARN)
|
||||
return (err2);
|
||||
if (err2 < err)
|
||||
|
|
@ -1138,7 +1138,7 @@ invalid:
|
|||
*/
|
||||
static int
|
||||
lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
|
||||
uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
|
||||
uint16_t *crc, int sizefield_length, uint64_t limitsize, size_t *total_size)
|
||||
{
|
||||
const void *h;
|
||||
const unsigned char *extdheader;
|
||||
|
|
@ -1187,8 +1187,7 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
|
|||
}
|
||||
|
||||
/* Sanity check to the extended header size. */
|
||||
if (((uint64_t)*total_size + extdsize) >
|
||||
(uint64_t)limitsize ||
|
||||
if (((uint64_t)*total_size + extdsize) > limitsize ||
|
||||
extdsize <= (size_t)sizefield_length)
|
||||
goto invalid;
|
||||
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
|
|||
struct huffman_table_entry *, int, int);
|
||||
static int expand(struct archive_read *, int64_t *);
|
||||
static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
|
||||
int64_t, int);
|
||||
int64_t, size_t);
|
||||
static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
|
||||
static int parse_filter(struct archive_read *, const uint8_t *, uint16_t,
|
||||
uint8_t);
|
||||
|
|
@ -1373,6 +1373,8 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
struct archive_string_conv *sconv, *fn_sconv;
|
||||
unsigned long crc32_val;
|
||||
int ret = (ARCHIVE_OK), ret2;
|
||||
char *newptr;
|
||||
size_t newsize;
|
||||
|
||||
rar = (struct rar *)(a->format->data);
|
||||
|
||||
|
|
@ -1469,6 +1471,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
|
||||
if (rar->file_flags & FHD_LARGE)
|
||||
{
|
||||
if (p + 8 > endp) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Invalid header size");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
memcpy(packed_size, file_header.pack_size, 4);
|
||||
memcpy(packed_size + 4, p, 4); /* High pack size */
|
||||
p += 4;
|
||||
|
|
@ -1514,8 +1521,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (rar->filename_allocated < filename_size * 2 + 2) {
|
||||
char *newptr;
|
||||
size_t newsize = filename_size * 2 + 2;
|
||||
newsize = filename_size * 2 + 2;
|
||||
newptr = realloc(rar->filename, newsize);
|
||||
if (newptr == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
|
|
@ -1539,7 +1545,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
fn_end = filename_size * 2;
|
||||
filename_size = 0;
|
||||
offset = (unsigned)strlen(filename) + 1;
|
||||
highbyte = *(p + offset++);
|
||||
highbyte = offset >= end ? 0 : *(p + offset++);
|
||||
flagbits = 0;
|
||||
flagbyte = 0;
|
||||
while (offset < end && filename_size < fn_end)
|
||||
|
|
@ -1554,14 +1560,22 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
switch((flagbyte >> flagbits) & 3)
|
||||
{
|
||||
case 0:
|
||||
if (offset >= end)
|
||||
continue;
|
||||
filename[filename_size++] = '\0';
|
||||
filename[filename_size++] = *(p + offset++);
|
||||
break;
|
||||
case 1:
|
||||
if (offset >= end)
|
||||
continue;
|
||||
filename[filename_size++] = highbyte;
|
||||
filename[filename_size++] = *(p + offset++);
|
||||
break;
|
||||
case 2:
|
||||
if (offset >= end - 1) {
|
||||
offset = end;
|
||||
continue;
|
||||
}
|
||||
filename[filename_size++] = *(p + offset + 1);
|
||||
filename[filename_size++] = *(p + offset);
|
||||
offset += 2;
|
||||
|
|
@ -1569,9 +1583,15 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
case 3:
|
||||
{
|
||||
char extra, high;
|
||||
uint8_t length = *(p + offset++);
|
||||
uint8_t length;
|
||||
|
||||
if (offset >= end)
|
||||
continue;
|
||||
|
||||
length = *(p + offset++);
|
||||
if (length & 0x80) {
|
||||
if (offset >= end)
|
||||
continue;
|
||||
extra = *(p + offset++);
|
||||
high = (char)highbyte;
|
||||
} else
|
||||
|
|
@ -1652,13 +1672,16 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
rar->cursor++;
|
||||
if (rar->cursor >= rar->nodes)
|
||||
{
|
||||
rar->nodes++;
|
||||
if ((rar->dbo =
|
||||
realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL)
|
||||
struct data_block_offsets *newdbo;
|
||||
|
||||
newsize = sizeof(*rar->dbo) * (rar->nodes + 1);
|
||||
if ((newdbo = realloc(rar->dbo, newsize)) == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
rar->dbo = newdbo;
|
||||
rar->nodes++;
|
||||
rar->dbo[rar->cursor].header_size = header_size;
|
||||
rar->dbo[rar->cursor].start_offset = -1;
|
||||
rar->dbo[rar->cursor].end_offset = -1;
|
||||
|
|
@ -1678,9 +1701,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
rar->filename_save = (char*)realloc(rar->filename_save,
|
||||
filename_size + 1);
|
||||
memcpy(rar->filename_save, rar->filename, filename_size + 1);
|
||||
newsize = filename_size + 1;
|
||||
if ((newptr = realloc(rar->filename_save, newsize)) == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
rar->filename_save = newptr;
|
||||
memcpy(rar->filename_save, rar->filename, newsize);
|
||||
rar->filename_save_size = filename_size;
|
||||
|
||||
/* Set info for seeking */
|
||||
|
|
@ -2060,7 +2088,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
|||
bs = rar->unp_buffer_size - rar->unp_offset;
|
||||
else
|
||||
bs = (size_t)rar->bytes_uncopied;
|
||||
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
|
||||
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
rar->offset += bs;
|
||||
|
|
@ -2213,7 +2241,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
|||
bs = rar->unp_buffer_size - rar->unp_offset;
|
||||
else
|
||||
bs = (size_t)rar->bytes_uncopied;
|
||||
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
|
||||
ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
rar->offset += bs;
|
||||
|
|
@ -2579,8 +2607,7 @@ read_next_symbol(struct archive_read *a, struct huffman_code *code)
|
|||
rar_br_consume(br, code->tablesize);
|
||||
|
||||
node = value;
|
||||
while (!(code->tree[node].branches[0] ==
|
||||
code->tree[node].branches[1]))
|
||||
while (code->tree[node].branches[0] != code->tree[node].branches[1])
|
||||
{
|
||||
if (!rar_br_read_ahead(a, br, 1)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
|
|
@ -2955,7 +2982,7 @@ expand(struct archive_read *a, int64_t *end)
|
|||
|
||||
if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
|
||||
goto bad_data;
|
||||
if (lensymbol > lengthb_min)
|
||||
if (lensymbol >= lengthb_min)
|
||||
goto bad_data;
|
||||
len = lengthbases[lensymbol] + 2;
|
||||
if (lengthbits[lensymbol] > 0) {
|
||||
|
|
@ -2987,7 +3014,7 @@ expand(struct archive_read *a, int64_t *end)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (symbol-271 > lengthb_min)
|
||||
if (symbol-271 >= lengthb_min)
|
||||
goto bad_data;
|
||||
len = lengthbases[symbol-271]+3;
|
||||
if(lengthbits[symbol-271] > 0) {
|
||||
|
|
@ -2999,7 +3026,7 @@ expand(struct archive_read *a, int64_t *end)
|
|||
|
||||
if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
|
||||
goto bad_data;
|
||||
if (offssymbol > offsetb_min)
|
||||
if (offssymbol >= offsetb_min)
|
||||
goto bad_data;
|
||||
offs = offsetbases[offssymbol]+1;
|
||||
if(offsetbits[offssymbol] > 0)
|
||||
|
|
@ -3094,11 +3121,16 @@ copy_from_lzss_window(struct archive_read *a, void *buffer,
|
|||
|
||||
static int
|
||||
copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
|
||||
int64_t startpos, int length)
|
||||
int64_t startpos, size_t length)
|
||||
{
|
||||
int windowoffs, firstpart;
|
||||
struct rar *rar = (struct rar *)(a->format->data);
|
||||
|
||||
if (length > rar->unp_buffer_size)
|
||||
{
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
if (!rar->unp_buffer)
|
||||
{
|
||||
if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
|
||||
|
|
@ -3110,17 +3142,17 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
|
|||
}
|
||||
|
||||
windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
|
||||
if(windowoffs + length <= lzss_size(&rar->lzss)) {
|
||||
if(windowoffs + length <= (size_t)lzss_size(&rar->lzss)) {
|
||||
memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
|
||||
length);
|
||||
} else if (length <= lzss_size(&rar->lzss)) {
|
||||
} else if (length <= (size_t)lzss_size(&rar->lzss)) {
|
||||
firstpart = lzss_size(&rar->lzss) - windowoffs;
|
||||
if (firstpart < 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Bad RAR file data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (firstpart < length) {
|
||||
if ((size_t)firstpart < length) {
|
||||
memcpy(&rar->unp_buffer[rar->unp_offset],
|
||||
&rar->lzss.window[windowoffs], firstpart);
|
||||
memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
|
||||
|
|
@ -3130,16 +3162,19 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
|
|||
&rar->lzss.window[windowoffs], length);
|
||||
}
|
||||
} else {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Bad RAR file data");
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fatal;
|
||||
}
|
||||
rar->unp_offset += length;
|
||||
rar->unp_offset += (unsigned int) length;
|
||||
if (rar->unp_offset >= rar->unp_buffer_size)
|
||||
*buffer = rar->unp_buffer;
|
||||
else
|
||||
*buffer = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
fatal:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Bad RAR file data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static const void *
|
||||
|
|
@ -3325,7 +3360,10 @@ create_filter(struct rar_program_code *prog, const uint8_t *globaldata, uint32_t
|
|||
filter->globaldatalen = globaldatalen > PROGRAM_SYSTEM_GLOBAL_SIZE ? globaldatalen : PROGRAM_SYSTEM_GLOBAL_SIZE;
|
||||
filter->globaldata = calloc(1, filter->globaldatalen);
|
||||
if (!filter->globaldata)
|
||||
{
|
||||
free(filter);
|
||||
return NULL;
|
||||
}
|
||||
if (globaldata)
|
||||
memcpy(filter->globaldata, globaldata, globaldatalen);
|
||||
if (registers)
|
||||
|
|
@ -3352,7 +3390,7 @@ run_filters(struct archive_read *a)
|
|||
if (filters == NULL || filter == NULL)
|
||||
return (0);
|
||||
|
||||
start = filters->filterstart;
|
||||
start = (size_t)filters->filterstart;
|
||||
end = start + filter->blocklength;
|
||||
|
||||
filters->filterstart = INT64_MAX;
|
||||
|
|
@ -3389,10 +3427,16 @@ run_filters(struct archive_read *a)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (filter->blocklength > VM_MEMORY_SIZE)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Bad RAR file data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = copy_from_lzss_window(a, filters->vm->memory, start, filter->blocklength);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return 0;
|
||||
if (!execute_filter(a, filter, filters->vm, rar->offset))
|
||||
if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
|
||||
return 0;
|
||||
|
||||
lastfilteraddress = filter->filteredblockaddress;
|
||||
|
|
@ -3404,7 +3448,7 @@ run_filters(struct archive_read *a)
|
|||
while ((filter = filters->stack) != NULL && (int64_t)filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength)
|
||||
{
|
||||
memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength);
|
||||
if (!execute_filter(a, filter, filters->vm, rar->offset))
|
||||
if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
|
||||
return 0;
|
||||
|
||||
lastfilteraddress = filter->filteredblockaddress;
|
||||
|
|
@ -3645,7 +3689,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
|
|||
{
|
||||
uint32_t currpos = (uint32_t)pos + i + 1;
|
||||
int32_t address = (int32_t)vm_read_32(vm, i + 1);
|
||||
if (address < 0 && currpos >= (uint32_t)-address)
|
||||
if (address < 0 && currpos >= (~(uint32_t)address + 1))
|
||||
vm_write_32(vm, i + 1, address + filesize);
|
||||
else if (address >= 0 && (uint32_t)address < filesize)
|
||||
vm_write_32(vm, i + 1, address - currpos);
|
||||
|
|
@ -3668,7 +3712,7 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
|
|||
uint8_t *src, *dst;
|
||||
uint32_t i, j;
|
||||
|
||||
if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength)
|
||||
if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength || blocklength < 3 || byteoffset > 2)
|
||||
return 0;
|
||||
|
||||
src = &vm->memory[0];
|
||||
|
|
@ -3678,6 +3722,13 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
|
|||
uint8_t *prev = dst + i - stride;
|
||||
for (j = i; j < blocklength; j += 3)
|
||||
{
|
||||
/*
|
||||
* The src block should not overlap with the dst block.
|
||||
* If so it would be better to consider this archive is broken.
|
||||
*/
|
||||
if (src >= dst)
|
||||
return 0;
|
||||
|
||||
if (prev >= dst)
|
||||
{
|
||||
uint32_t delta1 = abs(prev[3] - prev[0]);
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ struct comp_state {
|
|||
decompression. */
|
||||
uint8_t* filtered_buf; /* Buffer used when applying filters. */
|
||||
const uint8_t* block_buf; /* Buffer used when merging blocks. */
|
||||
size_t window_mask; /* Convenience field; window_size - 1. */
|
||||
ssize_t window_mask; /* Convenience field; window_size - 1. */
|
||||
int64_t write_ptr; /* This amount of data has been unpacked
|
||||
in the window buffer. */
|
||||
int64_t last_write_ptr; /* This amount of data has been stored in
|
||||
|
|
@ -361,6 +361,7 @@ static int verify_global_checksums(struct archive_read* a);
|
|||
static int rar5_read_data_skip(struct archive_read *a);
|
||||
static int push_data_ready(struct archive_read* a, struct rar5* rar,
|
||||
const uint8_t* buf, size_t size, int64_t offset);
|
||||
static void clear_data_ready_stack(struct rar5* rar);
|
||||
|
||||
/* CDE_xxx = Circular Double Ended (Queue) return values. */
|
||||
enum CDE_RETURN_VALUES {
|
||||
|
|
@ -505,7 +506,7 @@ static inline struct rar5* get_context(struct archive_read* a) {
|
|||
}
|
||||
|
||||
/* Convenience functions used by filter implementations. */
|
||||
static void circular_memcpy(uint8_t* dst, uint8_t* window, const uint64_t mask,
|
||||
static void circular_memcpy(uint8_t* dst, uint8_t* window, const ssize_t mask,
|
||||
int64_t start, int64_t end)
|
||||
{
|
||||
if((start & mask) > (end & mask)) {
|
||||
|
|
@ -652,6 +653,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
|
|||
int ret;
|
||||
struct rar5* rar = get_context(a);
|
||||
|
||||
clear_data_ready_stack(rar);
|
||||
free(rar->cstate.filtered_buf);
|
||||
|
||||
rar->cstate.filtered_buf = malloc(flt->block_length);
|
||||
|
|
@ -709,7 +711,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
|
|||
static void push_data(struct archive_read* a, struct rar5* rar,
|
||||
const uint8_t* buf, int64_t idx_begin, int64_t idx_end)
|
||||
{
|
||||
const uint64_t wmask = rar->cstate.window_mask;
|
||||
const ssize_t wmask = rar->cstate.window_mask;
|
||||
const ssize_t solid_write_ptr = (rar->cstate.solid_offset +
|
||||
rar->cstate.last_write_ptr) & wmask;
|
||||
|
||||
|
|
@ -1246,7 +1248,7 @@ static int process_main_locator_extra_block(struct archive_read* a,
|
|||
}
|
||||
|
||||
static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
|
||||
ssize_t* extra_data_size)
|
||||
int64_t* extra_data_size)
|
||||
{
|
||||
size_t hash_type = 0;
|
||||
size_t value_len;
|
||||
|
|
@ -1296,7 +1298,7 @@ static uint64_t time_win_to_unix(uint64_t win_time) {
|
|||
}
|
||||
|
||||
static int parse_htime_item(struct archive_read* a, char unix_time,
|
||||
uint64_t* where, ssize_t* extra_data_size)
|
||||
uint64_t* where, int64_t* extra_data_size)
|
||||
{
|
||||
if(unix_time) {
|
||||
uint32_t time_val;
|
||||
|
|
@ -1318,7 +1320,7 @@ static int parse_htime_item(struct archive_read* a, char unix_time,
|
|||
}
|
||||
|
||||
static int parse_file_extra_version(struct archive_read* a,
|
||||
struct archive_entry* e, ssize_t* extra_data_size)
|
||||
struct archive_entry* e, int64_t* extra_data_size)
|
||||
{
|
||||
size_t flags = 0;
|
||||
size_t version = 0;
|
||||
|
|
@ -1372,7 +1374,7 @@ static int parse_file_extra_version(struct archive_read* a,
|
|||
}
|
||||
|
||||
static int parse_file_extra_htime(struct archive_read* a,
|
||||
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
|
||||
struct archive_entry* e, struct rar5* rar, int64_t* extra_data_size)
|
||||
{
|
||||
char unix_time = 0;
|
||||
size_t flags = 0;
|
||||
|
|
@ -1425,7 +1427,7 @@ static int parse_file_extra_htime(struct archive_read* a,
|
|||
}
|
||||
|
||||
static int parse_file_extra_redir(struct archive_read* a,
|
||||
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
|
||||
struct archive_entry* e, struct rar5* rar, int64_t* extra_data_size)
|
||||
{
|
||||
uint64_t value_size = 0;
|
||||
size_t target_size = 0;
|
||||
|
|
@ -1448,9 +1450,6 @@ static int parse_file_extra_redir(struct archive_read* a,
|
|||
return ARCHIVE_EOF;
|
||||
*extra_data_size -= target_size + 1;
|
||||
|
||||
if(!read_ahead(a, target_size, &p))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
if(target_size > (MAX_NAME_IN_CHARS - 1)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Link target is too long");
|
||||
|
|
@ -1463,6 +1462,9 @@ static int parse_file_extra_redir(struct archive_read* a,
|
|||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
if(!read_ahead(a, target_size, &p))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
memcpy(target_utf8_buf, p, target_size);
|
||||
target_utf8_buf[target_size] = 0;
|
||||
|
||||
|
|
@ -1496,7 +1498,7 @@ static int parse_file_extra_redir(struct archive_read* a,
|
|||
}
|
||||
|
||||
static int parse_file_extra_owner(struct archive_read* a,
|
||||
struct archive_entry* e, ssize_t* extra_data_size)
|
||||
struct archive_entry* e, int64_t* extra_data_size)
|
||||
{
|
||||
uint64_t flags = 0;
|
||||
uint64_t value_size = 0;
|
||||
|
|
@ -1576,15 +1578,15 @@ static int parse_file_extra_owner(struct archive_read* a,
|
|||
}
|
||||
|
||||
static int process_head_file_extra(struct archive_read* a,
|
||||
struct archive_entry* e, struct rar5* rar, ssize_t extra_data_size)
|
||||
struct archive_entry* e, struct rar5* rar, int64_t extra_data_size)
|
||||
{
|
||||
size_t extra_field_size;
|
||||
size_t extra_field_id = 0;
|
||||
uint64_t extra_field_size;
|
||||
uint64_t extra_field_id = 0;
|
||||
int ret = ARCHIVE_FATAL;
|
||||
size_t var_size;
|
||||
uint64_t var_size;
|
||||
|
||||
while(extra_data_size > 0) {
|
||||
if(!read_var_sized(a, &extra_field_size, &var_size))
|
||||
if(!read_var(a, &extra_field_size, &var_size))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
extra_data_size -= var_size;
|
||||
|
|
@ -1592,7 +1594,7 @@ static int process_head_file_extra(struct archive_read* a,
|
|||
return ARCHIVE_EOF;
|
||||
}
|
||||
|
||||
if(!read_var_sized(a, &extra_field_id, &var_size))
|
||||
if(!read_var(a, &extra_field_id, &var_size))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
extra_data_size -= var_size;
|
||||
|
|
@ -1642,7 +1644,7 @@ static int process_head_file_extra(struct archive_read* a,
|
|||
static int process_head_file(struct archive_read* a, struct rar5* rar,
|
||||
struct archive_entry* entry, size_t block_flags)
|
||||
{
|
||||
ssize_t extra_data_size = 0;
|
||||
int64_t extra_data_size = 0;
|
||||
size_t data_size = 0;
|
||||
size_t file_flags = 0;
|
||||
size_t file_attr = 0;
|
||||
|
|
@ -1682,12 +1684,12 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
|
|||
}
|
||||
|
||||
if(block_flags & HFL_EXTRA_DATA) {
|
||||
size_t edata_size = 0;
|
||||
if(!read_var_sized(a, &edata_size, NULL))
|
||||
uint64_t edata_size = 0;
|
||||
if(!read_var(a, &edata_size, NULL))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
/* Intentional type cast from unsigned to signed. */
|
||||
extra_data_size = (ssize_t) edata_size;
|
||||
extra_data_size = (int64_t) edata_size;
|
||||
}
|
||||
|
||||
if(block_flags & HFL_DATA) {
|
||||
|
|
@ -1780,11 +1782,18 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
|
|||
if(rar->cstate.window_size < (ssize_t) window_size &&
|
||||
rar->cstate.window_buf)
|
||||
{
|
||||
/* The `data_ready` stack contains pointers to the `window_buf` or
|
||||
* `filtered_buf` buffers. Since we're about to reallocate the first
|
||||
* buffer, some of those pointers could become invalid. Therefore, we
|
||||
* need to dispose of all entries from the stack before attempting the
|
||||
* realloc. */
|
||||
clear_data_ready_stack(rar);
|
||||
|
||||
/* If window_buf has been allocated before, reallocate it, so
|
||||
* that its size will match new window_size. */
|
||||
|
||||
uint8_t* new_window_buf =
|
||||
realloc(rar->cstate.window_buf, window_size);
|
||||
realloc(rar->cstate.window_buf, (size_t) window_size);
|
||||
|
||||
if(!new_window_buf) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
|
|
@ -1876,9 +1885,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
|
|||
if(!read_var_sized(a, &name_size, NULL))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
if(!read_ahead(a, name_size, &p))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
if(name_size > (MAX_NAME_IN_CHARS - 1)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Filename is too long");
|
||||
|
|
@ -1893,6 +1899,9 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
|
|||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
if(!read_ahead(a, name_size, &p))
|
||||
return ARCHIVE_EOF;
|
||||
|
||||
memcpy(name_utf8_buf, p, name_size);
|
||||
name_utf8_buf[name_size] = 0;
|
||||
if(ARCHIVE_OK != consume(a, name_size)) {
|
||||
|
|
@ -1980,7 +1989,7 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
|
|||
struct archive_entry* entry, size_t block_flags)
|
||||
{
|
||||
int ret;
|
||||
size_t extra_data_size = 0;
|
||||
uint64_t extra_data_size = 0;
|
||||
size_t extra_field_size = 0;
|
||||
size_t extra_field_id = 0;
|
||||
size_t archive_flags = 0;
|
||||
|
|
@ -2002,7 +2011,7 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
|
|||
(void) entry;
|
||||
|
||||
if(block_flags & HFL_EXTRA_DATA) {
|
||||
if(!read_var_sized(a, &extra_data_size, NULL))
|
||||
if(!read_var(a, &extra_data_size, NULL))
|
||||
return ARCHIVE_EOF;
|
||||
} else {
|
||||
extra_data_size = 0;
|
||||
|
|
@ -2229,10 +2238,12 @@ static int process_base_block(struct archive_read* a,
|
|||
/* Verify the CRC32 of the header data. */
|
||||
computed_crc = (uint32_t) crc32(0, p, (int) hdr_size);
|
||||
if(computed_crc != hdr_crc) {
|
||||
#ifndef DONT_FAIL_ON_CRC_ERROR
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Header CRC error");
|
||||
|
||||
return ARCHIVE_FATAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If the checksum is OK, we proceed with parsing. */
|
||||
|
|
@ -2453,6 +2464,8 @@ static void init_unpack(struct rar5* rar) {
|
|||
rar->cstate.filtered_buf = NULL;
|
||||
}
|
||||
|
||||
clear_data_ready_stack(rar);
|
||||
|
||||
rar->cstate.write_ptr = 0;
|
||||
rar->cstate.last_write_ptr = 0;
|
||||
|
||||
|
|
@ -2983,7 +2996,7 @@ static int decode_code_length(struct archive_read* a, struct rar5* rar,
|
|||
|
||||
static int copy_string(struct archive_read* a, int len, int dist) {
|
||||
struct rar5* rar = get_context(a);
|
||||
const uint64_t cmask = rar->cstate.window_mask;
|
||||
const ssize_t cmask = rar->cstate.window_mask;
|
||||
const uint64_t write_ptr = rar->cstate.write_ptr +
|
||||
rar->cstate.solid_offset;
|
||||
int i;
|
||||
|
|
@ -3627,6 +3640,10 @@ static int use_data(struct rar5* rar, const void** buf, size_t* size,
|
|||
return ARCHIVE_RETRY;
|
||||
}
|
||||
|
||||
static void clear_data_ready_stack(struct rar5* rar) {
|
||||
memset(&rar->cstate.dready, 0, sizeof(rar->cstate.dready));
|
||||
}
|
||||
|
||||
/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
|
||||
* FIFO stack. Those values will be popped from this stack by the `use_data`
|
||||
* function. */
|
||||
|
|
@ -4185,6 +4202,7 @@ static int rar5_cleanup(struct archive_read *a) {
|
|||
|
||||
free(rar->cstate.window_buf);
|
||||
free(rar->cstate.filtered_buf);
|
||||
clear_data_ready_stack(rar);
|
||||
|
||||
free(rar->vol.push_buf);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -416,7 +416,7 @@ static void unknowntag_end(struct xar *, const char *);
|
|||
static int xml_start(struct archive_read *,
|
||||
const char *, struct xmlattr_list *);
|
||||
static void xml_end(void *, const char *);
|
||||
static void xml_data(void *, const char *, int);
|
||||
static void xml_data(void *, const char *, size_t);
|
||||
static int xml_parse_file_flags(struct xar *, const char *);
|
||||
static int xml_parse_file_ext2(struct xar *, const char *);
|
||||
#if defined(HAVE_LIBXML_XMLREADER_H)
|
||||
|
|
@ -1242,7 +1242,7 @@ heap_add_entry(struct archive_read *a,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
new_pending_files = (struct xar_file **)
|
||||
malloc(new_size * sizeof(new_pending_files[0]));
|
||||
calloc(new_size, sizeof(new_pending_files[0]));
|
||||
if (new_pending_files == NULL) {
|
||||
archive_set_error(&a->archive,
|
||||
ENOMEM, "Out of memory");
|
||||
|
|
@ -1616,9 +1616,9 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
|
|||
switch (xar->rd_encoding) {
|
||||
case GZIP:
|
||||
xar->stream.next_in = (Bytef *)(uintptr_t)b;
|
||||
xar->stream.avail_in = avail_in;
|
||||
xar->stream.avail_in = (uInt)avail_in;
|
||||
xar->stream.next_out = (unsigned char *)outbuff;
|
||||
xar->stream.avail_out = avail_out;
|
||||
xar->stream.avail_out = (uInt)avail_out;
|
||||
r = inflate(&(xar->stream), 0);
|
||||
switch (r) {
|
||||
case Z_OK: /* Decompressor made some progress.*/
|
||||
|
|
@ -1635,9 +1635,9 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
|
|||
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
|
||||
case BZIP2:
|
||||
xar->bzstream.next_in = (char *)(uintptr_t)b;
|
||||
xar->bzstream.avail_in = avail_in;
|
||||
xar->bzstream.avail_in = (unsigned int)avail_in;
|
||||
xar->bzstream.next_out = (char *)outbuff;
|
||||
xar->bzstream.avail_out = avail_out;
|
||||
xar->bzstream.avail_out = (unsigned int)avail_out;
|
||||
r = BZ2_bzDecompress(&(xar->bzstream));
|
||||
switch (r) {
|
||||
case BZ_STREAM_END: /* Found end of stream. */
|
||||
|
|
@ -2674,7 +2674,7 @@ is_string(const char *known, const char *data, size_t len)
|
|||
}
|
||||
|
||||
static void
|
||||
xml_data(void *userData, const char *s, int len)
|
||||
xml_data(void *userData, const char *s, size_t len)
|
||||
{
|
||||
struct archive_read *a;
|
||||
struct xar *xar;
|
||||
|
|
@ -2707,6 +2707,9 @@ xml_data(void *userData, const char *s, int len)
|
|||
|
||||
switch (xar->xmlsts) {
|
||||
case FILE_NAME:
|
||||
if (xar->file->has & HAS_PATHNAME)
|
||||
break;
|
||||
|
||||
if (xar->file->parent != NULL) {
|
||||
archive_string_concat(&(xar->file->pathname),
|
||||
&(xar->file->parent->pathname));
|
||||
|
|
@ -3190,8 +3193,11 @@ xml2_read_toc(struct archive_read *a)
|
|||
if (r == ARCHIVE_OK)
|
||||
r = xml_start(a, name, &list);
|
||||
xmlattr_cleanup(&list);
|
||||
if (r != ARCHIVE_OK)
|
||||
if (r != ARCHIVE_OK) {
|
||||
xmlFreeTextReader(reader);
|
||||
xmlCleanupParser();
|
||||
return (r);
|
||||
}
|
||||
if (empty)
|
||||
xml_end(a, name);
|
||||
break;
|
||||
|
|
@ -3280,7 +3286,7 @@ expat_data_cb(void *userData, const XML_Char *s, int len)
|
|||
{
|
||||
struct expat_userData *ud = (struct expat_userData *)userData;
|
||||
|
||||
xml_data(ud->archive, s, len);
|
||||
xml_data(ud->archive, s, (size_t)len);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -3316,14 +3322,16 @@ expat_read_toc(struct archive_read *a)
|
|||
|
||||
d = NULL;
|
||||
r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
|
||||
if (r != ARCHIVE_OK)
|
||||
if (r != ARCHIVE_OK) {
|
||||
XML_ParserFree(parser);
|
||||
return (r);
|
||||
}
|
||||
xar->toc_remaining -= used;
|
||||
xar->offset += used;
|
||||
xar->toc_total += outbytes;
|
||||
PRINT_TOC(d, outbytes);
|
||||
|
||||
xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
|
||||
xr = XML_Parse(parser, d, (int)outbytes, xar->toc_remaining == 0);
|
||||
__archive_read_consume(a, used);
|
||||
if (xr == XML_STATUS_ERROR) {
|
||||
XML_ParserFree(parser);
|
||||
|
|
|
|||
|
|
@ -1924,7 +1924,7 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
zip->zipx_lzma_stream.next_in = compressed_buf;
|
||||
zip->zipx_lzma_stream.avail_in = in_bytes;
|
||||
zip->zipx_lzma_stream.total_in = 0;
|
||||
|
|
@ -1966,14 +1966,14 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
|
|||
break;
|
||||
}
|
||||
|
||||
to_consume = zip->zipx_lzma_stream.total_in;
|
||||
to_consume = (ssize_t)zip->zipx_lzma_stream.total_in;
|
||||
|
||||
__archive_read_consume(a, to_consume);
|
||||
zip->entry_bytes_remaining -= to_consume;
|
||||
zip->entry_compressed_bytes_read += to_consume;
|
||||
zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
|
||||
|
||||
*size = zip->zipx_lzma_stream.total_out;
|
||||
*size = (size_t)zip->zipx_lzma_stream.total_out;
|
||||
*buff = zip->uncompressed_buffer;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
|
|
@ -2014,7 +2014,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
|||
}
|
||||
|
||||
/* Set decompressor parameters. */
|
||||
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
|
||||
zip->zipx_lzma_stream.next_in = compressed_buf;
|
||||
zip->zipx_lzma_stream.avail_in = in_bytes;
|
||||
|
|
@ -2024,7 +2024,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
|||
/* These lzma_alone streams lack end of stream marker, so let's
|
||||
* make sure the unpacker won't try to unpack more than it's
|
||||
* supposed to. */
|
||||
zipmin((int64_t) zip->uncompressed_buffer_size,
|
||||
(size_t)zipmin((int64_t) zip->uncompressed_buffer_size,
|
||||
zip->entry->uncompressed_size -
|
||||
zip->entry_uncompressed_bytes_read);
|
||||
zip->zipx_lzma_stream.total_out = 0;
|
||||
|
|
@ -2061,7 +2061,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
to_consume = zip->zipx_lzma_stream.total_in;
|
||||
to_consume = (ssize_t)zip->zipx_lzma_stream.total_in;
|
||||
|
||||
/* Update pointers. */
|
||||
__archive_read_consume(a, to_consume);
|
||||
|
|
@ -2082,7 +2082,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
|||
}
|
||||
|
||||
/* Return values. */
|
||||
*size = zip->zipx_lzma_stream.total_out;
|
||||
*size = (size_t)zip->zipx_lzma_stream.total_out;
|
||||
*buff = zip->uncompressed_buffer;
|
||||
|
||||
/* If we're here, then we're good! */
|
||||
|
|
@ -2331,7 +2331,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
if(in_bytes < 1) {
|
||||
/* libbz2 doesn't complain when caller feeds avail_in == 0.
|
||||
* It will actually return success in this case, which is
|
||||
|
|
@ -2394,7 +2394,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
|
|||
zip->entry_uncompressed_bytes_read += total_out;
|
||||
|
||||
/* Give libarchive its due. */
|
||||
*size = total_out;
|
||||
*size = (size_t)total_out;
|
||||
*buff = zip->uncompressed_buffer;
|
||||
|
||||
return ARCHIVE_OK;
|
||||
|
|
@ -2478,7 +2478,7 @@ zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
if(in_bytes < 1) {
|
||||
/* zstd doesn't complain when caller feeds avail_in == 0.
|
||||
* It will actually return success in this case, which is
|
||||
|
|
@ -2524,7 +2524,7 @@ zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
|
|||
zip->entry_uncompressed_bytes_read += total_out;
|
||||
|
||||
/* Give libarchive its due. */
|
||||
*size = total_out;
|
||||
*size = (size_t)total_out;
|
||||
*buff = zip->uncompressed_buffer;
|
||||
|
||||
return ARCHIVE_OK;
|
||||
|
|
@ -3680,7 +3680,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset)
|
|||
if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
|
||||
return 0;
|
||||
/* Central directory can't extend beyond start of EOCD record. */
|
||||
if (cd_offset + cd_size > current_offset)
|
||||
if ((int64_t)cd_offset + cd_size > current_offset)
|
||||
return 0;
|
||||
|
||||
/* Save the central directory location for later use. */
|
||||
|
|
|
|||
|
|
@ -3874,6 +3874,30 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
|
|||
}
|
||||
|
||||
*p = NULL;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/*
|
||||
* On Windows, first try converting from WCS because (1) there's no
|
||||
* guarantee that the conversion to MBS will succeed, e.g. when using
|
||||
* CP_ACP, and (2) that's more efficient than converting to MBS, just to
|
||||
* convert back to WCS again before finally converting to UTF-8
|
||||
*/
|
||||
if ((aes->aes_set & AES_SET_WCS) != 0) {
|
||||
sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
|
||||
if (sc == NULL)
|
||||
return (-1);/* Couldn't allocate memory for sc. */
|
||||
archive_string_empty(&(aes->aes_utf8));
|
||||
r = archive_string_append_from_wcs_in_codepage(&(aes->aes_utf8),
|
||||
aes->aes_wcs.s, aes->aes_wcs.length, sc);
|
||||
if (a == NULL)
|
||||
free_sconv_object(sc);
|
||||
if (r == 0) {
|
||||
aes->aes_set |= AES_SET_UTF8;
|
||||
*p = aes->aes_utf8.s;
|
||||
return (0);/* success. */
|
||||
} else
|
||||
return (-1);/* failure. */
|
||||
}
|
||||
#endif
|
||||
/* Try converting WCS to MBS first if MBS does not exist yet. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *pm; /* unused */
|
||||
|
|
@ -3958,6 +3982,32 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
|
|||
}
|
||||
|
||||
*wp = NULL;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/*
|
||||
* On Windows, prefer converting from UTF-8 directly to WCS because:
|
||||
* (1) there's no guarantee that the string can be represented in MBS (e.g.
|
||||
* with CP_ACP), and (2) in order to convert from UTF-8 to MBS, we're going
|
||||
* to need to convert from UTF-8 to WCS anyway and its wasteful to throw
|
||||
* away that intermediate result
|
||||
*/
|
||||
if (aes->aes_set & AES_SET_UTF8) {
|
||||
struct archive_string_conv *sc;
|
||||
|
||||
sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
|
||||
if (sc != NULL) {
|
||||
archive_wstring_empty((&aes->aes_wcs));
|
||||
r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
|
||||
aes->aes_utf8.s, aes->aes_utf8.length, sc);
|
||||
if (a == NULL)
|
||||
free_sconv_object(sc);
|
||||
if (r == 0) {
|
||||
aes->aes_set |= AES_SET_WCS;
|
||||
*wp = aes->aes_wcs.s;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Try converting UTF8 to MBS first if MBS does not exist yet. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *p; /* unused */
|
||||
|
|
@ -4211,21 +4261,31 @@ archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
|
|||
|
||||
aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */
|
||||
|
||||
/* Try converting UTF-8 to MBS, return false on failure. */
|
||||
sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
|
||||
if (sc == NULL)
|
||||
return (-1);/* Couldn't allocate memory for sc. */
|
||||
r = archive_strcpy_l(&(aes->aes_mbs), utf8, sc);
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* On failure, make an effort to convert UTF8 to WCS as the active code page
|
||||
* may not be able to represent all characters in the string */
|
||||
if (r != 0) {
|
||||
if (archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
|
||||
aes->aes_utf8.s, aes->aes_utf8.length, sc) == 0)
|
||||
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS;
|
||||
}
|
||||
#endif
|
||||
/* On Windows, there's no good way to convert from UTF8 -> MBS directly, so
|
||||
* prefer to first convert to WCS as (1) it's wasteful to throw away the
|
||||
* intermediate result, and (2) WCS will still be set even if we fail to
|
||||
* convert to MBS (e.g. with ACP that can't represent the characters) */
|
||||
r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
|
||||
aes->aes_utf8.s, aes->aes_utf8.length, sc);
|
||||
|
||||
if (a == NULL)
|
||||
free_sconv_object(sc);
|
||||
if (r != 0)
|
||||
return (-1); /* This will guarantee we can't convert to MBS */
|
||||
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS; /* Both UTF8 and WCS set. */
|
||||
|
||||
/* Try converting WCS to MBS, return false on failure. */
|
||||
if (archive_string_append_from_wcs(&(aes->aes_mbs), aes->aes_wcs.s,
|
||||
aes->aes_wcs.length))
|
||||
return (-1);
|
||||
#else
|
||||
/* Try converting UTF-8 to MBS, return false on failure. */
|
||||
r = archive_strcpy_l(&(aes->aes_mbs), utf8, sc);
|
||||
|
||||
if (a == NULL)
|
||||
free_sconv_object(sc);
|
||||
|
|
@ -4237,8 +4297,10 @@ archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
|
|||
if (archive_wstring_append_from_mbs(&(aes->aes_wcs), aes->aes_mbs.s,
|
||||
aes->aes_mbs.length))
|
||||
return (-1);
|
||||
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
|
||||
#endif
|
||||
|
||||
/* All conversions succeeded. */
|
||||
aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,7 +280,8 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
|
|||
if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
|
||||
strlen(tmpdir)) < 0)
|
||||
goto exit_tmpfile;
|
||||
if (temp_name.s[temp_name.length-1] != L'/')
|
||||
if (temp_name.length == 0 ||
|
||||
temp_name.s[temp_name.length-1] != L'/')
|
||||
archive_wstrappend_wchar(&temp_name, L'/');
|
||||
}
|
||||
|
||||
|
|
@ -454,7 +455,7 @@ get_tempdir(struct archive_string *temppath)
|
|||
tmp = "/tmp";
|
||||
#endif
|
||||
archive_strcpy(temppath, tmp);
|
||||
if (temppath->s[temppath->length-1] != '/')
|
||||
if (temppath->length == 0 || temppath->s[temppath->length-1] != '/')
|
||||
archive_strappend_char(temppath, '/');
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
|
@ -477,7 +478,8 @@ __archive_mktemp(const char *tmpdir)
|
|||
goto exit_tmpfile;
|
||||
} else {
|
||||
archive_strcpy(&temp_name, tmpdir);
|
||||
if (temp_name.s[temp_name.length-1] != '/')
|
||||
if (temp_name.length == 0 ||
|
||||
temp_name.s[temp_name.length-1] != '/')
|
||||
archive_strappend_char(&temp_name, '/');
|
||||
}
|
||||
#ifdef O_TMPFILE
|
||||
|
|
@ -538,7 +540,7 @@ __archive_mktempx(const char *tmpdir, char *template)
|
|||
goto exit_tmpfile;
|
||||
} else
|
||||
archive_strcpy(&temp_name, tmpdir);
|
||||
if (temp_name.s[temp_name.length-1] == '/') {
|
||||
if (temp_name.length > 0 && temp_name.s[temp_name.length-1] == '/') {
|
||||
temp_name.s[temp_name.length-1] = '\0';
|
||||
temp_name.length --;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,12 +292,17 @@ typedef int mbstate_t;
|
|||
size_t wcrtomb(char *, wchar_t, mbstate_t *);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
#if !WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) && NTDDI_VERSION < NTDDI_WIN10_VB
|
||||
// not supported in UWP SDK before 20H1
|
||||
#define GetVolumePathNameW(f, v, c) (0)
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1300
|
||||
WINBASEAPI BOOL WINAPI GetVolumePathNameW(
|
||||
LPCWSTR lpszFileName,
|
||||
LPWSTR lpszVolumePathName,
|
||||
DWORD cchBufferLength
|
||||
);
|
||||
#endif
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
|
||||
typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
||||
LARGE_INTEGER FileOffset;
|
||||
|
|
|
|||
|
|
@ -132,12 +132,17 @@ archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
|
|||
struct archive_write *a = (struct archive_write *)_a;
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
|
||||
|
||||
if (bytes_per_block < 0) {
|
||||
// Do nothing if the bytes_per_block is negative
|
||||
return 0;
|
||||
}
|
||||
a->bytes_per_block = bytes_per_block;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current block size. -1 if it has never been set.
|
||||
* Get the current block size.
|
||||
*/
|
||||
int
|
||||
archive_write_get_bytes_per_block(struct archive *_a)
|
||||
|
|
@ -145,6 +150,10 @@ archive_write_get_bytes_per_block(struct archive *_a)
|
|||
struct archive_write *a = (struct archive_write *)_a;
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||
ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
|
||||
if (a->bytes_per_block < 0) {
|
||||
// Don't return a negative value
|
||||
return 1;
|
||||
}
|
||||
return (a->bytes_per_block);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ archive_write_add_filter_b64encode(struct archive *_a)
|
|||
struct private_b64encode *state;
|
||||
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_write_add_filter_uu");
|
||||
ARCHIVE_STATE_NEW, "archive_write_add_filter_b64encode");
|
||||
|
||||
state = (struct private_b64encode *)calloc(1, sizeof(*state));
|
||||
if (state == NULL) {
|
||||
|
|
@ -149,7 +149,7 @@ archive_filter_b64encode_open(struct archive_write_filter *f)
|
|||
size_t bs = 65536, bpb;
|
||||
|
||||
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
|
||||
/* Buffer size should be a multiple number of the of bytes
|
||||
/* Buffer size should be a multiple number of the bytes
|
||||
* per block for performance. */
|
||||
bpb = archive_write_get_bytes_per_block(f->archive);
|
||||
if (bpb > bs)
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
|
|||
if (data->compressed == NULL) {
|
||||
size_t bs = 65536, bpb;
|
||||
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
|
||||
/* Buffer size should be a multiple number of the of bytes
|
||||
/* Buffer size should be a multiple number of the bytes
|
||||
* per block for performance. */
|
||||
bpb = archive_write_get_bytes_per_block(f->archive);
|
||||
if (bpb > bs)
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ archive_compressor_compress_open(struct archive_write_filter *f)
|
|||
}
|
||||
|
||||
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
|
||||
/* Buffer size should be a multiple number of the of bytes
|
||||
/* Buffer size should be a multiple number of the bytes
|
||||
* per block for performance. */
|
||||
bpb = archive_write_get_bytes_per_block(f->archive);
|
||||
if (bpb > bs)
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ archive_compressor_xz_open(struct archive_write_filter *f)
|
|||
if (data->compressed == NULL) {
|
||||
size_t bs = 65536, bpb;
|
||||
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
|
||||
/* Buffer size should be a multiple number of the of bytes
|
||||
/* Buffer size should be a multiple number of the bytes
|
||||
* per block for performance. */
|
||||
bpb = archive_write_get_bytes_per_block(f->archive);
|
||||
if (bpb > bs)
|
||||
|
|
|
|||
|
|
@ -4196,7 +4196,7 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
|
|||
}
|
||||
for (xattr_i = 0; xattr_i < xattr_size;
|
||||
xattr_i += strlen(xattr_names + xattr_i) + 1) {
|
||||
char *xattr_val_saved;
|
||||
char *p;
|
||||
ssize_t s;
|
||||
int f;
|
||||
|
||||
|
|
@ -4207,15 +4207,14 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
|
|||
ret = ARCHIVE_WARN;
|
||||
goto exit_xattr;
|
||||
}
|
||||
xattr_val_saved = xattr_val;
|
||||
xattr_val = realloc(xattr_val, s);
|
||||
if (xattr_val == NULL) {
|
||||
p = realloc(xattr_val, s);
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Failed to get metadata(xattr)");
|
||||
ret = ARCHIVE_WARN;
|
||||
free(xattr_val_saved);
|
||||
goto exit_xattr;
|
||||
}
|
||||
xattr_val = p;
|
||||
s = fgetxattr(tmpfd, xattr_names + xattr_i, xattr_val, s, 0, 0);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
|
|
@ -4361,8 +4360,7 @@ set_mac_metadata(struct archive_write_disk *a, const char *pathname,
|
|||
* silly dance of writing the data to disk just so that
|
||||
* copyfile() can read it back in again. */
|
||||
archive_string_init(&tmp);
|
||||
archive_strcpy(&tmp, pathname);
|
||||
archive_strcat(&tmp, ".XXXXXX");
|
||||
archive_strcpy(&tmp, "tar.mmd.XXXXXX");
|
||||
fd = mkstemp(tmp.s);
|
||||
|
||||
if (fd < 0) {
|
||||
|
|
|
|||
|
|
@ -577,6 +577,9 @@ archive_write_binary_close(struct archive_write *a)
|
|||
struct archive_entry *trailer;
|
||||
|
||||
trailer = archive_entry_new2(NULL);
|
||||
if (trailer == NULL) {
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
/* nlink = 1 here for GNU cpio compat. */
|
||||
archive_entry_set_nlink(trailer, 1);
|
||||
archive_entry_set_size(trailer, 0);
|
||||
|
|
|
|||
|
|
@ -467,6 +467,9 @@ archive_write_odc_close(struct archive_write *a)
|
|||
struct archive_entry *trailer;
|
||||
|
||||
trailer = archive_entry_new2(NULL);
|
||||
if (trailer == NULL) {
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
/* nlink = 1 here for GNU cpio compat. */
|
||||
archive_entry_set_nlink(trailer, 1);
|
||||
archive_entry_set_size(trailer, 0);
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ archive_write_gnutar_header(struct archive_write *a,
|
|||
/* Only regular files (not hardlinks) have data. */
|
||||
if (archive_entry_hardlink(entry) != NULL ||
|
||||
archive_entry_symlink(entry) != NULL ||
|
||||
!(archive_entry_filetype(entry) == AE_IFREG))
|
||||
archive_entry_filetype(entry) != AE_IFREG)
|
||||
archive_entry_set_size(entry, 0);
|
||||
|
||||
if (AE_IFDIR == archive_entry_filetype(entry)) {
|
||||
|
|
@ -523,7 +523,7 @@ archive_write_gnutar_header(struct archive_write *a,
|
|||
goto exit_write_header;
|
||||
}
|
||||
|
||||
if (archive_entry_hardlink(entry) != NULL) {
|
||||
if (archive_entry_hardlink_is_set(entry)) {
|
||||
tartype = '1';
|
||||
} else
|
||||
switch (archive_entry_filetype(entry)) {
|
||||
|
|
|
|||
|
|
@ -2237,7 +2237,7 @@ set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
|
|||
int onepad;
|
||||
|
||||
if (s == NULL)
|
||||
s = "";
|
||||
s = "\0\0";
|
||||
if (l & 0x01) {
|
||||
onepad = 1;
|
||||
l &= ~1;
|
||||
|
|
|
|||
|
|
@ -608,7 +608,15 @@ archive_write_pax_header(struct archive_write *a,
|
|||
const time_t ustar_max_mtime = get_ustar_max_mtime();
|
||||
|
||||
/* Sanity check. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* NOTE: If the caller supplied a pathname that fails WCS conversion (e.g.
|
||||
* if it is invalid UTF-8), we are expected to return ARCHIVE_WARN later on
|
||||
* in execution, hence the check for both pointers */
|
||||
if ((archive_entry_pathname_w(entry_original) == NULL) &&
|
||||
(archive_entry_pathname(entry_original) == NULL)) {
|
||||
#else
|
||||
if (archive_entry_pathname(entry_original) == NULL) {
|
||||
#endif
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Can't record entry in tar file without pathname");
|
||||
return (ARCHIVE_FAILED);
|
||||
|
|
@ -1032,6 +1040,14 @@ archive_write_pax_header(struct archive_write *a,
|
|||
archive_entry_set_symlink(entry_main,
|
||||
"././@LongSymLink");
|
||||
}
|
||||
else {
|
||||
/* Otherwise, has non-ASCII characters; update the paths to
|
||||
* however they got decoded above */
|
||||
if (hardlink != NULL)
|
||||
archive_entry_set_hardlink(entry_main, linkpath);
|
||||
else
|
||||
archive_entry_set_symlink(entry_main, linkpath);
|
||||
}
|
||||
need_extension = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,6 +209,10 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
|
|||
if (archive_entry_filetype(entry) != AE_IFDIR) {
|
||||
/* Try to create the dir. */
|
||||
p = strdup(name);
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
pp = strrchr(p, '/');
|
||||
/* If there is a / character, try to create the dir. */
|
||||
if (pp != NULL) {
|
||||
|
|
@ -291,6 +295,10 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
|
|||
free(shar->last_dir);
|
||||
|
||||
shar->last_dir = strdup(name);
|
||||
if (shar->last_dir == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
/* Trim a trailing '/'. */
|
||||
pp = strrchr(shar->last_dir, '/');
|
||||
if (pp != NULL && pp[1] == '\0')
|
||||
|
|
|
|||
|
|
@ -254,7 +254,11 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
|
|||
sconv = ustar->opt_sconv;
|
||||
|
||||
/* Sanity check. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if (archive_entry_pathname_w(entry) == NULL) {
|
||||
#else
|
||||
if (archive_entry_pathname(entry) == NULL) {
|
||||
#endif
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Can't record entry in tar file without pathname");
|
||||
return (ARCHIVE_FAILED);
|
||||
|
|
@ -263,7 +267,7 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
|
|||
/* Only regular files (not hardlinks) have data. */
|
||||
if (archive_entry_hardlink(entry) != NULL ||
|
||||
archive_entry_symlink(entry) != NULL ||
|
||||
!(archive_entry_filetype(entry) == AE_IFREG))
|
||||
archive_entry_filetype(entry) != AE_IFREG)
|
||||
archive_entry_set_size(entry, 0);
|
||||
|
||||
if (AE_IFDIR == archive_entry_filetype(entry)) {
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ archive_write_v7tar_header(struct archive_write *a, struct archive_entry *entry)
|
|||
/* Only regular files (not hardlinks) have data. */
|
||||
if (archive_entry_hardlink(entry) != NULL ||
|
||||
archive_entry_symlink(entry) != NULL ||
|
||||
!(archive_entry_filetype(entry) == AE_IFREG))
|
||||
archive_entry_filetype(entry) != AE_IFREG)
|
||||
archive_entry_set_size(entry, 0);
|
||||
|
||||
if (AE_IFDIR == archive_entry_filetype(entry)) {
|
||||
|
|
|
|||
|
|
@ -796,7 +796,7 @@ xar_finish_entry(struct archive_write *a)
|
|||
if (w > 0)
|
||||
xar->bytes_remaining -= w;
|
||||
else
|
||||
return (w);
|
||||
return ((int)w);
|
||||
}
|
||||
file = xar->cur_file;
|
||||
checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
|
||||
|
|
@ -1163,7 +1163,7 @@ make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
|
|||
/*
|
||||
* Make a file name entry, "<name>".
|
||||
*/
|
||||
l = ll = archive_strlen(&(file->basename));
|
||||
l = ll = (int)archive_strlen(&(file->basename));
|
||||
tmp = malloc(l);
|
||||
if (tmp == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
|
|
@ -1189,7 +1189,7 @@ make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
|
|||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
r = xmlTextWriterWriteBase64(writer, file->basename.s,
|
||||
0, archive_strlen(&(file->basename)));
|
||||
0, (int)archive_strlen(&(file->basename)));
|
||||
if (r < 0) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
|
|
@ -2231,10 +2231,10 @@ get_path_component(char *name, int n, const char *fn)
|
|||
|
||||
p = strchr(fn, '/');
|
||||
if (p == NULL) {
|
||||
if ((l = strlen(fn)) == 0)
|
||||
if ((l = (int)strlen(fn)) == 0)
|
||||
return (0);
|
||||
} else
|
||||
l = p - fn;
|
||||
l = (int)(p - fn);
|
||||
if (l > n -1)
|
||||
return (-1);
|
||||
memcpy(name, fn, l);
|
||||
|
|
@ -2651,10 +2651,10 @@ compression_init_encoder_gzip(struct archive *a,
|
|||
* of ugly hackery to convert a const * pointer to
|
||||
* a non-const pointer. */
|
||||
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
|
||||
strm->avail_in = lastrm->avail_in;
|
||||
strm->avail_in = (uInt)lastrm->avail_in;
|
||||
strm->total_in = (uLong)lastrm->total_in;
|
||||
strm->next_out = lastrm->next_out;
|
||||
strm->avail_out = lastrm->avail_out;
|
||||
strm->avail_out = (uInt)lastrm->avail_out;
|
||||
strm->total_out = (uLong)lastrm->total_out;
|
||||
if (deflateInit2(strm, level, Z_DEFLATED,
|
||||
(withheader)?15:-15,
|
||||
|
|
@ -2684,10 +2684,10 @@ compression_code_gzip(struct archive *a,
|
|||
* of ugly hackery to convert a const * pointer to
|
||||
* a non-const pointer. */
|
||||
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
|
||||
strm->avail_in = lastrm->avail_in;
|
||||
strm->avail_in = (uInt)lastrm->avail_in;
|
||||
strm->total_in = (uLong)lastrm->total_in;
|
||||
strm->next_out = lastrm->next_out;
|
||||
strm->avail_out = lastrm->avail_out;
|
||||
strm->avail_out = (uInt)lastrm->avail_out;
|
||||
strm->total_out = (uLong)lastrm->total_out;
|
||||
r = deflate(strm,
|
||||
(action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
|
||||
|
|
@ -2748,11 +2748,11 @@ compression_init_encoder_bzip2(struct archive *a,
|
|||
* of ugly hackery to convert a const * pointer to
|
||||
* a non-const pointer. */
|
||||
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
|
||||
strm->avail_in = lastrm->avail_in;
|
||||
strm->avail_in = (unsigned int)lastrm->avail_in;
|
||||
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
|
||||
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
|
||||
strm->next_out = (char *)lastrm->next_out;
|
||||
strm->avail_out = lastrm->avail_out;
|
||||
strm->avail_out = (unsigned int)lastrm->avail_out;
|
||||
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
|
||||
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
|
||||
if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
|
||||
|
|
@ -2781,11 +2781,11 @@ compression_code_bzip2(struct archive *a,
|
|||
* of ugly hackery to convert a const * pointer to
|
||||
* a non-const pointer. */
|
||||
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
|
||||
strm->avail_in = lastrm->avail_in;
|
||||
strm->avail_in = (unsigned int)lastrm->avail_in;
|
||||
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
|
||||
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
|
||||
strm->next_out = (char *)lastrm->next_out;
|
||||
strm->avail_out = lastrm->avail_out;
|
||||
strm->avail_out = (unsigned int)lastrm->avail_out;
|
||||
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
|
||||
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
|
||||
r = BZ2_bzCompress(strm,
|
||||
|
|
|
|||
|
|
@ -609,7 +609,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
|||
const char *p;
|
||||
size_t len;
|
||||
|
||||
if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
|
||||
if (archive_entry_pathname_l(zip->entry, &p, &len, sconv) != 0) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Pathname");
|
||||
|
|
@ -618,7 +618,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
|||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Can't translate Pathname '%s' to %s",
|
||||
archive_entry_pathname(entry),
|
||||
archive_entry_pathname(zip->entry),
|
||||
archive_string_conversion_charset_name(sconv));
|
||||
ret2 = ARCHIVE_WARN;
|
||||
}
|
||||
|
|
@ -631,7 +631,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
|||
* for filename.
|
||||
*/
|
||||
if (type == AE_IFLNK) {
|
||||
if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
|
||||
if (archive_entry_symlink_l(zip->entry, &p, &len, sconv)) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory "
|
||||
|
|
@ -906,7 +906,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
|||
archive_le32enc(e, (uint32_t)archive_entry_ctime(entry));
|
||||
e += 4;
|
||||
}
|
||||
archive_le16enc(ut + 2, e - ut - 4);
|
||||
archive_le16enc(ut + 2, (uint16_t)(e - ut - 4));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -203,7 +203,6 @@
|
|||
#define HAVE_SYS_MOUNT_H 1
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
#define HAVE_SYS_POLL_H 1
|
||||
#define HAVE_SYS_QUEUE_H 1
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
#define HAVE_SYS_STATVFS_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ IF(ENABLE_TEST)
|
|||
test_acl_platform_posix1e.c
|
||||
test_acl_posix1e.c
|
||||
test_acl_text.c
|
||||
test_ar_mode.c
|
||||
test_archive_api_feature.c
|
||||
test_archive_clear_error.c
|
||||
test_archive_cmdline.c
|
||||
|
|
@ -24,6 +25,7 @@ IF(ENABLE_TEST)
|
|||
test_archive_match_path.c
|
||||
test_archive_match_time.c
|
||||
test_archive_pathmatch.c
|
||||
test_archive_read.c
|
||||
test_archive_read_add_passphrase.c
|
||||
test_archive_read_close_twice.c
|
||||
test_archive_read_close_twice_open_fd.c
|
||||
|
|
@ -130,6 +132,7 @@ IF(ENABLE_TEST)
|
|||
test_read_format_gtar_lzma.c
|
||||
test_read_format_gtar_sparse.c
|
||||
test_read_format_gtar_sparse_skip_entry.c
|
||||
test_read_format_huge_rpm.c
|
||||
test_read_format_iso_Z.c
|
||||
test_read_format_iso_multi_extent.c
|
||||
test_read_format_iso_xorriso.c
|
||||
|
|
@ -164,6 +167,7 @@ IF(ENABLE_TEST)
|
|||
test_read_format_tar_empty_pax.c
|
||||
test_read_format_tar_filename.c
|
||||
test_read_format_tar_invalid_pax_size.c
|
||||
test_read_format_tar_pax_large_attr.c
|
||||
test_read_format_tbz.c
|
||||
test_read_format_tgz.c
|
||||
test_read_format_tlz.c
|
||||
|
|
@ -287,6 +291,7 @@ IF(ENABLE_TEST)
|
|||
test_write_format_zip_file_zip64.c
|
||||
test_write_format_zip_large.c
|
||||
test_write_format_zip_stream.c
|
||||
test_write_format_zip_windows_path.c
|
||||
test_write_format_zip_zip64.c
|
||||
test_write_open_memory.c
|
||||
test_write_read_format_zip.c
|
||||
|
|
|
|||
40
libarchive/test/test_ar_mode.c
Normal file
40
libarchive/test/test_ar_mode.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*-SPDX-License-Identifier: BSD-2-Clause
|
||||
* Copyright (C) 2024 by наб <nabijaczleweli@nabijaczleweli.xyz>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
static const char data[] = "!<arch>\narchivemount.1/ 0 0 0 644 0 `\n";
|
||||
|
||||
|
||||
DEFINE_TEST(test_ar_mode)
|
||||
{
|
||||
struct archive * ar = archive_read_new();
|
||||
assertEqualInt(archive_read_support_format_all(ar), ARCHIVE_OK);
|
||||
assertEqualInt(archive_read_open_memory(ar, data, sizeof(data) - 1), ARCHIVE_OK);
|
||||
|
||||
struct archive_entry * entry;
|
||||
assertEqualIntA(ar, archive_read_next_header(ar, &entry), ARCHIVE_OK);
|
||||
assertEqualIntA(ar, archive_entry_mode(entry), S_IFREG | 0644);
|
||||
|
||||
archive_read_free(ar);
|
||||
}
|
||||
|
|
@ -316,15 +316,14 @@ test_newer_mtime_than_file_mbs(void)
|
|||
static void
|
||||
test_newer_ctime_than_file_mbs(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct archive *m;
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!assert((m = archive_match_new()) != NULL))
|
||||
return;
|
||||
if (!assert((ae = archive_entry_new()) != NULL)) {
|
||||
|
|
@ -373,6 +372,7 @@ test_newer_ctime_than_file_mbs(void)
|
|||
archive_read_free(a);
|
||||
archive_entry_free(ae);
|
||||
archive_match_free(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -435,15 +435,14 @@ test_newer_mtime_than_file_wcs(void)
|
|||
static void
|
||||
test_newer_ctime_than_file_wcs(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct archive *m;
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!assert((m = archive_match_new()) != NULL))
|
||||
return;
|
||||
if (!assert((ae = archive_entry_new()) != NULL)) {
|
||||
|
|
@ -493,6 +492,7 @@ test_newer_ctime_than_file_wcs(void)
|
|||
archive_read_free(a);
|
||||
archive_entry_free(ae);
|
||||
archive_match_free(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -787,15 +787,14 @@ test_older_mtime_than_file_mbs(void)
|
|||
static void
|
||||
test_older_ctime_than_file_mbs(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct archive *m;
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!assert((m = archive_match_new()) != NULL))
|
||||
return;
|
||||
if (!assert((ae = archive_entry_new()) != NULL)) {
|
||||
|
|
@ -845,6 +844,7 @@ test_older_ctime_than_file_mbs(void)
|
|||
archive_read_free(a);
|
||||
archive_entry_free(ae);
|
||||
archive_match_free(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -907,15 +907,14 @@ test_older_mtime_than_file_wcs(void)
|
|||
static void
|
||||
test_older_ctime_than_file_wcs(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct archive *m;
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!assert((m = archive_match_new()) != NULL))
|
||||
return;
|
||||
if (!assert((ae = archive_entry_new()) != NULL)) {
|
||||
|
|
@ -965,6 +964,7 @@ test_older_ctime_than_file_wcs(void)
|
|||
archive_read_free(a);
|
||||
archive_entry_free(ae);
|
||||
archive_match_free(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1088,15 +1088,14 @@ test_mtime_between_files_wcs(void)
|
|||
static void
|
||||
test_ctime_between_files_mbs(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct archive *m;
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!assert((m = archive_match_new()) != NULL))
|
||||
return;
|
||||
if (!assert((ae = archive_entry_new()) != NULL)) {
|
||||
|
|
@ -1147,20 +1146,20 @@ test_ctime_between_files_mbs(void)
|
|||
archive_read_free(a);
|
||||
archive_entry_free(ae);
|
||||
archive_match_free(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
test_ctime_between_files_wcs(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
struct archive *m;
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
skipping("Can't set ctime on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!assert((m = archive_match_new()) != NULL))
|
||||
return;
|
||||
if (!assert((ae = archive_entry_new()) != NULL)) {
|
||||
|
|
@ -1211,6 +1210,7 @@ test_ctime_between_files_wcs(void)
|
|||
archive_read_free(a);
|
||||
archive_entry_free(ae);
|
||||
archive_match_free(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
63
libarchive/test/test_archive_read.c
Normal file
63
libarchive/test/test_archive_read.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*-
|
||||
* Copyright (c) 2024 Tobias Stoeckmann
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#define __LIBARCHIVE_TEST
|
||||
#include "archive_read_private.h"
|
||||
|
||||
static char buf[1024];
|
||||
|
||||
DEFINE_TEST(test_archive_read_ahead_eof)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_read *ar;
|
||||
ssize_t avail;
|
||||
|
||||
/* prepare a reader of raw in-memory data */
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
ar = (struct archive_read *)a;
|
||||
|
||||
assertA(0 == archive_read_support_format_raw(a));
|
||||
assertA(0 == archive_read_open_memory(a, buf, sizeof(buf)));
|
||||
|
||||
/* perform a read which can be fulfilled */
|
||||
assert(NULL != __archive_read_ahead(ar, sizeof(buf) - 1, &avail));
|
||||
assertEqualInt(sizeof(buf), avail);
|
||||
|
||||
/* perform a read which cannot be fulfilled due to EOF */
|
||||
assert(NULL == __archive_read_ahead(ar, sizeof(buf) + 1, &avail));
|
||||
assertEqualInt(sizeof(buf), avail);
|
||||
|
||||
/* perform the same read again */
|
||||
assert(NULL == __archive_read_ahead(ar, sizeof(buf) + 1, &avail));
|
||||
assertEqualInt(sizeof(buf), avail);
|
||||
|
||||
/* perform another read which can be fulfilled */
|
||||
assert(NULL != __archive_read_ahead(ar, sizeof(buf), &avail));
|
||||
assertEqualInt(sizeof(buf), avail);
|
||||
|
||||
assert(0 == archive_read_free(a));
|
||||
}
|
||||
|
|
@ -882,3 +882,138 @@ DEFINE_TEST(test_archive_string_conversion)
|
|||
test_archive_string_canonicalization();
|
||||
test_archive_string_set_get();
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string_conversion_utf16_utf8)
|
||||
{
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
skipping("This test is meant to verify unicode string handling on Windows");
|
||||
#else
|
||||
struct archive_mstring mstr;
|
||||
const char* utf8_string;
|
||||
|
||||
memset(&mstr, 0, sizeof(mstr));
|
||||
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_mstring_copy_wcs(&mstr, L"\U0000043f\U00000440\U00000438"));
|
||||
|
||||
/* Conversion from WCS to UTF-8 should always succeed */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_mstring_get_utf8(NULL, &mstr, &utf8_string));
|
||||
assertEqualString("\xD0\xBF\xD1\x80\xD0\xB8", utf8_string);
|
||||
|
||||
archive_mstring_clean(&mstr);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string_conversion_utf8_utf16)
|
||||
{
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
skipping("This test is meant to verify unicode string handling on Windows");
|
||||
#else
|
||||
struct archive_mstring mstr;
|
||||
const wchar_t* wcs_string;
|
||||
|
||||
memset(&mstr, 0, sizeof(mstr));
|
||||
|
||||
assertEqualInt(6,
|
||||
archive_mstring_copy_utf8(&mstr, "\xD0\xBF\xD1\x80\xD0\xB8"));
|
||||
|
||||
/* Conversion from UTF-8 to WCS should always succeed */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_mstring_get_wcs(NULL, &mstr, &wcs_string));
|
||||
assertEqualWString(L"\U0000043f\U00000440\U00000438", wcs_string);
|
||||
|
||||
archive_mstring_clean(&mstr);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string_update_utf8_win)
|
||||
{
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
skipping("This test is meant to verify unicode string handling on Windows"
|
||||
" with the C locale");
|
||||
#else
|
||||
static const char utf8_string[] = "\xD0\xBF\xD1\x80\xD0\xB8";
|
||||
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
|
||||
struct archive_mstring mstr;
|
||||
int r;
|
||||
|
||||
memset(&mstr, 0, sizeof(mstr));
|
||||
|
||||
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
|
||||
|
||||
/* On Windows, this should reliably fail with the C locale */
|
||||
assertEqualInt(-1, r);
|
||||
assertEqualInt(0, mstr.aes_set & AES_SET_MBS);
|
||||
|
||||
/* NOTE: We access the internals to validate that they were set by the
|
||||
* 'archive_mstring_update_utf8' function */
|
||||
/* UTF-8 should always be set */
|
||||
assertEqualInt(AES_SET_UTF8, mstr.aes_set & AES_SET_UTF8);
|
||||
assertEqualString(utf8_string, mstr.aes_utf8.s);
|
||||
/* WCS should always be set as well */
|
||||
assertEqualInt(AES_SET_WCS, mstr.aes_set & AES_SET_WCS);
|
||||
assertEqualWString(wcs_string, mstr.aes_wcs.s);
|
||||
|
||||
archive_mstring_clean(&mstr);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string_update_utf8_utf8)
|
||||
{
|
||||
static const char utf8_string[] = "\xD0\xBF\xD1\x80\xD0\xB8";
|
||||
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
|
||||
struct archive_mstring mstr;
|
||||
int r;
|
||||
|
||||
memset(&mstr, 0, sizeof(mstr));
|
||||
|
||||
if (setlocale(LC_ALL, "en_US.UTF-8") == NULL) {
|
||||
skipping("UTF-8 not supported on this system.");
|
||||
return;
|
||||
}
|
||||
|
||||
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
|
||||
|
||||
/* All conversions should have succeeded */
|
||||
assertEqualInt(0, r);
|
||||
assertEqualInt(AES_SET_MBS | AES_SET_WCS | AES_SET_UTF8, mstr.aes_set);
|
||||
assertEqualString(utf8_string, mstr.aes_utf8.s);
|
||||
assertEqualString(utf8_string, mstr.aes_mbs.s);
|
||||
assertEqualWString(wcs_string, mstr.aes_wcs.s);
|
||||
|
||||
archive_mstring_clean(&mstr);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string_update_utf8_koi8)
|
||||
{
|
||||
static const char utf8_string[] = "\xD0\xBF\xD1\x80\xD0\xB8";
|
||||
static const char koi8_string[] = "\xD0\xD2\xC9";
|
||||
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
|
||||
struct archive_mstring mstr;
|
||||
int r;
|
||||
|
||||
memset(&mstr, 0, sizeof(mstr));
|
||||
|
||||
if (setlocale(LC_ALL, "ru_RU.KOI8-R") == NULL) {
|
||||
skipping("KOI8-R locale not available on this system.");
|
||||
return;
|
||||
}
|
||||
|
||||
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
|
||||
|
||||
/* All conversions should have succeeded */
|
||||
assertEqualInt(0, r);
|
||||
assertEqualInt(AES_SET_MBS | AES_SET_WCS | AES_SET_UTF8, mstr.aes_set);
|
||||
assertEqualString(utf8_string, mstr.aes_utf8.s);
|
||||
assertEqualString(koi8_string, mstr.aes_mbs.s);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualWString(wcs_string, mstr.aes_wcs.s);
|
||||
#else
|
||||
/* No guarantee of how WCS strings behave, however this test test is
|
||||
* primarily meant for Windows */
|
||||
(void)wcs_string;
|
||||
#endif
|
||||
|
||||
archive_mstring_clean(&mstr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ echo "f3" > $dir/d1/f3
|
|||
rm -r $dir
|
||||
}
|
||||
#
|
||||
# Make a lzip file from splitted tar file.
|
||||
# Make a lzip file from split tar file.
|
||||
#
|
||||
name=test_compat_lzip_1
|
||||
dir="$name`date +%Y%m%d%H%M%S`.$USER"
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ test_compat_solaris_pax_sparse_1(void)
|
|||
assertEqualInt(0100644, archive_entry_mode(ae));
|
||||
|
||||
/* Verify the sparse information. */
|
||||
failure("This sparse file should have tree data blocks");
|
||||
failure("This sparse file should have three data blocks");
|
||||
assertEqualInt(3, archive_entry_sparse_reset(ae));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_sparse_next(ae, &offset, &length));
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ DEFINE_TEST(test_entry)
|
|||
archive_entry_set_hardlink(e, "hardlink");
|
||||
archive_entry_set_symlink(e, "symlink");
|
||||
archive_entry_set_link(e, "link");
|
||||
assertEqualString(archive_entry_hardlink(e), "hardlink");
|
||||
assertEqualString(archive_entry_hardlink(e), NULL);
|
||||
assertEqualString(archive_entry_symlink(e), "link");
|
||||
|
||||
/* mode */
|
||||
|
|
@ -513,7 +513,6 @@ DEFINE_TEST(test_entry)
|
|||
archive_entry_set_rdev(e, 532);
|
||||
archive_entry_set_size(e, 987654321);
|
||||
archive_entry_copy_sourcepath(e, "source");
|
||||
archive_entry_set_symlink(e, "symlinkname");
|
||||
archive_entry_set_uid(e, 83);
|
||||
archive_entry_set_uname(e, "user");
|
||||
/* Add an ACL entry. */
|
||||
|
|
@ -548,7 +547,7 @@ DEFINE_TEST(test_entry)
|
|||
assertEqualInt(archive_entry_rdev(e2), 532);
|
||||
assertEqualInt(archive_entry_size(e2), 987654321);
|
||||
assertEqualString(archive_entry_sourcepath(e2), "source");
|
||||
assertEqualString(archive_entry_symlink(e2), "symlinkname");
|
||||
assertEqualString(archive_entry_symlink(e2), NULL);
|
||||
assertEqualInt(archive_entry_uid(e2), 83);
|
||||
assertEqualString(archive_entry_uname(e2), "user");
|
||||
|
||||
|
|
@ -649,7 +648,7 @@ DEFINE_TEST(test_entry)
|
|||
assertEqualInt(archive_entry_rdev(e2), 532);
|
||||
assertEqualInt(archive_entry_size(e2), 987654321);
|
||||
assertEqualString(archive_entry_sourcepath(e2), "source");
|
||||
assertEqualString(archive_entry_symlink(e2), "symlinkname");
|
||||
assertEqualString(archive_entry_symlink(e2), NULL);
|
||||
assertEqualInt(archive_entry_uid(e2), 83);
|
||||
assertEqualString(archive_entry_uname(e2), "user");
|
||||
|
||||
|
|
@ -705,6 +704,13 @@ DEFINE_TEST(test_entry)
|
|||
/* Release clone. */
|
||||
archive_entry_free(e2);
|
||||
|
||||
/* Verify that symlink is copied over by `clone` */
|
||||
archive_entry_set_symlink(e, "symlinkpath");
|
||||
e2 = archive_entry_clone(e);
|
||||
assertEqualString(archive_entry_hardlink(e2), NULL);
|
||||
assertEqualString(archive_entry_symlink(e2), "symlinkpath");
|
||||
archive_entry_free(e2);
|
||||
|
||||
/*
|
||||
* Test clear() implementation.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -389,3 +389,105 @@ DEFINE_TEST(test_gnutar_filename_encoding_CP932_UTF8)
|
|||
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_gnutar_filename_encoding_UTF16_win)
|
||||
{
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
skipping("This test is meant to verify unicode string handling"
|
||||
" on Windows with UTF-16 names");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *entry;
|
||||
char buff[4096];
|
||||
size_t used;
|
||||
|
||||
/*
|
||||
* Don't call setlocale because we're verifying that the '_w' functions
|
||||
* work as expected when 'hdrcharset' is UTF-8
|
||||
*/
|
||||
|
||||
/* Part 1: file */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
|
||||
if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
|
||||
skipping("This system cannot convert character-set"
|
||||
" from UTF-16 to UTF-8.");
|
||||
archive_write_free(a);
|
||||
return;
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the filename using a UTF-16 string */
|
||||
archive_entry_copy_pathname_w(entry, L"\u8868.txt");
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
|
||||
|
||||
/* Part 2: directory */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the directory name using a UTF-16 string */
|
||||
/* NOTE: Explicitly not adding trailing slash to test that code path */
|
||||
archive_entry_copy_pathname_w(entry, L"\u8868");
|
||||
archive_entry_set_filetype(entry, AE_IFDIR);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff, "\xE8\xA1\xA8/", 4);
|
||||
|
||||
/* Part 3: symlink */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the symlink target using a UTF-16 string */
|
||||
archive_entry_set_pathname(entry, "link.txt");
|
||||
archive_entry_copy_symlink_w(entry, L"\u8868.txt");
|
||||
archive_entry_set_filetype(entry, AE_IFLNK);
|
||||
archive_entry_set_symlink_type(entry, AE_SYMLINK_TYPE_FILE);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
|
||||
|
||||
/* Part 4: hardlink */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the symlink target using a UTF-16 string */
|
||||
archive_entry_set_pathname(entry, "link.txt");
|
||||
archive_entry_copy_hardlink_w(entry, L"\u8868.txt");
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,3 +202,48 @@ DEFINE_TEST(test_link_resolver)
|
|||
test_linkify_old_cpio();
|
||||
test_linkify_new_cpio();
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_link_resolver_unicode_win)
|
||||
{
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
skipping("This test is meant to verify unicode string handling"
|
||||
" on Windows with UTF-16 names");
|
||||
return;
|
||||
#else
|
||||
struct archive_entry *entry, *e2;
|
||||
struct archive_entry_linkresolver *resolver;
|
||||
|
||||
/* Initialize the resolver. */
|
||||
assert(NULL != (resolver = archive_entry_linkresolver_new()));
|
||||
archive_entry_linkresolver_set_strategy(resolver,
|
||||
ARCHIVE_FORMAT_TAR_USTAR);
|
||||
|
||||
/* Create an entry with a unicode filename and 2 links. */
|
||||
assert(NULL != (entry = archive_entry_new()));
|
||||
archive_entry_copy_pathname_w(entry, L"\u4f60\u597d.txt");
|
||||
archive_entry_set_ino(entry, 1);
|
||||
archive_entry_set_dev(entry, 2);
|
||||
archive_entry_set_nlink(entry, 2);
|
||||
archive_entry_set_size(entry, 10);
|
||||
archive_entry_linkify(resolver, &entry, &e2);
|
||||
|
||||
/* Shouldn't be altered, since it wasn't seen before. */
|
||||
assert(e2 == NULL);
|
||||
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_pathname_w(entry));
|
||||
assertEqualWString(NULL, archive_entry_hardlink_w(entry));
|
||||
assertEqualInt(10, archive_entry_size(entry));
|
||||
|
||||
/* Link to the same file contents, but a new unicode name. */
|
||||
archive_entry_copy_pathname_w(entry, L"\u518d\u89c1.txt");
|
||||
archive_entry_linkify(resolver, &entry, &e2);
|
||||
|
||||
/* Size & link path should have changed. */
|
||||
assert(e2 == NULL);
|
||||
assertEqualWString(L"\u518d\u89c1.txt", archive_entry_pathname_w(entry));
|
||||
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_hardlink_w(entry));
|
||||
assertEqualInt(0, archive_entry_size(entry));
|
||||
|
||||
archive_entry_free(entry);
|
||||
archive_entry_linkresolver_free(resolver);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -579,6 +579,158 @@ DEFINE_TEST(test_pax_filename_encoding_KOI8R_CP1251)
|
|||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that unicode filenames are correctly preserved on Windows
|
||||
*/
|
||||
DEFINE_TEST(test_pax_filename_encoding_UTF16_win)
|
||||
{
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
skipping("This test is meant to verify unicode string handling"
|
||||
" on Windows with UTF-16 names");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *entry;
|
||||
char buff[0x2000];
|
||||
char *p;
|
||||
size_t used;
|
||||
|
||||
/*
|
||||
* Don't call setlocale because we're verifying that the '_w' functions
|
||||
* work as expected when 'hdrcharset' is UTF-8
|
||||
*/
|
||||
|
||||
/* Check if the platform completely supports the string conversion. */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
|
||||
if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
|
||||
skipping("This system cannot convert character-set"
|
||||
" from UTF-16 to UTF-8.");
|
||||
archive_write_free(a);
|
||||
return;
|
||||
}
|
||||
archive_write_free(a);
|
||||
|
||||
/*
|
||||
* Create a new archive handle with default charset handling
|
||||
*/
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
/* Part 1: file */
|
||||
entry = archive_entry_new2(a);
|
||||
archive_entry_copy_pathname_w(entry, L"\u4f60\u597d.txt");
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
|
||||
/* Part 2: directory */
|
||||
/* NOTE: Explicitly not adding trailing slash to test that code path */
|
||||
archive_entry_copy_pathname_w(entry, L"\u043f\u0440\u0438");
|
||||
archive_entry_set_filetype(entry, AE_IFDIR);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
|
||||
/* Part 3: symlink */
|
||||
archive_entry_copy_pathname_w(entry, L"\u518d\u89c1.txt");
|
||||
archive_entry_copy_symlink_w(entry, L"\u4f60\u597d.txt");
|
||||
archive_entry_set_filetype(entry, AE_IFLNK);
|
||||
archive_entry_set_symlink_type(entry, AE_SYMLINK_TYPE_FILE);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
|
||||
/* Part 4: hardlink */
|
||||
archive_entry_copy_pathname_w(entry, L"\u665a\u5b89.txt");
|
||||
archive_entry_copy_hardlink_w(entry, L"\u4f60\u597d.txt");
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/*
|
||||
* Examine the bytes to ensure the filenames ended up UTF-8
|
||||
* encoded as we expect.
|
||||
*/
|
||||
|
||||
/* Part 1: file */
|
||||
p = buff + 0;
|
||||
assertEqualString(p + 0, "PaxHeader/\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* File name */
|
||||
assertEqualInt(p[156], 'x'); /* Pax extension header */
|
||||
p += 512; /* Pax extension body */
|
||||
assertEqualString(p + 0, "19 path=\xE4\xBD\xA0\xE5\xA5\xBD.txt\n");
|
||||
p += 512; /* Ustar header */
|
||||
assertEqualString(p + 0, "\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* File name */
|
||||
assertEqualInt(p[156], '0');
|
||||
|
||||
/* Part 2: directory */
|
||||
p += 512; /* Pax extension header */
|
||||
assertEqualString(p + 0, "PaxHeader/\xD0\xBF\xD1\x80\xD0\xB8"); /* File name */
|
||||
assertEqualInt(p[156], 'x');
|
||||
p += 512; /* Pax extension body */
|
||||
assertEqualString(p + 0, "16 path=\xD0\xBF\xD1\x80\xD0\xB8/\n");
|
||||
p += 512; /* Ustar header */
|
||||
assertEqualString(p + 0, "\xD0\xBF\xD1\x80\xD0\xB8/"); /* File name */
|
||||
assertEqualInt(p[156], '5'); /* directory */
|
||||
|
||||
/* Part 3: symlink */
|
||||
p += 512; /* Pax Extension Header */
|
||||
assertEqualString(p + 0, "PaxHeader/\xE5\x86\x8D\xE8\xA7\x81.txt"); /* File name */
|
||||
p += 512; /* Pax extension body */
|
||||
assertEqualString(p + 0,
|
||||
"19 path=\xE5\x86\x8D\xE8\xA7\x81.txt\n"
|
||||
"23 linkpath=\xE4\xBD\xA0\xE5\xA5\xBD.txt\n"
|
||||
"31 LIBARCHIVE.symlinktype=file\n");
|
||||
p += 512; /* Ustar header */
|
||||
assertEqualString(p + 0, "\xE5\x86\x8D\xE8\xA7\x81.txt"); /* File name */
|
||||
assertEqualInt(p[156], '2'); /* symlink */
|
||||
assertEqualString(p + 157, "\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* link name */
|
||||
|
||||
/* Part 4: hardlink */
|
||||
p += 512; /* Pax extension header */
|
||||
assertEqualString(p + 0, "PaxHeader/\xE6\x99\x9A\xE5\xAE\x89.txt"); /* File name */
|
||||
p += 512; /* Pax extension body */
|
||||
assertEqualString(p + 0,
|
||||
"19 path=\xE6\x99\x9A\xE5\xAE\x89.txt\n"
|
||||
"23 linkpath=\xE4\xBD\xA0\xE5\xA5\xBD.txt\n"
|
||||
"31 LIBARCHIVE.symlinktype=file\n");
|
||||
p += 512; /* Ustar header */
|
||||
assertEqualString(p + 0, "\xE6\x99\x9A\xE5\xAE\x89.txt"); /* File name */
|
||||
assertEqualInt(p[156], '1'); /* hard link */
|
||||
assertEqualString(p + 157, "\xE4\xBD\xA0\xE5\xA5\xBD.txt"); /* link name */
|
||||
|
||||
/*
|
||||
* Read back the archive to see if we get the original names
|
||||
*/
|
||||
a = archive_read_new();
|
||||
archive_read_support_format_all(a);
|
||||
archive_read_support_filter_all(a);
|
||||
assertEqualInt(0, archive_read_open_memory(a, buff, used));
|
||||
|
||||
/* Read part 1: file */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
|
||||
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_pathname_w(entry));
|
||||
|
||||
/* Read part 2: directory */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
|
||||
assertEqualWString(L"\u043f\u0440\u0438/", archive_entry_pathname_w(entry));
|
||||
|
||||
/* Read part 3: symlink */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
|
||||
assertEqualWString(L"\u518d\u89c1.txt", archive_entry_pathname_w(entry));
|
||||
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_symlink_w(entry));
|
||||
|
||||
/* Read part 4: hardlink */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));
|
||||
assertEqualWString(L"\u665a\u5b89.txt", archive_entry_pathname_w(entry));
|
||||
assertEqualWString(L"\u4f60\u597d.txt", archive_entry_hardlink_w(entry));
|
||||
|
||||
archive_free(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_pax_filename_encoding)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,7 @@ test_arm_filter(const char *refname)
|
|||
|
||||
extract_reference_file(refname);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
|
|
@ -1123,6 +1124,7 @@ test_arm64_filter(const char *refname)
|
|||
|
||||
extract_reference_file(refname);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
|
|
@ -1255,5 +1257,47 @@ DEFINE_TEST(test_read_format_7zip_win_attrib)
|
|||
assertEqualString("system", archive_entry_fflags_text(ae));
|
||||
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_7zip_extract_second)
|
||||
{
|
||||
struct archive *a;
|
||||
char buffer[256];
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping(
|
||||
"7zip:lzma decoding is not supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
|
||||
/*
|
||||
* The test archive has two files: first.txt which is a 65,536 file (the
|
||||
* size of the uncompressed buffer), and second.txt which has contents
|
||||
* we will validate. This test ensures we can skip first.txt and still
|
||||
* be able to read the contents of second.txt
|
||||
*/
|
||||
const char *refname = "test_read_format_7zip_extract_second.7z";
|
||||
extract_reference_file(refname);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, refname, 10240));
|
||||
|
||||
struct archive_entry *ae;
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("first.txt", archive_entry_pathname(ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("second.txt", archive_entry_pathname(ae));
|
||||
|
||||
assertEqualInt(23, archive_read_data(a, buffer, sizeof(buffer)));
|
||||
assertEqualMem("This is from second.txt", buffer, 23);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
|
|
|||
11
libarchive/test/test_read_format_7zip_extract_second.7z.uu
Normal file
11
libarchive/test/test_read_format_7zip_extract_second.7z.uu
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
begin 644 test_read_format_7zip_extract_second.7z
|
||||
M-WJ\KR<<``-N%=VX!@$````````B`````````*R\U.<`&`Q"DFIGO`[1,RO\
|
||||
MN,RA7-QU1L&_]O_/$0MMLIEBUR3'BDX@M2C-5'VG./-4,5@W3Q@*__^7_,[H
|
||||
MEO`DB'[ZI>@H2_E>/W.2G$$.P01-X!YN5";SS[3#7Z4Q1G/EF.0'^D*[S8&8
|
||||
M[FV9DYX7,SA%^.Q\'?__P!@`````@3,'K@_4WV/Q0A7VLXG$X?GH4=5W^`UM
|
||||
M$N_EX$)LE*?K$W5?WLP:X0T[Q%V^?A!0E\VZRBB,)(MO`C`LO[O!3(1YL)<:
|
||||
MJ."`';WU;>GP5',%Z=6?*/H9*Z)&\*!2^<F\P&>,RV`R30UOBH8+5.;;2IKF
|
||||
M0W://&'?"L?0L2!)`*]F30B0&/_'<4``%P9Z`0F`C``'"P$``2,#`0$%70``
|
||||
-@``,@*@*`6]FB2D`````
|
||||
`
|
||||
end
|
||||
|
|
@ -65,15 +65,6 @@ static unsigned char archive[] = {
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX This must be removed when we use int64_t for uid.
|
||||
*/
|
||||
static int
|
||||
uid_size(void)
|
||||
{
|
||||
return (sizeof(uid_t));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_cpio_afio)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
|
@ -106,8 +97,7 @@ DEFINE_TEST(test_read_format_cpio_afio)
|
|||
*/
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualInt(17, archive_entry_size(ae));
|
||||
if (uid_size() > 4)
|
||||
assertEqualInt(65536, archive_entry_uid(ae));
|
||||
assertEqualInt(65536, archive_entry_uid(ae));
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
|
||||
assertA(archive_filter_code(a, 0) == ARCHIVE_FILTER_NONE);
|
||||
|
|
@ -117,3 +107,21 @@ DEFINE_TEST(test_read_format_cpio_afio)
|
|||
|
||||
free(p);
|
||||
}
|
||||
|
||||
// From OSS Fuzz Issue 70019:
|
||||
static unsigned char archive2[] = "070727bbbBbbbBabbbbbbcbcbbbbbbm726f777f777ffffffff518402ffffbbbabDDDDDDDDD7c7Ddd7DDDDnDDDdDDDB7777s77777777777C7727:";
|
||||
|
||||
DEFINE_TEST(test_read_format_cpio_afio_broken)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, archive2, sizeof(archive2)));
|
||||
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
|
||||
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
|
||||
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_AFIO_LARGE);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
|
|
|||
50
libarchive/test/test_read_format_huge_rpm.c
Normal file
50
libarchive/test/test_read_format_huge_rpm.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2024 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
DEFINE_TEST(test_read_format_huge_rpm)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
const char *name = "test_read_format_huge_rpm.rpm";
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
|
||||
|
||||
/* This archive should have no entries -- if it has entries, the bid has screwed up */
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
|
||||
/* Verify that the format detection worked. */
|
||||
assertEqualInt(ARCHIVE_FILTER_RPM, archive_filter_code(a, 0));
|
||||
assertEqualString("rpm", archive_filter_name(a, 0));
|
||||
assertEqualInt(ARCHIVE_FORMAT_EMPTY, archive_format(a));
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
244
libarchive/test/test_read_format_huge_rpm.rpm.uu
Normal file
244
libarchive/test/test_read_format_huge_rpm.rpm.uu
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
(
|
||||
# set up ST_LEAD
|
||||
python -c 'import sys; sys.stdout.buffer.write(b"\xED\xAB\xEE\xDB\x03\x00\x00\x01" + (96 - 8) * b"\x00")'
|
||||
# set up ST_HEADER with 0x800000 sections
|
||||
python -c 'import sys; sys.stdout.buffer.write(b"\x8E\xAD\xE8\x01" + 4 * b"\x00" + b"\x80" + 7 * b"\x00")'
|
||||
# create archive
|
||||
touch input.txt
|
||||
bsdtar -cf - input.txt
|
||||
) > test_read_format_huge_rpm.rpm
|
||||
|
||||
begin 644 test_read_format_huge_rpm.rpm
|
||||
M[:ONVP,```$`````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````CJWH`0````"``````````&EN<'5T+G1X=```````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````````````````````````P,#`V-#0@`#`P,#<V
|
||||
M-2``,#`P,#(T(``P,#`P,#`P,#`P,"`Q-#8Q-3(U-C0W-"`P,3(W,38`(#``
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````=7-T87(`,#!T:6T`````````````````````````````````
|
||||
M`````'-T869F````````````````````````````````````,#`P,#`P(``P
|
||||
M,#`P,#`@````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
"````
|
||||
`
|
||||
end
|
||||
40
libarchive/test/test_read_format_iso_3.iso.Z.uu
Normal file
40
libarchive/test/test_read_format_iso_3.iso.Z.uu
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
Same as test_read_format_iso_2.iso.Z except that the root directory record
|
||||
size in the PVD has been changed to 68 bytes (instead of the 34 required
|
||||
by the standard). This non-standard value was seen in the wild.
|
||||
|
||||
begin 644 test_read_format_iso_3.iso.Z
|
||||
M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR
|
||||
MI,F3*%.J7,FRI<N7,&/*G$FSILV;.'/JW,FSI\^?0(,*'4JTJ-&C2),J7<JT
|
||||
MJ=.G4*-*G4JUJM6K6+-JW<JUJ]>O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
|
||||
MKMV[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
|
||||
ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
|
||||
MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
|
||||
MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$Z408<04Q`!PH,01BCA
|
||||
MA!16:.&%$!Z404$;>G0@``%\>"`""`#@04$>2)#0!`,1`0`%!<%8HD`EEF+C
|
||||
MC:4($)"(!V+HXX]`!BGDD$06:>212":IY)),-NGDDU!&*>645%9II8\R%!@#
|
||||
M##C$0(,,,6Q)PPP$DI-EF%QZ"::89,)`#H%PQBDGG&=NV>67:(Y9YH?_]>GG
|
||||
MGX7](R"!!@)JZ*&()JKHHL<="...`AU80:0`!`$B`!=0.@2CG';JZ:>@A@H8
|
||||
MGR]>:FI`DP9@*:F9!BCJJ[#&*NNLM#XE0JD$R3A0C3C:J*.I(0)PZZ,#Z4HC
|
||||
M`+WZ"BF((=XZ*4&3SAA0B6\@X$`%"AA`SJ\\!G%KI@1E*BT`U%J+[0+;+AOB
|
||||
MIK6VZ^Z[\,8;G;,%1;LK`-5>FVVZP!XX;(SDWIMLCNJ&:`(`%A1D@0$%&9`O
|
||||
MMMI2"B(!0KBP0PSR9JSQQAQWW!P:9;#!QAL*>&SRR2BGK'*GWQ8D[KT/*X`N
|
||||
MMSOZBVNQ`1\[,,W,!G`P!@5AP#!!#ILK,SD2!T``$19CO/+34$<M]=2$@2PR
|
||||
MR51GK?767'?M]==@ARWVV&27;?;9:*>M]MILM^WVVW#'+??<=-=M]]UXYZWW
|
||||
MWGSW[???@`<N^."$%V[XX8@GKOCBC#?N^..01R[YY)17;OGEF&>N^>:<=^[Y
|
||||
MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,<N^^RTUV[[[;CGKOONO/?N^^_`!R_\
|
||||
M\,07;_SQR">O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(<O_OCDEV_^
|
||||
M^>BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@
|
||||
M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$*
|
||||
M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7
|
||||
MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?(
|
||||
MQC:Z\8UPC*,<YTC'.MKQCGC,HQ[WR,<^^O&/@`RD(`=)R$(:\I"(3*0B%\G(
|
||||
M1CKRD9",I"0G2<E*6O*2F,RD)C?)R4YZ\I.@#*4H1TG*4IKRE*A,I2I7R<I6
|
||||
MNO*5L(RE+&=)RUK:\I:XS*4N=\G+7OKRE\`,IC"'2<QB&O.8R$RF,I?)S&8Z
|
||||
M\YG0C*8TITG-:EKSFMC,IC:WR<UN>O.;X`RG.,=)SG*:\YSH3*<ZU\G.=KKS
|
||||
MG?",ISSG2<]ZVO.>^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A
|
||||
M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P
|
||||
MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"-
|
||||
MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK
|
||||
".`$`
|
||||
`
|
||||
end
|
||||
|
|
@ -40,8 +40,29 @@ test1(void)
|
|||
archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, name, 512));
|
||||
|
||||
/* Root directory */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, 1131434684, archive_entry_atime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
|
||||
assertEqualIntA(a, 1131434684, archive_entry_ctime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_dev(ae));
|
||||
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_gid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_gname(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_ino(ae));
|
||||
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
|
||||
assertEqualIntA(a, 1131434684, archive_entry_mtime(ae));
|
||||
assertEqualIntA(a, 2, archive_entry_nlink(ae));
|
||||
assertEqualStringA(a, ".", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, 0700, archive_entry_perm(ae));
|
||||
assertEqualIntA(a, 2048, archive_entry_size(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_uid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_uname(ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_EOF,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualInt(1, archive_file_count(a));
|
||||
assertEqualInt(archive_filter_code(a, 0),
|
||||
ARCHIVE_FILTER_COMPRESS);
|
||||
|
|
@ -53,11 +74,10 @@ test1(void)
|
|||
}
|
||||
|
||||
static void
|
||||
test2(void)
|
||||
test_small(const char *name)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
const char *name = "test_read_format_iso_2.iso.Z";
|
||||
|
||||
extract_reference_file(name);
|
||||
|
||||
|
|
@ -68,21 +88,110 @@ test2(void)
|
|||
archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, name, 512));
|
||||
|
||||
/* Root directory */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualString(".", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, 3443989665, archive_entry_atime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
|
||||
assertEqualIntA(a, 3443989665, archive_entry_ctime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_dev(ae));
|
||||
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_gid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_gname(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_ino(ae));
|
||||
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
|
||||
assertEqualIntA(a, 3443989665, archive_entry_mtime(ae));
|
||||
assertEqualIntA(a, 4, archive_entry_nlink(ae));
|
||||
assertEqualIntA(a, 0700, archive_entry_perm(ae));
|
||||
assertEqualIntA(a, 2048, archive_entry_size(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_uid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_uname(ae));
|
||||
|
||||
/* Directory "A" */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualString("A", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, 1313381406, archive_entry_atime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
|
||||
assertEqualIntA(a, 1313381406, archive_entry_ctime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_dev(ae));
|
||||
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_gid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_gname(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_ino(ae));
|
||||
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
|
||||
assertEqualIntA(a, 1313381406, archive_entry_mtime(ae));
|
||||
assertEqualIntA(a, 2, archive_entry_nlink(ae));
|
||||
assertEqualIntA(a, 0700, archive_entry_perm(ae));
|
||||
assertEqualIntA(a, 2048, archive_entry_size(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_uid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_uname(ae));
|
||||
|
||||
/* File "A/B" */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualString("A/B", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, 1313381406, archive_entry_atime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
|
||||
assertEqualIntA(a, 1313381406, archive_entry_ctime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_dev(ae));
|
||||
assertEqualIntA(a, AE_IFREG, archive_entry_filetype(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_gid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_gname(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_ino(ae));
|
||||
assertEqualIntA(a, AE_IFREG | 0400, archive_entry_mode(ae));
|
||||
assertEqualIntA(a, 1313381406, archive_entry_mtime(ae));
|
||||
assertEqualIntA(a, 1, archive_entry_nlink(ae));
|
||||
assertEqualIntA(a, 0400, archive_entry_perm(ae));
|
||||
assertEqualIntA(a, 6, archive_entry_size(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_uid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_uname(ae));
|
||||
/* TODO: Verify that file contents are "hello\n" */
|
||||
|
||||
/* Directory "C" */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualString("C", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, 1313381411, archive_entry_atime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
|
||||
assertEqualIntA(a, 1313381411, archive_entry_ctime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_dev(ae));
|
||||
assertEqualIntA(a, AE_IFDIR, archive_entry_filetype(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_gid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_gname(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_ino(ae));
|
||||
assertEqualIntA(a, AE_IFDIR | 0700, archive_entry_mode(ae));
|
||||
assertEqualIntA(a, 1313381411, archive_entry_mtime(ae));
|
||||
assertEqualIntA(a, 2, archive_entry_nlink(ae));
|
||||
assertEqualIntA(a, 0700, archive_entry_perm(ae));
|
||||
assertEqualIntA(a, 2048, archive_entry_size(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_uid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_uname(ae));
|
||||
|
||||
/* File "C/D" */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualString("C/D", archive_entry_pathname(ae));
|
||||
assertEqualIntA(a, 1313381411, archive_entry_atime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_birthtime(ae));
|
||||
assertEqualIntA(a, 1313381411, archive_entry_ctime(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_dev(ae));
|
||||
assertEqualIntA(a, AE_IFREG, archive_entry_filetype(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_gid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_gname(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_ino(ae));
|
||||
assertEqualIntA(a, AE_IFREG | 0400, archive_entry_mode(ae));
|
||||
assertEqualIntA(a, 1313381411, archive_entry_mtime(ae));
|
||||
assertEqualIntA(a, 1, archive_entry_nlink(ae));
|
||||
assertEqualIntA(a, 0400, archive_entry_perm(ae));
|
||||
assertEqualIntA(a, 6, archive_entry_size(ae));
|
||||
assertEqualIntA(a, 0, archive_entry_uid(ae));
|
||||
assertEqualStringA(a, NULL, archive_entry_uname(ae));
|
||||
/* TODO: Verify that file contents are "hello\n" */
|
||||
|
||||
/* Final statistics */
|
||||
assertEqualIntA(a, ARCHIVE_EOF,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualInt(5, archive_file_count(a));
|
||||
|
|
@ -98,5 +207,8 @@ test2(void)
|
|||
DEFINE_TEST(test_read_format_iso_Z)
|
||||
{
|
||||
test1();
|
||||
test2();
|
||||
/* A very small ISO image with a variety of contents. */
|
||||
test_small("test_read_format_iso_2.iso.Z");
|
||||
/* As above, but with a non-standard 68-byte root directory in the PVD */
|
||||
test_small("test_read_format_iso_3.iso.Z");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ test_read_format_mtree1(void)
|
|||
/* TODO: Mtree reader should probably return ARCHIVE_WARN for this. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString(archive_entry_pathname(ae), "dir2/toosmallfile");
|
||||
assertEqualInt(archive_entry_size(ae), -1);
|
||||
assertEqualInt(archive_entry_size(ae), 0);
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
|
||||
|
||||
|
|
|
|||
|
|
@ -843,7 +843,7 @@ DEFINE_TEST(test_read_format_rar5_block_by_block)
|
|||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
uint8_t buf[173];
|
||||
int bytes_read;
|
||||
ssize_t bytes_read;
|
||||
uint32_t computed_crc = 0;
|
||||
|
||||
extract_reference_file("test_read_format_rar5_compressed.rar");
|
||||
|
|
@ -932,19 +932,22 @@ DEFINE_TEST(test_read_format_rar5_symlink)
|
|||
assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
|
||||
assertEqualString("file.txt", archive_entry_symlink(ae));
|
||||
assertEqualInt(AE_SYMLINK_TYPE_FILE, archive_entry_symlink_type(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
|
||||
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualString("dirlink", archive_entry_pathname(ae));
|
||||
assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
|
||||
assertEqualString("dir", archive_entry_symlink(ae));
|
||||
assertEqualInt(AE_SYMLINK_TYPE_DIRECTORY, archive_entry_symlink_type(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
|
||||
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualString("dir", archive_entry_pathname(ae));
|
||||
assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
|
||||
|
||||
assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
|
||||
|
||||
|
|
@ -969,7 +972,8 @@ DEFINE_TEST(test_read_format_rar5_hardlink)
|
|||
assertEqualString("hardlink.txt", archive_entry_pathname(ae));
|
||||
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
|
||||
assertEqualString("file.txt", archive_entry_hardlink(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae)));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
assertA(0 == archive_read_data(a, NULL, (size_t)archive_entry_size(ae)));
|
||||
|
||||
assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
|
||||
|
||||
|
|
@ -1340,7 +1344,7 @@ DEFINE_TEST(test_read_format_rar5_sfx)
|
|||
|
||||
assertA(size == archive_read_data(a, buff, size));
|
||||
assertEqualMem(buff, test_txt, size);
|
||||
|
||||
|
||||
EPILOGUE();
|
||||
}
|
||||
|
||||
|
|
@ -1402,3 +1406,26 @@ DEFINE_TEST(test_read_format_rar5_read_data_block_uninitialized_offset)
|
|||
|
||||
EPILOGUE();
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_rar5_data_ready_pointer_leak)
|
||||
{
|
||||
/* oss fuzz 70024 */
|
||||
|
||||
char buf[4096];
|
||||
PROLOGUE("test_read_format_rar5_data_ready_pointer_leak.rar");
|
||||
|
||||
/* Return codes of those calls are ignored, because this sample file
|
||||
* is invalid. However, the unpacker shouldn't produce any SIGSEGV
|
||||
* errors during processing. */
|
||||
|
||||
(void) archive_read_next_header(a, &ae);
|
||||
(void) archive_read_data(a, buf, sizeof(buf));
|
||||
(void) archive_read_next_header(a, &ae);
|
||||
(void) archive_read_data(a, buf, sizeof(buf));
|
||||
(void) archive_read_data(a, buf, sizeof(buf));
|
||||
(void) archive_read_next_header(a, &ae);
|
||||
/* This call shouldn't produce SIGSEGV. */
|
||||
(void) archive_read_data(a, buf, sizeof(buf));
|
||||
|
||||
EPILOGUE();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
begin 644 test_read_format_rar5_data_ready_pointer_leak.rar.uu
|
||||
M4F%R(1H'`0`]/-[E`@$`_R`@1#[Z5P("`P,`(/__(""`((``"2`@("`@_R`@
|
||||
M("`@(%.`*O0#`N<B`A"`("#_((`+`00@("`@(""!)/\@("`@("`@(/\@("`@
|
||||
M^I@R<00"WN<-\@$@_R`@(``C("`@("`@("`@("`@("`@("`@("`@("`@("#_
|
||||
M____("`@(/___R#_("`@("`@("#___\@_____R`@("`@("`@(/__________
|
||||
M____(/__(/\@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@________
|
||||
M_________R`@____(/____\@("`@("`@("#______________R#___\@("`@
|
||||
M("`@("`@("`@("`@("`@("`@(/\@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@_________R`@("`@_R`@("`@("`@
|
||||
M("`@("`@(/__("`@("`@("`@("`@("`@(%.`*O0#`N<B`A"`_R`@_R#_"P$$
|
||||
M("`@("`@@23_("`@_R`@("#_("`@(/J8,G$$`M[G#?(!(/\@("``(R`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("#_("`@("`@("#_("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("#_
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@____("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@_R`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("!3@"KT`P+G(B`0@/\@(/\@_PL!_R"!)/\@("`@("`@(/\@("`@^I@R<00"
|
||||
MWN<-\@$@_R`@(``C("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("#______________R`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@(/\@(/_______R`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@_________R`@("`@("`@("`@("`@("`@(/________\@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(/\@
|
||||
M("`@("`@(/\@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@(/\@($0^^E<"`@,#("`@(/\@@``)("`@("`@("`@
|
||||
)("`@("`@("`@
|
||||
`
|
||||
end
|
||||
|
|
@ -437,7 +437,7 @@ static void verify(unsigned char *d, size_t s,
|
|||
assertA(0 == archive_read_support_filter_all(a));
|
||||
assertA(0 == archive_read_support_format_all(a));
|
||||
assertA(0 == archive_read_open_memory(a, buff, s + 1024));
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualInt(archive_filter_code(a, 0), compression);
|
||||
assertEqualInt(archive_format(a), format);
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
|
|
|
|||
65
libarchive/test/test_read_format_tar_pax_large_attr.c
Normal file
65
libarchive/test/test_read_format_tar_pax_large_attr.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2023 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
/*
|
||||
* Read a pax formatted tar archive that has an extremely large
|
||||
* (8,000,000 bytes) attribute of unknown type. The pax reader should simply
|
||||
* skip the attribute.
|
||||
*/
|
||||
DEFINE_TEST(test_read_format_tar_pax_large_attr)
|
||||
{
|
||||
char name[] = "test_read_format_tar_pax_large_attr.tar.Z";
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
|
||||
|
||||
/* Read first entry. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("foo", archive_entry_pathname(ae));
|
||||
assertEqualInt(1, archive_entry_mtime(ae));
|
||||
assertEqualInt(1000, archive_entry_uid(ae));
|
||||
assertEqualString("tim", archive_entry_uname(ae));
|
||||
assertEqualInt(0, archive_entry_gid(ae));
|
||||
assertEqualString("wheel", archive_entry_gname(ae));
|
||||
assertEqualInt(0100644, archive_entry_mode(ae));
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
|
||||
|
||||
/* Verify the end-of-archive. */
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
|
||||
/* Verify that the format detection worked. */
|
||||
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS);
|
||||
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
149
libarchive/test/test_read_format_tar_pax_large_attr.tar.Z.uu
Normal file
149
libarchive/test/test_read_format_tar_pax_large_attr.tar.Z.uu
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
Decode this file with:
|
||||
cat test_read_format_tar_pax_large_attr.tar.Z.uu | uudecode -p | uncompress | hexdump -C
|
||||
|
||||
It contains a single tar entry with a pax header that has a single
|
||||
attribute of 8000000 bytes
|
||||
00000200 38 30 30 30 30 30 30 20 75 6e 6b 6e 6f 77 6e 3d |8000000 unknown=|
|
||||
00000210 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b |++++++++++++++++|
|
||||
*
|
||||
007a13f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 0a |+++++++++++++++.|
|
||||
|
||||
begin 644 test_read_format_tar_pax_large_attr.tar.Z
|
||||
M'YV04,+@05(F#)DR<EZ8>?,&@,.'$"-*G$BQHL6+&"O"V&B#!@T0`#;"N&&C
|
||||
M!DB1,&1\#+EQ1L<8,42"B$&CA@P;-UQZM`$"1HP9-6+<```"3\:C2),J73JQ
|
||||
MSAPZ8>2PI).F#5.+3\.8,7-U(LJ-)[^"[$JVK-FS:-'B^`H#1!TW:]R\N>.F
|
||||
MQXJ[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
|
||||
ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
|
||||
MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
|
||||
MO?OW\./+GT^_OOW[^//KW\^_O___``8HX(`$%FC@@0@FJ.""##;HX(,01BCA
|
||||
MA!16:.&%&&:HX88<=NCAAR"&*.*())9HXHDHIJCBBBRVZ.*+,,8HXXPTUFCC
|
||||
MC3CFJ...//;HXX]`!BGDD$06:>212":IY)),-NGDDU!&*>645%9IY9589JGE
|
||||
MEEQVZ>678(8IYIADEFGFF6BFJ>::;+;IYIMPQBGGG'36:>>=>.:IYYY\]NGG
|
||||
MGX`&*NB@A!9JZ*&()JKHHHPVZNBCD$8JZ:245FKII9AFJNFFG';JZ:>@ABKJ
|
||||
MJ*26:NJIJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYJKKKKSVZNNOP`8K[+#$%FOL
|
||||
ML<@FJ^RRS#;K[+/01BOMM-16:^VUV&:K[;;<=NOMM^"&*^ZXY)9K[KGHIJON
|
||||
MNNRVZ^Z[\,8K[[STUFOOO?CFJ^^^_/;K[[\`!RSPP`07;/#!"">L\,(,-^SP
|
||||
MPQ!'+/'$%%=L\<489ZSQQAQW[/''((<L\L@DEVSRR2BGK/+*++?L\LLPQRSS
|
||||
MS#37;//-..>L\\X\]^SSST`'+?301!=M]-%()ZWTTDPW[?334$<M]=145VWU
|
||||
MU5AGK?767'?M]==@ARWVV&27;?;9:*>M]MILM^WVVW#'+??<=-=M]]UXYZWW
|
||||
MWGSW[???@`<N^."$%V[XX8@GKOCBC#?N^..01R[YY)17;OGEF&>N^>:<=^[Y
|
||||
MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,<N^^RTUV[[[;CGKOONO/?N^^_`!R_\
|
||||
M\,07;_SQR">O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(<O_OCDEV_^
|
||||
M^>BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@
|
||||
M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$*
|
||||
M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7
|
||||
MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?(
|
||||
MQC:Z\8UPC*,<YTC'.MKQCGC,HQ[WR,<^^O&/@`RD(`=)R$(:\I"(3*0B%\G(
|
||||
M1CKRD9",I"0G2<E*6O*2F,RD)C?)R4YZ\I.@#*4H1TG*4IKRE*A,I2I7R<I6
|
||||
MNO*5L(RE+&=)RUK:\I:XS*4N=\G+7OKRE\`,IC"'2<QB&O.8R$RF,I?)S&8Z
|
||||
M\YG0C*8TITG-:EKSFMC,IC:WR<UN>O.;X`RG.,=)SG*:\YSH3*<ZU\G.=KKS
|
||||
MG?",ISSG2<]ZVO.>^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A
|
||||
M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P
|
||||
MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"-
|
||||
MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK
|
||||
M7.=*U[K:]:YXS:M>]\K7OOKUKX`-K&`'2]C"&O:PB$VL8A?+V,8Z]K&0C:QD
|
||||
M)TO9REKVLIC-K&8WR]G.>O:SH`VM:$=+VM*:]K2H3:UJ5\O:UKKVM;"-K6QG
|
||||
M2]O:VO:VN,VM;G?+V][Z]K?`#:YPATO<XAKWN,A-KG*7R]SF.O>YT(VN=*=+
|
||||
MW>I:][K8S:YVM\O=[GKWN^`-KWC'2][RFO>\Z$VO>M?+WO:Z][WPC:]\YTO?
|
||||
M^MKWOOC-KW[WR]_^^O>_``ZP@`=,X`(;^,`(3K""%\S@!COXP1".L(0G3.$*
|
||||
M6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK;
|
||||
M^,8XSK&.=\SC'OOXQT`.LI"'3.0B&_G(2$ZRDI?,Y"8[^<E0CK*4ITSE*EOY
|
||||
MREC.LI:WS.4N>_G+8`ZSF,=,YC*;^<QH3K.:U\SF-KOYS7".LYSG3.<ZV_G.
|
||||
M>,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8
|
||||
MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC.
|
||||
MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV
|
||||
MMK?-[6Y[^]O@#K>XQTWN<IO[W.A.M[K7S>YVN_O=\(ZWO.=-[WK;^][XSK>^
|
||||
M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W
|
||||
MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/N<QG3O.:V_SF.,^YSG?.
|
||||
M\Y[[_.=`#[K0AT[THAO]Z$A/NM*7SO2F._WI4(^ZU*=.]:I;_>I8S[K6M\[U
|
||||
MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O<YT[WNMO][GC/N][WSO>^
|
||||
M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^<Y[
|
||||
M_O.@#[WH1T_ZTIO^]*A/O>I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^
|
||||
M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[
|
||||
MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\`
|
||||
M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($<V($>
|
||||
M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\
|
||||
MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5:
|
||||
MN(5<V(5>^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X
|
||||
MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6
|
||||
M>(F8F(F:N(F<V(F>^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT
|
||||
M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2
|
||||
M.(W46(W6>(W8F(W:N(W<V(W>^(W@&([B.([D6([F>([HF([JN([LV([N^([P
|
||||
M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`.
|
||||
M^9`0&9$2.9$469$6>9$8F9$:N9$<V9$>^9$@&9(B.9(D69(F>9(HF9(JN9(L
|
||||
MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91*
|
||||
MN91,V91.^910&952.9546956>958F95:N95<V95>^95@&99B.99D699F>99H
|
||||
MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B&
|
||||
M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F<V9F>^9F@&9JB.9JD
|
||||
M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S"
|
||||
M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W<V9W>^9W@
|
||||
M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^
|
||||
M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$<
|
||||
MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z
|
||||
MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58
|
||||
MFJ5:NJ5<VJ5>^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V
|
||||
M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4
|
||||
M6JF6>JF8FJF:NJF<VJF>^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR
|
||||
M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0
|
||||
M&JW2.JW46JW6>JW8FJW:NJW<VJW>^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N
|
||||
M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`,
|
||||
MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$<V[$>^[$@&[(B.[(D6[(F>[(HF[(J
|
||||
MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1(
|
||||
MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5<V[5>^[5@&[9B.[9D6[9F
|
||||
M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$
|
||||
M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F<V[F>^[F@&[JB
|
||||
M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O`
|
||||
M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W<V[W>
|
||||
M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\
|
||||
MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$:
|
||||
MO,$<W,$>_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X
|
||||
MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56
|
||||
M?,58G,5:O,5<W,5>_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T
|
||||
M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2
|
||||
M/,F47,F6?,F8G,F:O,F<W,F>_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP
|
||||
M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S.
|
||||
M_,S0',W2/,W47,W6?,W8G,W:O,W<W,W>_,W@',[B/,[D7,[F?,[HG,[JO,[L
|
||||
MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`*
|
||||
MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$<W=$>_=$@'=(B/=(D7=(F?=(H
|
||||
MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1&
|
||||
M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5<W=5>_=5@'=9B/=9D
|
||||
M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B"
|
||||
M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F<W=F>_=F@
|
||||
M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^
|
||||
M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W<
|
||||
MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z
|
||||
MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8
|
||||
MGN$:ON$<WN$>_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V
|
||||
M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54
|
||||
M7N56?N58GN5:ON5<WN5>_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R
|
||||
M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0
|
||||
M'NF2/NF47NF6?NF8GNF:ONF<WNF>_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN
|
||||
M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS,
|
||||
MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW<WNW>_NW@'N[B/N[D7N[F?N[HGN[J
|
||||
MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`(
|
||||
MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$<W_$>__$@'_(B/_(D7_(F
|
||||
M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$
|
||||
M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5<W_5>__5@'_9B
|
||||
M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>`
|
||||
M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F<W_F>
|
||||
M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\
|
||||
MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W:
|
||||
MO_W<W_W>__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X
|
||||
MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@!
|
||||
M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P
|
||||
M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27(
|
||||
M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R#
|
||||
M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)!
|
||||
M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\
|
||||
MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K"
|
||||
M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U
|
||||
MO(;8,!MJPVW(#;NA-_R&X#`<BL-Q2`[+H3D\A^@P':K#=<@.VZ$[?(?P,![*
|
||||
MPWE(#^NA/;R'^#`?ZL-]R`_[H3_\AP`Q(`K$@4@0"Z)!/(@(,2$JQ(7($!NB
|
||||
M0WR($#$B2L2)2!%ID@)8"`TA+6C$C8@11$)'6`D;02C4@+;`$E!"6&`+,@$E
|
||||
MBH08T!-@`@UP"40!!G#$F4@3FT)6D`H;@2I8!8UX!]!`&2@#;"`ML(63*!-J
|
||||
MHE$\BD@Q*2K%I<@4FZ)3?(I0,2I*Q:E(%:NB5;R*6#$K:L6MR!6[HE?\BF`Q
|
||||
M+(K%L4@6RZ)9/(MH,2VJQ;7(%MNB6WR+<#$NRL6Y2!?KHEV\BW@Q+^K%O<@7
|
||||
M^Z)?_(N`,3`*QL%(&`NC83R,B#$Q*L;%R!@;HV-\C)`Q,DK&R4@9*Z-EO(R8
|
||||
),3-JQLW(&0$C
|
||||
`
|
||||
end
|
||||
|
|
@ -860,3 +860,34 @@ DEFINE_TEST(test_read_format_xar)
|
|||
verify(archive12, sizeof(archive12), verify12, NULL, GZIP);
|
||||
verifyB(archive13, sizeof(archive13));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_xar_duplicate_filename_node)
|
||||
{
|
||||
static const char *reffiles[] =
|
||||
{
|
||||
"test_read_format_xar_duplicate_filename_node.xar",
|
||||
NULL
|
||||
};
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
extract_reference_files(reffiles);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
|
||||
r = archive_read_support_format_xar(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
skipping("xar reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
|
||||
assertA(0 == archive_read_open_filenames(a, reffiles, 10240));
|
||||
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualString("File", archive_entry_pathname(ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
begin 644 test_read_format_xar_duplicate_filename_node.xar
|
||||
M>&%R(0`<``$````````!EP````````.]`````7B<A5-);H,P%-U7ZAT0>VIC
|
||||
MC('((;N<H-UT][$-L<H0@1,E.7T-`0H=TI6?__OSP'>7JG3.JNUT4V]=_P6[
|
||||
MCJI%(W5=;-VWU[T7N[OT^8E?H+6/XW#3B`%8*%H%QMIY1E<J)9A0#S//IZ\$
|
||||
M;PC=^(RCM<ID=U#BHSM53F>NI=JZW0%\=R0MW>1YITR*.1K1S'3ZUL?A:`"C
|
||||
M-S2YFP2Y+I6CI:UFX;0&&W]O&8X&^#]AKD>5Y@,QP)G0=2-M&E'"DIBC^V\F
|
||||
MI3IKH>HF]0-&68!]PM$LF[6JW@8S9CM4K<Q/6O:%]\\L*^ZR8BD3O[<<)^^V
|
||||
M'XM>][$>J%9K57B@"FM5"0;FG_V7JB[,(?5MHB-<D.,<R<^1SD-=S7203VLX
|
||||
M;0D<CZ46PS:ABU?<]-%UT-(`6G'09R6]W_<KIG$LJ9\%"6!)"&80R#`)<"!R
|
||||
M'(DL)T`CH2384K\[6J5U,2T(\V>8#&+(0L`DQED2!@!)1(,PS^.$,I&)+"-1
|
||||
M&`*)./KIZ:N]:-%?COHMO%\?NI\?1_T]?@(L`P/8\;44V2:R;"\D48GC?CRL
|
||||
C(UAG)C5XG./E`@``)@`8>)R%4TEN@S`4W5?J'1![:F.,@<@`
|
||||
`
|
||||
end
|
||||
|
|
@ -41,7 +41,7 @@ DEFINE_TEST(test_read_format_zip_traditional_encryption_data)
|
|||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
|
||||
if (ARCHIVE_OK != archive_write_set_options(a,
|
||||
"zip:encryption=traditional")) {
|
||||
skipping("This system does not have cryptographic liberary");
|
||||
skipping("This system does not have cryptographic library");
|
||||
archive_write_free(a);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ test_winzip_aes(const char *refname, int need_libz)
|
|||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
|
||||
if (ARCHIVE_OK != archive_write_set_options(a,
|
||||
"zip:encryption=aes256")) {
|
||||
skipping("This system does not have cryptographic liberary");
|
||||
skipping("This system does not have cryptographic library");
|
||||
archive_write_free(a);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ DEFINE_TEST(test_read_format_zip_winzip_aes256_large)
|
|||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
|
||||
if (ARCHIVE_OK != archive_write_set_options(a,
|
||||
"zip:encryption=aes256")) {
|
||||
skipping("This system does not have cryptographic liberary");
|
||||
skipping("This system does not have cryptographic library");
|
||||
archive_write_free(a);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -390,3 +390,105 @@ DEFINE_TEST(test_ustar_filename_encoding_CP932_UTF8)
|
|||
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_ustar_filename_encoding_UTF16_win)
|
||||
{
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
skipping("This test is meant to verify unicode string handling"
|
||||
" on Windows with UTF-16 names");
|
||||
return;
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *entry;
|
||||
char buff[4096];
|
||||
size_t used;
|
||||
|
||||
/*
|
||||
* Don't call setlocale because we're verifying that the '_w' functions
|
||||
* work as expected when 'hdrcharset' is UTF-8
|
||||
*/
|
||||
|
||||
/* Part 1: file */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
|
||||
skipping("This system cannot convert character-set"
|
||||
" from UTF-16 to UTF-8.");
|
||||
archive_write_free(a);
|
||||
return;
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the filename using a UTF-16 string */
|
||||
archive_entry_copy_pathname_w(entry, L"\u8868.txt");
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
|
||||
|
||||
/* Part 2: directory */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the directory name using a UTF-16 string */
|
||||
/* NOTE: Explicitly not adding trailing slash to test that code path */
|
||||
archive_entry_copy_pathname_w(entry, L"\u8868");
|
||||
archive_entry_set_filetype(entry, AE_IFDIR);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff, "\xE8\xA1\xA8/", 4);
|
||||
|
||||
/* Part 3: symlink */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the symlink target using a UTF-16 string */
|
||||
archive_entry_set_pathname(entry, "link.txt");
|
||||
archive_entry_copy_symlink_w(entry, L"\u8868.txt");
|
||||
archive_entry_set_filetype(entry, AE_IFLNK);
|
||||
archive_entry_set_symlink_type(entry, AE_SYMLINK_TYPE_FILE);
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
|
||||
|
||||
/* Part 4: hardlink */
|
||||
a = archive_write_new();
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_set_options(a, "hdrcharset=UTF-8"));
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
entry = archive_entry_new2(a);
|
||||
/* Set the symlink target using a UTF-16 string */
|
||||
archive_entry_set_pathname(entry, "link.txt");
|
||||
archive_entry_copy_hardlink_w(entry, L"\u8868.txt");
|
||||
archive_entry_set_size(entry, 0);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
|
||||
archive_entry_free(entry);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Check UTF-8 version. */
|
||||
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,12 +230,8 @@ DEFINE_TEST(test_write_filter_zstd)
|
|||
archive_write_set_filter_option(a, NULL, "max-frame-out", "1GB"));
|
||||
#endif
|
||||
#if ZSTD_VERSION_NUMBER >= MINVER_LONG
|
||||
if ((int)(sizeof(size_t) == 4))
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_write_set_filter_option(a, NULL, "long", "26"));
|
||||
else
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_write_set_filter_option(a, NULL, "long", "27"));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_write_set_filter_option(a, NULL, "long", "23"));
|
||||
assertEqualIntA(a, ARCHIVE_FAILED,
|
||||
archive_write_set_filter_option(a, NULL, "long", "-1")); /* negative */
|
||||
#endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue