Update vendor/libarchive/dist to git b5818e39e128eca4951e2ab10467d4d850a2ba57

Relevant vendor changes:
Issue #795: XAR - do not try to add xattrs without an allocated name
PR #812: non-recursive option for extract and list
PR #958: support reading metadata from compressed files
PR #999: add --exclude-vcs option to bsdtar
Issue #1062: treat empty archives with a GNU volume header as valid
PR #1074: Handle ZIP files with trailing 0s in the extra fields
          (Android APK archives)
PR #1109: Ignore padding in Zip extra field data (Android APK archives)
PR #1167: fix problems related to unreadable directories
Issue #1168: fix handling of strtol() and strtoul()
PR #1172: RAR5 - fix invalid window buffer read in E8E9 filter
PR #1174: ZIP reader - fix of MSZIP signature parsing
PR #1175: gzip filter - fix reading files larger than 4GB from memory
PR #1177: gzip filter - fix memory leak with repeated header reads
PR #1180: ZIP reader - add support for Info-ZIP Unicode Path Extra Field
PR #1181: RAR5 - fix merge_block() recursion
          (OSS-Fuzz 12999, 13029, 13144, 13478, 13490)
PR #1183: fix memory leak when decompressing ZIP files with LZMA
PR #1184: fix RAR5 OSS-Fuzz issues 12466, 14490, 14491, 12817
  OSS-Fuzz 12466: RAR5 - fix buffer overflow when parsing huffman tables
  OSS-Fuzz 14490, 14491: RAR5 - fix bad shift-left operations
  OSS-Fuzz 12817: RAR5 - handle a case with truncated huffman tables
PR #1186: RAR5 - fix invalid type used for dictionary size mask
          (OSS-Fuzz 14537)
PR #1187: RAR5 - fix integer overflow (OSS-Fuzz 14555)
PR #1190: RAR5 - RAR5 don't try to unpack entries marked as directories
          (OSS-Fuzz 14574)
PR #1196: RAR5 - fix a potential SIGSEGV on 32-bit builds
OSS-Fuzz 2582: RAR - fix use after free if there is an invalid entry
OSS-Fuzz 14331: RAR5 - fix maximum owner name length
OSS-Fuzz 13965: RAR5 - use unsigned int for volume number + range check

Additional RAR5 reader changes:
  - support symlinks, hardlinks, file owner, file group, versioned files
  - change ARCHIVE_FORMAT_RAR_V5 to 0x100000
  - set correct mode for readonly directories
  - support readonly, hidden and system Windows file attributes

NOTE: a version bump of libarchive will happen in the following days
This commit is contained in:
Martin Matuska 2019-05-20 12:32:00 +00:00
parent f9b2e63a44
commit 8e97bbedae
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/libarchive/dist/; revision=347989
107 changed files with 7650 additions and 3360 deletions

View File

@ -2,25 +2,130 @@ env:
CIRRUS_CLONE_DEPTH: 1
ARCH: amd64
task:
matrix:
container:
image: fedora:29
freebsd_instance:
image: freebsd-12-0-release-amd64
freebsd_instance:
image: freebsd-11-2-release-amd64
osx_instance:
image: mojave-xcode-10.1
osx_instance:
image: high-sierra-xcode-10.0
FreeBSD_task:
matrix:
env:
BS: autotools
env:
BS: cmake
matrix:
freebsd_instance:
image: freebsd-12-0-release-amd64
freebsd_instance:
image: freebsd-11-2-release-amd64
prepare_script:
- ./build/ci/cirrus_ci/ci.sh prepare
configure_script:
- ./build/ci/build.sh -a autogen
- ./build/ci/build.sh -a configure
build_script:
- ./build/ci/build.sh -a build
test_script:
- ./build/ci/build.sh -a test
- ./build/ci/cirrus_ci/ci.sh test
install_script:
- ./build/ci/cirrus_ci.sh install
script:
- ./build/ci/build.sh
- ./build/ci/cirrus_ci.sh test
- ./build/ci/build.sh -a install
MacOS_task:
matrix:
env:
BS: autotools
env:
BS: cmake
matrix:
osx_instance:
image: mojave-xcode-10.2
osx_instance:
image: high-sierra-xcode-10.0
prepare_script:
- ./build/ci/cirrus_ci/ci.sh prepare
configure_script:
- ./build/ci/build.sh -a autogen
- ./build/ci/build.sh -a configure
build_script:
- ./build/ci/build.sh -a build
test_script:
- ./build/ci/build.sh -a test
- ./build/ci/cirrus_ci/ci.sh test
install_script:
- ./build/ci/build.sh -a install
Fedora_29_task:
container:
dockerfile: build/ci/cirrus_ci/Dockerfile.fc29
matrix:
env:
BS: autotools
env:
BS: cmake
configure_script:
- ./build/ci/build.sh -a autogen
- ./build/ci/build.sh -a configure
build_script:
- ./build/ci/build.sh -a build
test_script:
- ./build/ci/build.sh -a test
install_script:
- ./build/ci/build.sh -a install
Fedora_29_distcheck_task:
container:
dockerfile: build/ci/cirrus_ci/Dockerfile.fc29.distcheck
env:
BS: autotools
configure_script:
- ./build/ci/build.sh -a autogen
- ./build/ci/build.sh -a configure
distcheck_script:
- ./build/ci/build.sh -a distcheck
Windows_MSVC_task:
windows_container:
dockerfile: build/ci/cirrus_ci/Dockerfile.msvc
os_version: 2019
env:
BE: msvc
configure_script:
- build\ci\cirrus_ci\ci.cmd configure
build_script:
- build\ci\cirrus_ci\ci.cmd build
test_script:
- build\ci\cirrus_ci\ci.cmd test
instal_script:
- build\ci\cirrus_ci\ci.cmd install
Windows_MinGW_task:
windows_container:
image: cirrusci/windowsservercore:2019
os_version: 2019
env:
BE: mingw-gcc
prepare_script:
- build\ci\cirrus_ci\ci.cmd prepare
deplibs_script:
- build\ci\cirrus_ci\ci.cmd deplibs
configure_script:
- build\ci\cirrus_ci\ci.cmd configure
build_script:
- build\ci\cirrus_ci\ci.cmd build
test_script:
- build\ci\cirrus_ci\ci.cmd test
install_script:
- build\ci\cirrus_ci\ci.cmd install
Windows_Cygwin_task:
windows_container:
image: cirrusci/windowsservercore:2019
os_version: 2019
env:
BE: cygwin-gcc
prepare_script:
- build\ci\cirrus_ci\ci.cmd prepare
configure_script:
- build\ci\cirrus_ci\ci.cmd configure
build_script:
- build\ci\cirrus_ci\ci.cmd build
test_script:
- build\ci\cirrus_ci\ci.cmd test
install_script:
- build\ci\cirrus_ci\ci.cmd install

View File

@ -1,9 +0,0 @@
language: C
matrix:
include:
- os: windows
env: BS=msbuild
- os: windows
env: BS=mingw
script:
- build/ci/travis_ci.sh

View File

@ -481,6 +481,7 @@ ENDIF()
IF(LIBLZMA_FOUND)
SET(HAVE_LIBLZMA 1)
SET(HAVE_LZMA_H 1)
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIRS})
@ -494,6 +495,7 @@ IF(LIBLZMA_FOUND)
IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
ADD_DEFINITIONS(-DLZMA_API_STATIC)
ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
CMAKE_POP_CHECK_STATE()
ELSE(LIBLZMA_FOUND)
# LZMA not found and will not be used.
ENDIF(LIBLZMA_FOUND)
@ -549,9 +551,11 @@ IF(LIBB2_FOUND)
SET(HAVE_BLAKE2_H 1)
SET(ARCHIVE_BLAKE2 FALSE)
LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
CHECK_FUNCTION_EXISTS(blake2sp_init HAVE_LIBB2)
CMAKE_POP_CHECK_STATE()
ELSE(LIBB2_FOUND)
SET(ARCHIVE_BLAKE2 TRUE)
ENDIF(LIBB2_FOUND)
@ -606,17 +610,18 @@ IF(ZSTD_FOUND)
SET(HAVE_ZSTD_H 1)
INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD)
#
# TODO: test for static library.
#
CMAKE_POP_CHECK_STATE()
ENDIF(ZSTD_FOUND)
MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY)
set(CMAKE_REQUIRED_LIBRARIES)
#
# Check headers

View File

@ -288,6 +288,7 @@ libarchive_man_MANS= \
libarchive/archive_entry.3 \
libarchive/archive_entry_acl.3 \
libarchive/archive_entry_linkify.3 \
libarchive/archive_entry_misc.3 \
libarchive/archive_entry_paths.3 \
libarchive/archive_entry_perms.3 \
libarchive/archive_entry_stat.3 \
@ -501,6 +502,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_tar_concatenated.c \
libarchive/test/test_read_format_tar_empty_pax.c \
libarchive/test/test_read_format_tar_empty_filename.c \
libarchive/test/test_read_format_tar_empty_with_gnulabel.c \
libarchive/test/test_read_format_tar_filename.c \
libarchive/test/test_read_format_tbz.c \
libarchive/test/test_read_format_tgz.c \
@ -511,10 +513,12 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_warc.c \
libarchive/test/test_read_format_xar.c \
libarchive/test/test_read_format_zip.c \
libarchive/test/test_read_format_zip_7075_utf8_paths.c \
libarchive/test/test_read_format_zip_comment_stored.c \
libarchive/test/test_read_format_zip_encryption_data.c \
libarchive/test/test_read_format_zip_encryption_partially.c \
libarchive/test/test_read_format_zip_encryption_header.c \
libarchive/test/test_read_format_zip_extra_padding.c \
libarchive/test/test_read_format_zip_filename.c \
libarchive/test/test_read_format_zip_high_compression.c \
libarchive/test/test_read_format_zip_jar.c \
@ -721,6 +725,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_filter_lzop.tar.lzo.uu \
libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu \
libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu \
libarchive/test/test_read_format_mtree_noprint.mtree.uu \
libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu \
@ -820,15 +825,51 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu \
libarchive/test/test_read_format_rar_noeof.rar.uu \
libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \
libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu \
libarchive/test/test_read_format_rar_sfx.exe.uu \
libarchive/test/test_read_format_rar_subblock.rar.uu \
libarchive/test/test_read_format_rar_unicode.rar.uu \
libarchive/test/test_read_format_rar_windows.rar.uu \
libarchive/test/test_read_format_rar5_arm.rar.uu \
libarchive/test/test_read_format_rar5_blake2.rar.uu \
libarchive/test/test_read_format_rar5_compressed.rar.uu \
libarchive/test/test_read_format_rar5_distance_overflow.rar.uu \
libarchive/test/test_read_format_rar5_extra_field_version.rar.uu \
libarchive/test/test_read_format_rar5_fileattr.rar.uu \
libarchive/test/test_read_format_rar5_hardlink.rar.uu \
libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu \
libarchive/test/test_read_format_rar5_leftshift1.rar.uu \
libarchive/test/test_read_format_rar5_leftshift2.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part02.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part03.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part04.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part05.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part06.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part07.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part08.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part01.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part02.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part03.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part04.rar.uu \
libarchive/test/test_read_format_rar5_multiple_files.rar.uu \
libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu \
libarchive/test/test_read_format_rar5_nonempty_dir_stream.rar.uu \
libarchive/test/test_read_format_rar5_owner.rar.uu \
libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu \
libarchive/test/test_read_format_rar5_solid.rar.uu \
libarchive/test/test_read_format_rar5_stored.rar.uu \
libarchive/test/test_read_format_rar5_stored_manyfiles.rar.uu \
libarchive/test/test_read_format_rar5_symlink.rar.uu \
libarchive/test/test_read_format_rar5_truncated_huff.rar.uu \
libarchive/test/test_read_format_rar5_win32.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 \
libarchive/test/test_read_format_raw.data.uu \
libarchive/test/test_read_format_tar_concatenated.tar.uu \
libarchive/test/test_read_format_tar_empty_filename.tar.uu \
libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu \
libarchive/test/test_read_format_tar_empty_pax.tar.Z.uu \
libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \
@ -836,11 +877,16 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_warc.warc.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_bz2_hang.zip.uu \
libarchive/test/test_read_format_zip_bzip2.zipx.uu \
libarchive/test/test_read_format_zip_bzip2_multi.zipx.uu \
libarchive/test/test_read_format_zip_comment_stored_1.zip.uu \
libarchive/test/test_read_format_zip_comment_stored_2.zip.uu \
libarchive/test/test_read_format_zip_encryption_data.zip.uu \
libarchive/test/test_read_format_zip_encryption_header.zip.uu \
libarchive/test/test_read_format_zip_encryption_partially.zip.uu \
libarchive/test/test_read_format_zip_extra_padding.zip.uu \
libarchive/test/test_read_format_zip_filename_cp866.zip.uu \
libarchive/test/test_read_format_zip_filename_cp932.zip.uu \
libarchive/test/test_read_format_zip_filename_koi8r.zip.uu \
@ -849,6 +895,9 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \
libarchive/test/test_read_format_zip_high_compression.zip.uu \
libarchive/test/test_read_format_zip_length_at_end.zip.uu \
libarchive/test/test_read_format_zip_lzma.zipx.uu \
libarchive/test/test_read_format_zip_lzma_alone_leak.zipx.uu \
libarchive/test/test_read_format_zip_lzma_multi.zipx.uu \
libarchive/test/test_read_format_zip_jar.jar.uu \
libarchive/test/test_read_format_zip_mac_metadata.zip.uu \
libarchive/test/test_read_format_zip_malformed1.zip.uu \
@ -858,6 +907,10 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_zip_padded1.zip.uu \
libarchive/test/test_read_format_zip_padded2.zip.uu \
libarchive/test/test_read_format_zip_padded3.zip.uu \
libarchive/test/test_read_format_zip_ppmd8.zipx.uu \
libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu \
libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu \
libarchive/test/test_read_format_zip_ppmd8_multi.zipx.uu \
libarchive/test/test_read_format_zip_sfx.uu \
libarchive/test/test_read_format_zip_symlink.zip.uu \
libarchive/test/test_read_format_zip_traditional_encryption_data.zip.uu \
@ -867,6 +920,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_zip_winzip_aes256_large.zip.uu \
libarchive/test/test_read_format_zip_winzip_aes256_stored.zip.uu \
libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.zip.uu \
libarchive/test/test_read_format_zip_xz_multi.zipx.uu \
libarchive/test/test_read_format_zip_zip64a.zip.uu \
libarchive/test/test_read_format_zip_zip64b.zip.uu \
libarchive/test/test_read_large_splitted_rar_aa.uu \
@ -995,6 +1049,7 @@ bsdtar_test_SOURCES= \
tar/test/test_option_b.c \
tar/test/test_option_b64encode.c \
tar/test/test_option_exclude.c \
tar/test/test_option_exclude_vcs.c \
tar/test/test_option_fflags.c \
tar/test/test_option_gid_gname.c \
tar/test/test_option_grzip.c \

10
NEWS
View File

@ -1,3 +1,13 @@
Apr 16, 2019: Support for non-recursive list and extract
Apr 14, 2019: New tar option: --exclude-vcs
Mar 27, 2019: Support for file and directory symlinks on Windows
Mar 12, 2019: Important fixes for storing file attributes and flags
Jan 20, 2019: Support for xz, lzma, ppmd8 and bzip2 compression in zip archives
Oct 06, 2018: RAR 5.0 reader
Sep 03, 2018: libarchive 3.3.3 released

View File

@ -8,11 +8,13 @@
# SRCDIR= # source directory
# CONFIGURE_ARGS= # configure arguments
# MAKE_ARGS= # make arguments
# DEBUG= # set -g -fsanitize=address flags
ACTIONS=
if [ -n "${BUILD_SYSTEM}" ]; then
BS="${BUILD_SYSTEM}"
fi
BS="${BS:-autotools}"
MAKE="${MAKE:-make}"
CMAKE="${CMAKE:-cmake}"
@ -21,7 +23,7 @@ SRCDIR="${SRCDIR:-`pwd`}"
RET=0
usage () {
echo "Usage: $0 [-b autotools|cmake] [-a autogen|configure|build|test ] [ -a ... ] [ -d builddir ] [-s srcdir ]"
echo "Usage: $0 [-b autotools|cmake] [-a autogen|configure|build|test|install|distcheck ] [ -a ... ] [ -d builddir ] [-s srcdir ]"
}
inputerror () {
echo $1
@ -36,6 +38,8 @@ while getopts a:b:d:s: opt; do
configure) ;;
build) ;;
test) ;;
install) ;;
distcheck) ;;
*) inputerror "Invalid action (-a)" ;;
esac
ACTIONS="${ACTIONS} ${OPTARG}"
@ -58,8 +62,25 @@ while getopts a:b:d:s: opt; do
;;
esac
done
if [ -z "${MAKE_ARGS}" ]; then
if [ "${BS}" = "autotools" ]; then
MAKE_ARGS="V=1"
elif [ "${BS}" = "cmake" ]; then
MAKE_ARGS="VERBOSE=1"
fi
fi
if [ -n "${DEBUG}" ]; then
if [ -n "${CFLAGS}" ]; then
export CFLAGS="${CFLAGS} -g -fsanitize=address"
else
export CFLAGS="-g -fsanitize=address"
fi
if ["${BS}" = "cmake" ]; then
CONFIGURE_ARGS="${CONFIGURE_ARGS} -DCMAKE_C_CFLAGS=-g -fsanitize=address"
fi
fi
if [ -z "${ACTIONS}" ]; then
ACTIONS="autogen configure build test"
ACTIONS="autogen configure build test install"
fi
if [ -z "${BS}" ]; then
inputerror "Missing build system (-b) parameter"
@ -103,6 +124,15 @@ for action in ${ACTIONS}; do
RET="$?"
find ${TMPDIR:-/tmp} -path '*_test.*' -name '*.log' -print -exec cat {} \;
;;
install)
${MAKE} ${MAKE_ARGS} install DESTDIR="${BUILDDIR}/destdir"
RET="$?"
cd ${BUILDDIR}/destdir && ls -lR .
;;
distcheck)
${MAKE} ${MAKE_ARGS} distcheck
RET="$?"
;;
esac
if [ "${RET}" != "0" ]; then
exit "${RET}"

View File

@ -0,0 +1,4 @@
FROM cirrusci/windowsservercore:2019
RUN choco install -y --no-progress cygwin
RUN C:\tools\cygwin\cygwinsetup.exe -q -P make,autoconf,automake,cmake,gcc-core,binutils,libtool,pkg-config,bison,sharutils,zlib-devel,libbz2-devel,liblzma-devel,liblz4-devel,libiconv-devel,libxml2-devel,libzstd-devel,libssl-devel

View File

@ -0,0 +1,3 @@
FROM fedora:29
RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel

View File

@ -0,0 +1,3 @@
FROM fedora:29
RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel groff ghostscript

View File

@ -0,0 +1,8 @@
FROM cirrusci/windowsservercore:2019
RUN choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=User' cmake
RUN choco install -y --no-progress mingw
RUN curl -o zlib-1.2.11.tar.gz https://www.zlib.net/zlib-1.2.11.tar.gz
RUN tar -x -f zlib-1.2.11.tar.gz
RUN cd zlib-1.2.11 && cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE="Release" . && mingw32-make && mingw32-make install
RUN del /f /q /s zlib-1.2.11 zlib-1.2.11.tar.gz

View File

@ -0,0 +1,9 @@
FROM cirrusci/windowsservercore:2019
RUN choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=User' cmake
RUN choco install -y --no-progress visualstudio2017community
RUN choco install -y --no-progress visualstudio2017-workload-vctools
RUN curl -o zlib-1.2.11.tar.gz https://www.zlib.net/zlib-1.2.11.tar.gz
RUN tar -x -f zlib-1.2.11.tar.gz
RUN cd zlib-1.2.11 && cmake -G "Visual Studio 15 2017" . && cmake --build . --target ALL_BUILD --config Release && cmake --build . --target INSTALL --config Release
RUN del /f /q /s zlib-1.2.11 zlib-1.2.11.tar.gz

View File

@ -0,0 +1,12 @@
FROM cirrusci/windowsservercore:2019
RUN choco install -y --no-progress mingw
RUN choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=User' cmake
RUN choco install -y --no-progress visualstudio2017community
RUN choco install -y --no-progress visualstudio2017-workload-vctools
RUN curl -o zlib-1.2.11.tar.gz https://www.zlib.net/zlib-1.2.11.tar.gz
RUN tar -x -f zlib-1.2.11.tar.gz
RUN cd zlib-1.2.11 && cmake -G "Visual Studio 15 2017" . && cmake --build . --target ALL_BUILD --config Release && cmake --build . --target INSTALL --config Release
RUN del /f /q /s zlib-1.2.11 zlib-1.2.11.tar.gz
RUN choco install -y --no-progress cygwin
RUN C:\tools\cygwin\cygwinsetup.exe -q -P make,autoconf,automake,cmake,gcc-core,binutils,libtool,pkg-config,bison,sharutils,zlib-devel,libbz2-devel,liblzma-devel,liblz4-devel,libiconv-devel,libxml2-devel,libzstd-devel,libssl-devel

122
build/ci/cirrus_ci/ci.cmd Executable file
View File

@ -0,0 +1,122 @@
@ECHO OFF
SET ZLIB_VERSION=1.2.11
IF NOT "%BE%"=="cygwin-gcc" (
IF NOT "%BE%"=="mingw-gcc" (
IF NOT "%BE%"=="msvc" (
ECHO Environment variable BE must be cygwin-gcc, mingw-gcc or msvc
EXIT /b 1
)
)
)
IF "%1%"=="prepare" (
IF "%BE%"=="cygwin-gcc" (
@ECHO ON
choco install -y --no-progress cygwin || EXIT /b 1
C:\tools\cygwin\cygwinsetup.exe -q -P make,autoconf,automake,cmake,gcc-core,binutils,libtool,pkg-config,bison,sharutils,zlib-devel,libbz2-devel,liblzma-devel,liblz4-devel,libiconv-devel,libxml2-devel,libzstd-devel,libssl-devel || EXIT /b 1
@EXIT /b 0
) ELSE IF "%BE%"=="mingw-gcc" (
@ECHO ON
choco install -y --no-progress mingw || EXIT /b 1
choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=System' cmake || EXIT /b 1
@EXIT /b 0
) ELSE IF "%BE%"=="msvc" (
@ECHO ON
choco install -y --no-progress visualstudio2017community || EXIT /b 1
choco install -y --no-progress visualstudio2017-workload-vctools || EXIT /b 1
choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=System' cmake || EXIT /b 1
)
) ELSE IF "%1"=="deplibs" (
IF "%BE%"=="cygwin-gcc" (
ECHO Skipping on this platform
EXIT /b 0
)
IF NOT EXIST build_ci\libs (
MKDIR build_ci\libs
)
CD build_ci\libs
IF NOT EXIST zlib-%ZLIB_VERSION%.tar.gz (
curl -o zlib-%ZLIB_VERSION%.tar.gz https://www.zlib.net/zlib-%ZLIB_VERSION%.tar.gz
)
IF NOT EXIST zlib-%ZLIB_VERSION% (
tar -x -z -f zlib-%ZLIB_VERSION%.tar.gz
)
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD zlib-%ZLIB_VERSION%
IF "%BE%"=="mingw-gcc" (
cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE="Release" . || EXIT /b 1
mingw32-make || EXIT /b 1
mingw32-make test || EXIT /b 1
mingw32-make install || EXIT /b 1
) ELSE IF "%BE%"=="msvc" (
cmake -G "Visual Studio 15 2017" . || EXIT /b 1
cmake --build . --target ALL_BUILD --config Release || EXIT /b 1
cmake --build . --target RUN_TESTS --config Release || EXIT /b 1
cmake --build . --target INSTALL --config Release || EXIT /b 1
)
) ELSE IF "%1%"=="configure" (
IF "%BE%"=="cygwin-gcc" (
SET BS=cmake
SET CONFIGURE_ARGS=-DENABLE_ACL=OFF
C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a configure" || EXIT /b 1
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
MKDIR build_ci\cmake
CD build_ci\cmake
cmake -G "MinGW Makefiles" ..\.. || EXIT /b 1
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
MKDIR build_ci\cmake
CD build_ci\cmake
cmake -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPE="Release" ..\.. || EXIT /b 1
)
) ELSE IF "%1%"=="build" (
IF "%BE%"=="cygwin-gcc" (
SET BS=cmake
C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a build"
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD build_ci\cmake
mingw32-make || EXIT /b 1
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD build_ci\cmake
cmake --build . --target ALL_BUILD --config Release
)
) ELSE IF "%1%"=="test" (
IF "%BE%"=="cygwin-gcc" (
ECHO "Skipping tests on this platform"
EXIT /b 0
REM SET BS=cmake
REM SET SKIP_TEST_SPARSE=1
REM C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a test"
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
COPY "C:\Program Files (x86)\zlib\bin\libzlib.dll" build_ci\cmake\bin\
CD build_ci\cmake
SET SKIP_TEST_SPARSE=1
mingw32-make test
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
ECHO "Skipping tests on this platform"
EXIT /b 0
REM CD build_ci\cmake
REM cmake --build . --target RUN_TESTS --config Release
)
) ELSE IF "%1%"=="install" (
IF "%BE%"=="cygwin-gcc" (
SET BS=cmake
C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a install"
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD build_ci\cmake
mingw32-make install DESTDIR=%cd%\destdir
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
cmake --build . --target INSTALL --config Release
)
) ELSE (
ECHO "Usage: %0% prepare|deplibs|configure|build|test|install"
@EXIT /b 0
)
@EXIT /b 0

View File

@ -1,6 +1,6 @@
#!/bin/sh
UNAME=`uname`
if [ "$1" = "install" ]
if [ "$1" = "prepare" ]
then
if [ "${UNAME}" = "FreeBSD" ]
then
@ -17,8 +17,11 @@ then
elif [ "${UNAME}" = "Darwin" ]
then
set -x -e
brew update
brew install autoconf automake libtool pkg-config cmake xz lz4 zstd
brew update > /dev/null
for pkg in autoconf automake libtool pkg-config cmake xz lz4 zstd
do
brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg
done
elif [ "${UNAME}" = "Linux" ]
then
if [ -f "/etc/debian_version" ]
@ -48,6 +51,6 @@ then
TMPDIR=/tmp_acl_nfsv4 ${BIN_SUBDIR}/libarchive_test -r "${CURDIR}/libarchive/test" -v test_acl_platform_nfs4
fi
else
echo "Usage $0 install | test_nfsv4_acls"
echo "Usage $0 prepare | test_nfsv4_acls"
exit 1
fi

View File

@ -15,13 +15,14 @@ case "$UNAME" in
cmake -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPE="Release" "${SRCDIR}"
cmake --build . --target ALL_BUILD
# Until fixed, we don't run tests on Windows (lots of fails + timeout)
#export SKIP_TEST_FUZZ=1
#cmake --build . --target RUN_TESTS
set +x
elif [ "${BS}" = "mingw" ]; then
set -x
cmake -G "MSYS Makefiles" -D CMAKE_C_COMPILER="${CC}" -D CMAKE_MAKE_PROGRAM="mingw32-make" -D CMAKE_BUILD_TYPE="Release" "${SRCDIR}"
mingw32-make
# The MinGW tests time out on Travis CI, disable for now
#export SKIP_TEST_FUZZ=1
#mingw32-make test
set +x
else

218
contrib/archivetest.c Normal file
View File

@ -0,0 +1,218 @@
/*-
* Copyright (c) 2019 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Archivetest verifies reading archives with libarchive
*
* It may be used to reproduce failures in testcases discovered by OSS-Fuzz
* https://github.com/google/oss-fuzz/blob/master/projects/libarchive
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <archive.h>
#include <archive_entry.h>
const char *errnostr(int errno)
{
char *estr;
switch(errno) {
case ARCHIVE_EOF:
estr = "ARCHIVE_EOF";
break;
case ARCHIVE_OK:
estr = "ARCHIVE_OK";
break;
case ARCHIVE_WARN:
estr = "ARCHIVE_WARN";
break;
case ARCHIVE_RETRY:
estr = "ARCHIVE_RETRY";
break;
case ARCHIVE_FAILED:
estr = "ARCHIVE_FAILED";
break;
case ARCHIVE_FATAL:
estr = "ARCHIVE_FATAL";
break;
default:
estr = "Unknown";
break;
}
return (estr);
}
void usage(const char *prog)
{
fprintf(stderr, "Usage: %s [-f filename] [-h] [-q] [-s]\n", prog);
}
void printhelp()
{
fprintf(stdout, "archivetest: verify reading archives with "
"libarchive\n\n"
"Options:\n"
" -f filename Filename to verify\n"
" -h Show this help\n"
" -q Quiet mode\n"
" -s Verify only headers (skip data)\n\n"
"If no filename is specified, data is read from standard input.\n"
"\n%s\n", archive_version_details());
}
int v_print(int verbose, const char *format, ...)
{
int r = 0;
if (verbose) {
va_list args;
va_start(args, format);
r = vfprintf(stdout, format, args);
va_end(args);
}
return (r);
}
int main(int argc, char *argv[])
{
struct archive *a;
struct archive_entry *entry;
char *filename;
const char *p;
char buffer[4096];
int c;
int v, skip_data;
int r = ARCHIVE_OK;
int format_printed;
filename = NULL;
skip_data = 0;
v = 1;
while ((c = getopt (argc, argv, "f:hqs")) != -1) {
switch (c) {
case 'f':
filename = optarg;
break;
case 'h':
printhelp();
exit(0);
case 'q':
v = 0;
break;
case 's':
skip_data = 1;
break;
case '?':
if (optopt == 'f')
fprintf(stderr, "Option -%c requires "
"an argument.\n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option '-%c'"
".\n", optopt);
else
fprintf(stderr, "Unknown option "
"character '\\x%x'.\n", optopt);
usage(argv[0]);
default:
exit(1);
}
}
a = archive_read_new();
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
v_print(v, "Data source: ");
if (filename == NULL) {
v_print(v, "standard input\n");
r = archive_read_open_fd(a, STDIN_FILENO, 4096);
} else {
v_print(v, "filename: %s\n", filename);
r = archive_read_open_filename(a, filename, 4096);
}
if (r != ARCHIVE_OK) {
archive_read_free(a);
fprintf(stderr, "Invalid or unsupported data source\n");
exit(1);
}
format_printed = 0;
c = 1;
while (1) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_FATAL) {
v_print(v, "Entry %d: fatal error reading "
"header\n", c);
break;
}
if (!format_printed) {
v_print(v, "Filter: %s\nFormat: %s\n",
archive_filter_name(a, 0), archive_format_name(a));
format_printed = 1;
}
if (r == ARCHIVE_RETRY)
continue;
if (r == ARCHIVE_EOF)
break;
p = archive_entry_pathname(entry);
v_print(v, "Entry %d: %s, pathname", c, errnostr(r));
if (p == NULL || p[0] == '\0')
v_print(v, " unreadable");
else
v_print(v, ": %s", p);
v_print(v, ", data: ");
if (skip_data) {
v_print(v, "skipping");
} else {
while ((r = archive_read_data(a, buffer, 4096) > 0))
;
if (r == ARCHIVE_FATAL) {
v_print(v, "ERROR\nError string: %s\n",
archive_error_string(a));
break;
}
v_print(v, "OK");
}
v_print(v, "\n");
c++;
}
v_print(v, "Last return code: %s (%d)\n", errnostr(r), r);
if (r == ARCHIVE_EOF || r == ARCHIVE_OK) {
archive_read_free(a);
exit(0);
}
v_print(v, "Error string: %s\n", archive_error_string(a));
archive_read_free(a);
exit(2);
}

View File

@ -46,7 +46,7 @@ verify_files(const char *msg)
/* Symlink */
if (canSymlink())
assertIsSymlink("symlink", "file");
assertIsSymlink("symlink", "file", 0);
/* Another file with 1 link and different permissions. */
failure(msg);
@ -173,7 +173,7 @@ DEFINE_TEST(test_basic)
/* Symlink to above file. */
if (canSymlink()) {
assertMakeSymlink("symlink", "file");
assertMakeSymlink("symlink", "file", 0);
fprintf(filelist, "symlink\n");
if (is_LargeInode("symlink")) {
strncat(result,

View File

@ -114,7 +114,7 @@ DEFINE_TEST(test_format_newc)
/* "symlink" */
if (canSymlink()) {
assertMakeSymlink("symlink", "file1");
assertMakeSymlink("symlink", "file1", 0);
fprintf(list, "symlink\n");
}
@ -233,7 +233,12 @@ DEFINE_TEST(test_format_newc)
assert(is_hex(e, 110));
assertEqualMem(e + 0, "070701", 6); /* Magic */
assert(is_hex(e + 6, 8)); /* ino */
#if defined(_WIN32) && !defined(CYGWIN)
/* Mode: Group members bits and others bits do not work. */
assertEqualInt(0xa180, from_hex(e + 14, 8) & 0xffc0);
#else
assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
#endif
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
assertEqualMem(e + 38, "00000001", 8); /* nlink */

View File

@ -71,7 +71,7 @@ unpack_test(const char *from, const char *options, const char *se)
/* Symlink */
if (canSymlink())
assertIsSymlink("symlink", "file");
assertIsSymlink("symlink", "file", 0);
/* dir */
assertIsDir("dir", 0775);

View File

@ -30,8 +30,10 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_L.c,v 1.2 2008/08/24 06:21
* tests won't run on Windows. */
#if defined(_WIN32) && !defined(__CYGWIN__)
#define CAT "type"
#define SEP "\\"
#else
#define CAT "cat"
#define SEP "/"
#endif
DEFINE_TEST(test_option_L_upper)
@ -51,7 +53,7 @@ DEFINE_TEST(test_option_L_upper)
fprintf(filelist, "file\n");
/* Symlink to above file. */
assertMakeSymlink("symlink", "file");
assertMakeSymlink("symlink", "file", 0);
fprintf(filelist, "symlink\n");
fclose(filelist);
@ -61,7 +63,7 @@ DEFINE_TEST(test_option_L_upper)
assertTextFileContents("1 block\n", "copy.err");
failure("Regular -p without -L should preserve symlinks.");
assertIsSymlink("copy/symlink", NULL);
assertIsSymlink("copy/symlink", NULL, 0);
r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
assertEqualInt(r, 0);
@ -77,13 +79,14 @@ DEFINE_TEST(test_option_L_upper)
assertMakeDir("unpack", 0755);
assertChdir("unpack");
r = systemf(CAT " ../archive.out | %s -i >unpack.out 2>unpack.err", testprog);
r = systemf(CAT " .." SEP "archive.out | %s -i >unpack.out 2>unpack.err", testprog);
failure("Error invoking %s -i", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "unpack.err");
assertChdir("..");
assertIsSymlink("unpack/symlink", NULL);
assertIsSymlink("unpack/symlink", NULL, 0);
r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
failure("Error invoking %s -oL", testprog);
@ -92,7 +95,8 @@ DEFINE_TEST(test_option_L_upper)
assertMakeDir("unpack-L", 0755);
assertChdir("unpack-L");
r = systemf(CAT " ../archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
r = systemf(CAT " .." SEP "archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
failure("Error invoking %s -i < archive-L.out", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "unpack-L.err");

View File

@ -71,8 +71,13 @@ test_create(void)
* #ifdef this section out. Most of the test below is
* still valid. */
memset(&times, 0, sizeof(times));
#if defined(_WIN32) && !defined(CYGWIN)
times.actime = 86400;
times.modtime = 86400;
#else
times.actime = 1;
times.modtime = 3;
#endif
assertEqualInt(0, utime(files[i].name, &times));
/* Record whatever atime the file ended up with. */

View File

@ -85,7 +85,7 @@ DEFINE_TEST(test_option_c)
/* "symlink" */
if (canSymlink()) {
assertMakeSymlink("symlink", "file");
assertMakeSymlink("symlink", "file", 0);
fprintf(filelist, "symlink\n");
}

View File

@ -170,6 +170,7 @@ SET(libarchive_MANS
archive_entry.3
archive_entry_acl.3
archive_entry_linkify.3
archive_entry_misc.3
archive_entry_paths.3
archive_entry_perms.3
archive_entry_stat.3

View File

@ -338,9 +338,9 @@ typedef const char *archive_passphrase_callback(struct archive *,
#define ARCHIVE_FORMAT_LHA 0xB0000
#define ARCHIVE_FORMAT_CAB 0xC0000
#define ARCHIVE_FORMAT_RAR 0xD0000
#define ARCHIVE_FORMAT_RAR_V5 (ARCHIVE_FORMAT_RAR | 1)
#define ARCHIVE_FORMAT_7ZIP 0xE0000
#define ARCHIVE_FORMAT_WARC 0xF0000
#define ARCHIVE_FORMAT_RAR_V5 0x100000
/*
* Codes returned by archive_read_format_capabilities().
@ -1095,6 +1095,8 @@ __LA_DECL int archive_match_excluded(struct archive *,
*/
__LA_DECL int archive_match_path_excluded(struct archive *,
struct archive_entry *);
/* Control recursive inclusion of directory content when directory is included. Default on. */
__LA_DECL int archive_match_set_inclusion_recursion(struct archive *, int);
/* Add exclusion pathname pattern. */
__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *);
__LA_DECL int archive_match_exclude_pattern_w(struct archive *,

View File

@ -168,6 +168,7 @@ archive_entry_clear(struct archive_entry *entry)
archive_entry_xattr_clear(entry);
archive_entry_sparse_clear(entry);
free(entry->stat);
entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
memset(entry, 0, sizeof(*entry));
return entry;
}
@ -202,6 +203,9 @@ archive_entry_clone(struct archive_entry *entry)
entry2->ae_set = entry->ae_set;
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
/* Copy symlink type */
entry2->ae_symlink_type = entry->ae_symlink_type;
/* Copy encryption status */
entry2->encryption = entry->encryption;
@ -253,6 +257,7 @@ archive_entry_new2(struct archive *a)
if (entry == NULL)
return (NULL);
entry->archive = a;
entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
return (entry);
}
@ -675,6 +680,12 @@ archive_entry_symlink(struct archive_entry *entry)
return (NULL);
}
int
archive_entry_symlink_type(struct archive_entry *entry)
{
return (entry->ae_symlink_type);
}
const char *
archive_entry_symlink_utf8(struct archive_entry *entry)
{
@ -1245,6 +1256,12 @@ archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
entry->ae_set &= ~AE_SET_SYMLINK;
}
void
archive_entry_set_symlink_type(struct archive_entry *entry, int type)
{
entry->ae_symlink_type = type;
}
void
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
{
@ -1749,6 +1766,10 @@ static const struct flag {
{ "nohidden", L"nohidden", UF_HIDDEN, 0},
{ "nouhidden", L"nouhidden", UF_HIDDEN, 0},
#endif
#ifdef FILE_ATTRIBUTE_HIDDEN
{ "nohidden", L"nohidden", FILE_ATTRIBUTE_HIDDEN, 0},
{ "nouhidden", L"nouhidden", FILE_ATTRIBUTE_HIDDEN, 0},
#endif
#ifdef UF_OFFLINE
{ "nooffline", L"nooffline", UF_OFFLINE, 0},
{ "nouoffline", L"nouoffline", UF_OFFLINE, 0},
@ -1758,6 +1779,11 @@ static const struct flag {
{ "nourdonly", L"nourdonly", UF_READONLY, 0},
{ "noreadonly", L"noreadonly", UF_READONLY, 0},
#endif
#ifdef FILE_ATTRIBUTE_READONLY
{ "nordonly", L"nordonly", FILE_ATTRIBUTE_READONLY, 0},
{ "nourdonly", L"nourdonly", FILE_ATTRIBUTE_READONLY, 0},
{ "noreadonly", L"noreadonly", FILE_ATTRIBUTE_READONLY, 0},
#endif
#ifdef UF_SPARSE
{ "nosparse", L"nosparse", UF_SPARSE, 0},
{ "nousparse", L"nousparse", UF_SPARSE, 0},
@ -1770,6 +1796,10 @@ static const struct flag {
{ "nosystem", L"nosystem", UF_SYSTEM, 0},
{ "nousystem", L"nousystem", UF_SYSTEM, 0},
#endif
#ifdef FILE_ATTRIBUTE_SYSTEM
{ "nosystem", L"nosystem", FILE_ATTRIBUTE_SYSTEM, 0},
{ "nousystem", L"nousystem", FILE_ATTRIBUTE_SYSTEM, 0},
#endif
#if defined(FS_UNRM_FL) /* 'u' */
{ "noundel", L"noundel", FS_UNRM_FL, 0},
#elif defined(EXT2_UNRM_FL)

View File

@ -190,6 +190,13 @@ struct archive_entry;
#define AE_IFDIR ((__LA_MODE_T)0040000)
#define AE_IFIFO ((__LA_MODE_T)0010000)
/*
* Symlink types
*/
#define AE_SYMLINK_TYPE_UNDEFINED 0
#define AE_SYMLINK_TYPE_FILE 1
#define AE_SYMLINK_TYPE_DIRECTORY 2
/*
* Basic object manipulation
*/
@ -275,6 +282,7 @@ __LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(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 *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
@ -350,6 +358,7 @@ __LA_DECL void archive_entry_unset_size(struct archive_entry *);
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int);
__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
@ -692,7 +701,6 @@ __LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
struct archive_entry **, struct archive_entry **);
__LA_DECL struct archive_entry *archive_entry_partial_links(
struct archive_entry_linkresolver *res, unsigned int *links);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,62 @@
.\" Copyright (c) 2019 Martin Matuska
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
.\"
.Dd April 15, 2019
.Dt ARCHIVE_ENTRY_MISC 3
.Os
.Sh NAME
.Nm archive_entry_symlink_type ,
.Nm archive_entry_set_symlink_type
.Nd miscellaneous functions for manipulating properties of archive_entry.
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS
.In archive_entry.h
.Ft int
.Fn archive_entry_symlink_type "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_symlink_type "struct archive_entry *a" "int"
.Sh DESCRIPTION
The function
.Fn archive_entry_symlink_type
returns and the function
.Fn archive_entry_set_symlink_type
sets the type of the symbolic link stored in an archive entry. These functions
have special meaning on operating systems that support multiple symbolic link
types (e.g. Microsoft Windows).
.Pp
Supported values are:
.Bl -tag -width "AE_SYMLINK_TYPE_DIRECTORY" -compact
.It AE_SYMLINK_TYPE_UNDEFINED
Symbolic link target type is not defined (default on unix systems)
.It AE_SYMLINK_TYPE_FILE
Symbolic link points to a file
.It AE_SYMLINK_TYPE_DIRECTORY
Symbolic link points to a directory
.El
.Sh SEE ALSO
.Xr archive_entry 3 ,
.Xr archive_entry_paths 3 ,
.Xr archive_entry_stat 3 ,
.Xr libarchive 3

View File

@ -176,6 +176,9 @@ struct archive_entry {
/* Miscellaneous. */
char strmode[12];
/* Symlink type support */
int ae_symlink_type;
};
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

View File

@ -83,6 +83,7 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
{
#pragma GCC diagnostic ignored "-Wcast-qual"
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
DWORD hash_len;

View File

@ -93,6 +93,9 @@ struct archive_match {
/* exclusion/inclusion set flag. */
int setflag;
/* Recursively include directory content? */
int recursive_include;
/*
* Matching filename patterns.
*/
@ -223,6 +226,7 @@ archive_match_new(void)
return (NULL);
a->archive.magic = ARCHIVE_MATCH_MAGIC;
a->archive.state = ARCHIVE_STATE_NEW;
a->recursive_include = 1;
match_list_init(&(a->inclusions));
match_list_init(&(a->exclusions));
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
@ -470,6 +474,28 @@ archive_match_path_excluded(struct archive *_a,
#endif
}
/*
* When recursive inclusion of directory content is enabled,
* an inclusion pattern that matches a directory will also
* include everything beneath that directory. Enabled by default.
*
* For compatibility with GNU tar, exclusion patterns always
* match if a subset of the full patch matches (i.e., they are
* are not rooted at the beginning of the path) and thus there
* is no corresponding non-recursive exclusion mode.
*/
int
archive_match_set_inclusion_recursion(struct archive *_a, int enabled)
{
struct archive_match *a;
archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
ARCHIVE_STATE_NEW, "archive_match_set_inclusion_recursion");
a = (struct archive_match *)_a;
a->recursive_include = enabled;
return (ARCHIVE_OK);
}
/*
* Utility functions to get statistic information for inclusion patterns.
*/
@ -781,7 +807,10 @@ static int
match_path_inclusion(struct archive_match *a, struct match *m,
int mbs, const void *pn)
{
int flag = PATHMATCH_NO_ANCHOR_END;
/* Recursive operation requires only a prefix match. */
int flag = a->recursive_include ?
PATHMATCH_NO_ANCHOR_END :
0;
int r;
if (mbs) {
@ -1232,7 +1261,7 @@ set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
return (ARCHIVE_FAILED);
}
if (stat(path, &st) != 0) {
if (la_stat(path, &st) != 0) {
archive_set_error(&(a->archive), errno, "Failed to stat()");
return (ARCHIVE_FAILED);
}

View File

@ -69,6 +69,8 @@
* either Windows or Posix APIs. */
#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
#include "archive_windows.h"
#else
#define la_stat(path,stref) stat(path,stref)
#endif
/*

View File

@ -611,6 +611,15 @@ choose_filters(struct archive_read *a)
return (ARCHIVE_FATAL);
}
int
__archive_read_header(struct archive_read *a, struct archive_entry *entry)
{
if (a->filter->read_header)
return a->filter->read_header(a->filter, entry);
else
return (ARCHIVE_OK);
}
/*
* Read header of next entry.
*/

View File

@ -191,7 +191,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
}
} else
#endif
if (stat(path, &s) != 0) {
if (la_stat(path, &s) != 0) {
archive_set_error(&a->archive, errno,
"Can't stat %s", path);
return (ARCHIVE_FAILED);

View File

@ -909,7 +909,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
}
}
break;
}
}
} while (lst == NULL);
#ifdef __APPLE__
@ -1295,10 +1295,23 @@ archive_read_disk_descend(struct archive *_a)
if (t->visit_type != TREE_REGULAR || !t->descend)
return (ARCHIVE_OK);
/*
* We must not treat the initial specified path as a physical dir,
* because if we do then we will try and ascend out of it by opening
* ".." which is (a) wrong and (b) causes spurious permissions errors
* if ".." is not readable by us. Instead, treat it as if it were a
* symlink. (This uses an extra fd, but it can only happen once at the
* top level of a traverse.) But we can't necessarily assume t->st is
* valid here (though t->lst is), which complicates the logic a
* little.
*/
if (tree_current_is_physical_dir(t)) {
tree_push(t, t->basename, t->current_filesystem_id,
t->lst.st_dev, t->lst.st_ino, &t->restore_time);
t->stack->flags |= isDir;
if (t->stack->parent->parent != NULL)
t->stack->flags |= isDir;
else
t->stack->flags |= isDirLink;
} else if (tree_current_is_dir(t)) {
tree_push(t, t->basename, t->current_filesystem_id,
t->st.st_dev, t->st.st_ino, &t->restore_time);
@ -2151,6 +2164,17 @@ tree_open(const char *path, int symlink_mode, int restore_time)
static struct tree *
tree_reopen(struct tree *t, const char *path, int restore_time)
{
#if defined(O_PATH)
/* Linux */
const int o_flag = O_PATH;
#elif defined(O_SEARCH)
/* SunOS */
const int o_flag = O_SEARCH;
#elif defined(O_EXEC)
/* FreeBSD */
const int o_flag = O_EXEC;
#endif
t->flags = (restore_time != 0)?needsRestoreTimes:0;
t->flags |= onInitialDir;
t->visit_type = 0;
@ -2172,6 +2196,15 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
t->stack->flags = needsFirstVisit;
t->maxOpenCount = t->openCount = 1;
t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
/*
* Most likely reason to fail opening "." is that it's not readable,
* so try again for execute. The consequences of not opening this are
* unhelpful and unnecessary errors later.
*/
if (t->initial_dir_fd < 0)
t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
#endif
__archive_ensure_cloexec_flag(t->initial_dir_fd);
t->working_dir_fd = tree_dup(t->initial_dir_fd);
return (t);
@ -2479,7 +2512,7 @@ tree_current_stat(struct tree *t)
#else
if (tree_enter_working_dir(t) != 0)
return NULL;
if (stat(tree_current_access_path(t), &t->st) != 0)
if (la_stat(tree_current_access_path(t), &t->st) != 0)
#endif
return NULL;
t->flags |= hasStat;

View File

@ -299,8 +299,155 @@ static int close_and_restore_time(HANDLE, struct tree *,
struct restore_time *);
static int setup_sparse_from_disk(struct archive_read_disk *,
struct archive_entry *, HANDLE);
static int la_linkname_from_handle(HANDLE, wchar_t **, int *);
static int la_linkname_from_pathw(const wchar_t *, wchar_t **, int *);
static void entry_symlink_from_pathw(struct archive_entry *,
const wchar_t *path);
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags;
WCHAR PathBuffer[1];
} SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[1];
} MountPointReparseBuffer;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
} DUMMYUNIONNAME;
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
/*
* Reads the target of a symbolic link
*
* Returns 0 on success and -1 on failure
* outbuf is allocated in the function
*/
static int
la_linkname_from_handle(HANDLE h, wchar_t **linkname, int *linktype)
{
DWORD inbytes;
REPARSE_DATA_BUFFER *buf;
BY_HANDLE_FILE_INFORMATION st;
size_t len;
BOOL ret;
BYTE *indata;
wchar_t *tbuf;
ret = GetFileInformationByHandle(h, &st);
if (ret == 0 ||
(st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
return (-1);
}
indata = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
ret = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, indata,
1024, &inbytes, NULL);
if (ret == 0) {
la_dosmaperr(GetLastError());
free(indata);
return (-1);
}
buf = (REPARSE_DATA_BUFFER *) indata;
if (buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
free(indata);
/* File is not a symbolic link */
errno = EINVAL;
return (-1);
}
len = buf->SymbolicLinkReparseBuffer.SubstituteNameLength;
if (len <= 0) {
free(indata);
return (-1);
}
tbuf = malloc(len + 1 * sizeof(wchar_t));
if (tbuf == NULL) {
free(indata);
return (-1);
}
memcpy(tbuf, &((BYTE *)buf->SymbolicLinkReparseBuffer.PathBuffer)
[buf->SymbolicLinkReparseBuffer.SubstituteNameOffset], len);
free(indata);
tbuf[len / sizeof(wchar_t)] = L'\0';
*linkname = tbuf;
/*
* Translate backslashes to slashes for libarchive internal use
*/
while(*tbuf != L'\0') {
if (*tbuf == L'\\')
*tbuf = L'/';
tbuf++;
}
if ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
*linktype = AE_SYMLINK_TYPE_FILE;
else
*linktype = AE_SYMLINK_TYPE_DIRECTORY;
return (0);
}
/*
* Returns AE_SYMLINK_TYPE_FILE, AE_SYMLINK_TYPE_DIRECTORY or -1 on error
*/
static int
la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
{
HANDLE h;
const DWORD flag = FILE_FLAG_BACKUP_SEMANTICS |
FILE_FLAG_OPEN_REPARSE_POINT;
int ret;
h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag,
NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
return (-1);
}
ret = la_linkname_from_handle(h, outbuf, linktype);
CloseHandle(h);
return (ret);
}
static void
entry_symlink_from_pathw(struct archive_entry *entry, const wchar_t *path)
{
wchar_t *linkname = NULL;
int ret, linktype;
ret = la_linkname_from_pathw(path, &linkname, &linktype);
if (ret != 0)
return;
if (linktype >= 0) {
archive_entry_copy_symlink_w(entry, linkname);
archive_entry_set_symlink_type(entry, linktype);
}
free(linkname);
return;
}
static struct archive_vtable *
archive_read_disk_vtable(void)
@ -899,6 +1046,19 @@ next_entry(struct archive_read_disk *a, struct tree *t,
}
}
/*
* File attributes
*/
if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
const int supported_attrs =
FILE_ATTRIBUTE_READONLY |
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM;
DWORD file_attrs = st->dwFileAttributes & supported_attrs;
if (file_attrs != 0)
archive_entry_set_fflags(entry, file_attrs, 0);
}
/*
* Invoke a meta data filter callback.
*/
@ -1838,9 +1998,10 @@ entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
mode |= S_IWUSR | S_IWGRP | S_IWOTH;
if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
findData != NULL &&
findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
mode |= S_IFLNK;
else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry_symlink_from_pathw(entry, path);
} else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
else {
const wchar_t *p;
@ -2139,6 +2300,8 @@ archive_read_disk_entry_from_file(struct archive *_a,
fileAttributes = bhfi.dwFileAttributes;
} else {
archive_entry_copy_stat(entry, st);
if (st->st_mode & S_IFLNK)
entry_symlink_from_pathw(entry, path);
h = INVALID_HANDLE_VALUE;
}
@ -2150,6 +2313,19 @@ archive_read_disk_entry_from_file(struct archive *_a,
if (name != NULL)
archive_entry_copy_gname(entry, name);
/*
* File attributes
*/
if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
const int supported_attrs =
FILE_ATTRIBUTE_READONLY |
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM;
DWORD file_attrs = fileAttributes & supported_attrs;
if (file_attrs != 0)
archive_entry_set_fflags(entry, file_attrs, 0);
}
/*
* Can this file be sparse file ?
*/

View File

@ -98,6 +98,8 @@ struct archive_read_filter {
int (*close)(struct archive_read_filter *self);
/* Function that handles switching from reading one block to the next/prev */
int (*sswitch)(struct archive_read_filter *self, unsigned int iindex);
/* Read any header metadata if available. */
int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
/* My private data. */
void *data;
@ -250,6 +252,7 @@ int64_t __archive_read_seek(struct archive_read*, int64_t, int);
int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
int64_t __archive_read_consume(struct archive_read *, int64_t);
int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
int __archive_read_header(struct archive_read *, struct archive_entry *);
int __archive_read_program(struct archive_read_filter *, const char *);
void __archive_read_free_filters(struct archive_read *);
struct archive_read_extract *__archive_read_get_extract(struct archive_read *);

View File

@ -73,6 +73,9 @@ archive_read_set_format(struct archive *_a, int code)
case ARCHIVE_FORMAT_RAR:
strcpy(str, "rar");
break;
case ARCHIVE_FORMAT_RAR_V5:
strcpy(str, "rar5");
break;
case ARCHIVE_FORMAT_TAR:
strcpy(str, "tar");
break;

View File

@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@ -45,6 +48,8 @@ __FBSDID("$FreeBSD$");
#endif
#include "archive.h"
#include "archive_entry.h"
#include "archive_endian.h"
#include "archive_private.h"
#include "archive_read_private.h"
@ -56,6 +61,8 @@ struct private_data {
size_t out_block_size;
int64_t total_out;
unsigned long crc;
uint32_t mtime;
char *name;
char eof; /* True = found end of compressed data. */
};
@ -123,7 +130,8 @@ archive_read_support_filter_gzip(struct archive *_a)
* count of bits verified, suitable for use by bidder.
*/
static ssize_t
peek_at_header(struct archive_read_filter *filter, int *pbits)
peek_at_header(struct archive_read_filter *filter, int *pbits,
struct private_data *state)
{
const unsigned char *p;
ssize_t avail, len;
@ -144,7 +152,9 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
return (0);
bits += 3;
header_flags = p[3];
/* Bytes 4-7 are mod time. */
/* Bytes 4-7 are mod time in little endian. */
if (state)
state->mtime = archive_le32dec(p + 4);
/* Byte 8 is deflate flags. */
/* XXXX TODO: return deflate flags back to consume_header for use
in initializing the decompressor. */
@ -161,6 +171,7 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
/* Null-terminated optional filename. */
if (header_flags & 8) {
ssize_t file_start = len;
do {
++len;
if (avail < len)
@ -169,6 +180,12 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
if (p == NULL)
return (0);
} while (p[len - 1] != 0);
if (state) {
/* Reset the name in case of repeat header reads. */
free(state->name);
state->name = strdup((const char *)&p[file_start]);
}
}
/* Null-terminated optional comment. */
@ -214,11 +231,28 @@ gzip_bidder_bid(struct archive_read_filter_bidder *self,
(void)self; /* UNUSED */
if (peek_at_header(filter, &bits_checked))
if (peek_at_header(filter, &bits_checked, NULL))
return (bits_checked);
return (0);
}
static int
gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry)
{
struct private_data *state;
state = (struct private_data *)self->data;
/* A mtime of 0 is considered invalid/missing. */
if (state->mtime != 0)
archive_entry_set_mtime(entry, state->mtime, 0);
/* If the name is available, extract it. */
if (state->name)
archive_entry_set_pathname(entry, state->name);
return (ARCHIVE_OK);
}
#ifndef HAVE_ZLIB_H
@ -272,6 +306,7 @@ gzip_bidder_init(struct archive_read_filter *self)
self->read = gzip_filter_read;
self->skip = NULL; /* not supported */
self->close = gzip_filter_close;
self->read_header = gzip_read_header;
state->in_stream = 0; /* We're not actually within a stream yet. */
@ -289,7 +324,7 @@ consume_header(struct archive_read_filter *self)
state = (struct private_data *)self->data;
/* If this is a real header, consume it. */
len = peek_at_header(self->upstream, NULL);
len = peek_at_header(self->upstream, NULL, state);
if (len == 0)
return (ARCHIVE_EOF);
__archive_read_filter_consume(self->upstream, len);
@ -374,7 +409,7 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
{
struct private_data *state;
size_t decompressed;
ssize_t avail_in;
ssize_t avail_in, max_in;
int ret;
state = (struct private_data *)self->data;
@ -408,6 +443,12 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
"truncated gzip input");
return (ARCHIVE_FATAL);
}
if (UINT_MAX >= SSIZE_MAX)
max_in = SSIZE_MAX;
else
max_in = UINT_MAX;
if (avail_in > max_in)
avail_in = max_in;
state->stream.avail_in = (uInt)avail_in;
/* Decompress and consume some of that data. */
@ -469,6 +510,7 @@ gzip_filter_close(struct archive_read_filter *self)
}
}
free(state->name);
free(state->out_block);
free(state);
return (ret);

View File

@ -1509,8 +1509,8 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
}
if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
goto nomszip;
else if (cab->stream.next_in[0] != 0x43 ||
cab->stream.next_in[1] != 0x4b)
else if (mszip == 2 && (cab->stream.next_in[0] != 0x43 ||
cab->stream.next_in[1] != 0x4b))
goto nomszip;
cab->stream.next_in += mszip;
cab->stream.avail_in -= mszip;

View File

@ -45,6 +45,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#include "archive.h"
#include "archive_entry.h"
@ -1011,7 +1014,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
{
ssize_t len;
uintmax_t counter;
char *p;
char *p, *s;
struct mtree_option *global;
struct mtree_entry *last_entry;
int r, is_form_d;
@ -1025,6 +1028,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
(void)detect_form(a, &is_form_d);
for (counter = 1; ; ++counter) {
r = ARCHIVE_OK;
len = readline(a, mtree, &p, 65536);
if (len == 0) {
mtree->this_entry = mtree->entries;
@ -1045,6 +1049,15 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
continue;
if (*p == '\r' || *p == '\n' || *p == '\0')
continue;
/* Non-printable characters are not allowed */
for (s = p;s < p + len - 1; s++) {
if (!isprint(*s)) {
r = ARCHIVE_FATAL;
break;
}
}
if (r != ARCHIVE_OK)
break;
if (*p != '/') {
r = process_add_entry(a, mtree, &global, p, len,
&last_entry, is_form_d);

View File

@ -1024,8 +1024,10 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
case COMPRESS_METHOD_GOOD:
case COMPRESS_METHOD_BEST:
ret = read_data_compressed(a, buff, size, offset);
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
rar->start_new_table = 1;
}
break;
default:

File diff suppressed because it is too large Load Diff

View File

@ -120,7 +120,9 @@ archive_read_format_raw_read_header(struct archive_read *a,
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_perm(entry, 0644);
/* I'm deliberately leaving most fields unset here. */
return (ARCHIVE_OK);
/* Let the filter fill out any fields it might have. */
return __archive_read_header(a, entry);
}
static int

View File

@ -694,11 +694,13 @@ tar_read_header(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, size_t *unconsumed)
{
ssize_t bytes;
int err;
int err, eof_vol_header;
const char *h;
const struct archive_entry_header_ustar *header;
const struct archive_entry_header_gnutar *gnuheader;
eof_vol_header = 0;
/* Loop until we find a workable header record. */
for (;;) {
tar_flush_unconsumed(a, unconsumed);
@ -788,6 +790,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
break;
case 'V': /* GNU volume header */
err = header_volume(a, tar, entry, h, unconsumed);
if (err == ARCHIVE_EOF)
eof_vol_header = 1;
break;
case 'X': /* Used by SUN tar; same as 'x'. */
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
@ -862,9 +866,17 @@ tar_read_header(struct archive_read *a, struct tar *tar,
}
return (err);
}
if (err == ARCHIVE_EOF)
/* EOF when recursively reading a header is bad. */
archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
if (err == ARCHIVE_EOF) {
if (!eof_vol_header) {
/* EOF when recursively reading a header is bad. */
archive_set_error(&a->archive, EINVAL,
"Damaged tar archive");
} else {
/* If we encounter just a GNU volume header treat
* this situation as an empty archive */
return (ARCHIVE_EOF);
}
}
return (ARCHIVE_FATAL);
}
@ -1942,6 +1954,15 @@ pax_attribute(struct archive_read *a, struct tar *tar,
pax_time(value, &s, &n);
archive_entry_set_birthtime(entry, s, n);
}
if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) {
if (strcmp(value, "file") == 0) {
archive_entry_set_symlink_type(entry,
AE_SYMLINK_TYPE_FILE);
} else if (strcmp(value, "dir") == 0) {
archive_entry_set_symlink_type(entry,
AE_SYMLINK_TYPE_DIRECTORY);
}
}
if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
pax_attribute_xattr(entry, key, value);
break;

View File

@ -744,8 +744,9 @@ _warc_rdlen(const char *buf, size_t bsz)
/* there must be at least one digit */
if (!isdigit((unsigned char)*val))
return -1;
errno = 0;
len = strtol(val, &on, 10);
if (on != eol) {
if (errno != 0 || on != eol) {
/* line must end here */
return -1;
}

View File

@ -798,7 +798,8 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
xattr = file->xattr_list;
while (xattr != NULL) {
const void *d;
size_t outbytes, used;
size_t outbytes = 0;
size_t used = 0;
r = move_reading_point(a, xattr->offset);
if (r != ARCHIVE_OK)
@ -820,8 +821,18 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
r = checksum_final(a,
xattr->a_sum.val, xattr->a_sum.len,
xattr->e_sum.val, xattr->e_sum.len);
if (r != ARCHIVE_OK)
if (r != ARCHIVE_OK) {
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
"Xattr checksum error");
r = ARCHIVE_WARN;
break;
}
if (xattr->name.s == NULL) {
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
"Xattr name error");
r = ARCHIVE_WARN;
break;
}
archive_entry_xattr_add_entry(entry,
xattr->name.s, d, outbytes);
xattr = xattr->next;
@ -847,7 +858,7 @@ xar_read_data(struct archive_read *a,
const void **buff, size_t *size, int64_t *offset)
{
struct xar *xar;
size_t used;
size_t used = 0;
int r;
xar = (struct xar *)(a->format->data);

View File

@ -472,27 +472,49 @@ zip_time(const char *p)
* triplets. id and size are 2 bytes each.
*/
static int
process_extra(struct archive_read *a, const char *p, size_t extra_length, struct zip_entry* zip_entry)
process_extra(struct archive_read *a, struct archive_entry *entry,
const char *p, size_t extra_length, struct zip_entry* zip_entry)
{
unsigned offset = 0;
struct zip *zip = (struct zip *)(a->format->data);
if (extra_length == 0) {
return ARCHIVE_OK;
}
if (extra_length < 4) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Too-small extra data: Need at least 4 bytes, but only found %d bytes", (int)extra_length);
return ARCHIVE_FAILED;
size_t i = 0;
/* Some ZIP files may have trailing 0 bytes. Let's check they
* are all 0 and ignore them instead of returning an error.
*
* This is not techincally correct, but some ZIP files look
* like this and other tools support those files - so let's
* also support them.
*/
for (; i < extra_length; i++) {
if (p[i] != 0) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Too-small extra data: "
"Need at least 4 bytes, "
"but only found %d bytes",
(int)extra_length);
return ARCHIVE_FAILED;
}
}
return ARCHIVE_OK;
}
while (offset <= extra_length - 4) {
unsigned short headerid = archive_le16dec(p + offset);
unsigned short datasize = archive_le16dec(p + offset + 2);
offset += 4;
if (offset + datasize > extra_length) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Extra data overflow: Need %d bytes but only found %d bytes",
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT, "Extra data overflow: "
"Need %d bytes but only found %d bytes",
(int)datasize, (int)(extra_length - offset));
return ARCHIVE_FAILED;
}
@ -507,9 +529,12 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
if (zip_entry->uncompressed_size == 0xffffffff) {
uint64_t t = 0;
if (datasize < 8
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed 64-bit uncompressed size");
|| (t = archive_le64dec(p + offset)) >
INT64_MAX) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed 64-bit "
"uncompressed size");
return ARCHIVE_FAILED;
}
zip_entry->uncompressed_size = t;
@ -519,9 +544,12 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
if (zip_entry->compressed_size == 0xffffffff) {
uint64_t t = 0;
if (datasize < 8
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed 64-bit compressed size");
|| (t = archive_le64dec(p + offset)) >
INT64_MAX) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed 64-bit "
"compressed size");
return ARCHIVE_FAILED;
}
zip_entry->compressed_size = t;
@ -531,9 +559,12 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
if (zip_entry->local_header_offset == 0xffffffff) {
uint64_t t = 0;
if (datasize < 8
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed 64-bit local header offset");
|| (t = archive_le64dec(p + offset)) >
INT64_MAX) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed 64-bit "
"local header offset");
return ARCHIVE_FAILED;
}
zip_entry->local_header_offset = t;
@ -566,7 +597,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
/* Extended time field "UT". */
int flags;
if (datasize == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Incomplete extended time field");
return ARCHIVE_FAILED;
}
@ -648,7 +680,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
* if bitmap & 1, 2 byte "version made by"
* if bitmap & 2, 2 byte "internal file attributes"
* if bitmap & 4, 4 byte "external file attributes"
* if bitmap & 8, 2 byte comment length + n byte comment
* if bitmap & 8, 2 byte comment length + n byte
* comment
*/
int bitmap, bitmap_last;
@ -699,13 +732,18 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
= external_attributes >> 16;
} else if (zip_entry->system == 0) {
// Interpret MSDOS directory bit
if (0x10 == (external_attributes & 0x10)) {
zip_entry->mode = AE_IFDIR | 0775;
if (0x10 == (external_attributes &
0x10)) {
zip_entry->mode =
AE_IFDIR | 0775;
} else {
zip_entry->mode = AE_IFREG | 0664;
zip_entry->mode =
AE_IFREG | 0664;
}
if (0x01 == (external_attributes & 0x01)) {
// Read-only bit; strip write permissions
if (0x01 == (external_attributes &
0x01)) {
/* Read-only bit;
* strip write permissions */
zip_entry->mode &= 0555;
}
} else {
@ -732,6 +770,59 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
}
break;
}
case 0x7075:
{
/* Info-ZIP Unicode Path Extra Field. */
if (datasize < 5 || entry == NULL)
break;
offset += 5;
datasize -= 5;
/* The path name in this field is always encoded
* in UTF-8. */
if (zip->sconv_utf8 == NULL) {
zip->sconv_utf8 =
archive_string_conversion_from_charset(
&a->archive, "UTF-8", 1);
/* If the converter from UTF-8 is not
* available, then the path name from the main
* field will more likely be correct. */
if (zip->sconv_utf8 == NULL)
break;
}
/* Make sure the CRC32 of the filename matches. */
if (!zip->ignore_crc32) {
const char *cp = archive_entry_pathname(entry);
if (cp) {
unsigned long file_crc =
zip->crc32func(0, cp, strlen(cp));
unsigned long utf_crc =
archive_le32dec(p + offset - 4);
if (file_crc != utf_crc) {
#ifdef DEBUG
fprintf(stderr,
"CRC filename mismatch; "
"CDE is %lx, but UTF8 "
"is outdated with %lx\n",
file_crc, utf_crc);
#endif
break;
}
}
}
if (archive_entry_copy_pathname_l(entry,
p + offset, datasize, zip->sconv_utf8) != 0) {
/* Ignore the error, and fallback to the path
* name from the main field. */
#ifdef DEBUG
fprintf(stderr, "Failed to read the ZIP "
"0x7075 extra field path.\n");
#endif
}
break;
}
case 0x7855:
/* Info-ZIP Unix Extra Field (type 2) "Ux". */
#ifdef DEBUG
@ -766,7 +857,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
}
if (datasize >= (2 + uidsize + 3)) {
/* get a gid size. */
gidsize = 0xff & (int)p[offset+2+uidsize];
gidsize = 0xff &
(int)p[offset+2+uidsize];
if (gidsize == 2)
zip_entry->gid =
archive_le16dec(
@ -783,7 +875,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
case 0x9901:
/* WinZip AES extra data field. */
if (datasize < 6) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Incomplete AES field");
return ARCHIVE_FAILED;
}
@ -803,12 +896,6 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
}
offset += datasize;
}
if (offset != extra_length) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed extra data: Consumed %d bytes of %d bytes",
(int)offset, (int)extra_length);
return ARCHIVE_FAILED;
}
return ARCHIVE_OK;
}
@ -928,7 +1015,8 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
if (ARCHIVE_OK != process_extra(a, h, extra_length, zip_entry)) {
if (ARCHIVE_OK != process_extra(a, entry, h, extra_length,
zip_entry)) {
return ARCHIVE_FATAL;
}
__archive_read_consume(a, extra_length);
@ -945,8 +1033,8 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
zip_entry->mode |= 0664;
}
/* Windows archivers sometimes use backslash as the directory separator.
Normalize to slash. */
/* Windows archivers sometimes use backslash as the directory
* separator. Normalize to slash. */
if (zip_entry->system == 0 &&
(wp = archive_entry_pathname_w(entry)) != NULL) {
if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) {
@ -1255,7 +1343,8 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
zip->entry->crc32 = archive_le32dec(p + 4);
compressed = archive_le64dec(p + 8);
uncompressed = archive_le64dec(p + 16);
if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
if (compressed > INT64_MAX || uncompressed >
INT64_MAX) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Overflow of 64-bit file sizes");
@ -1372,7 +1461,8 @@ consume_optional_marker(struct archive_read *a, struct zip *zip)
zip->entry->crc32 = archive_le32dec(p);
compressed = archive_le64dec(p + 4);
uncompressed = archive_le64dec(p + 12);
if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
if (compressed > INT64_MAX ||
uncompressed > INT64_MAX) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Overflow of 64-bit file sizes");
@ -1444,12 +1534,16 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
} alone_header;
#pragma pack(pop)
/* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma that
* is a part of XZ Utils. The stream format stored inside ZIPX file is a
* modified "lzma alone" file format, that was used by the `lzma` utility
* which was later deprecated in favour of `xz` utility. Since those
* formats are nearly the same, we can use a standard "lzma alone" decoder
* from XZ Utils. */
if(zip->zipx_lzma_valid) {
lzma_end(&zip->zipx_lzma_stream);
zip->zipx_lzma_valid = 0;
}
/* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma
* that is a part of XZ Utils. The stream format stored inside ZIPX
* file is a modified "lzma alone" file format, that was used by the
* `lzma` utility which was later deprecated in favour of `xz` utility. * Since those formats are nearly the same, we can use a standard
* "lzma alone" decoder from XZ Utils. */
memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
r = lzma_alone_decoder(&zip->zipx_lzma_stream, UINT64_MAX);
@ -1477,8 +1571,8 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
* lzma_params is a 5-byte blob that has to be decoded to extract
* parameters of this LZMA stream. The uncompressed_size field is an
* uint64_t value that contains information about the size of the
* uncompressed file, or UINT64_MAX if this value is unknown. The <data...>
* part is the actual lzma-compressed data stream.
* uncompressed file, or UINT64_MAX if this value is unknown.
* The <data...> part is the actual lzma-compressed data stream.
*
* Now here's the structure of the stream inside the ZIPX file:
*
@ -1488,17 +1582,17 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
* 2byte 2byte 5 bytes n bytes
* <magic1><magic2><lzma_params><data...>
*
* This means that the ZIPX file contains an additional magic1 and magic2
* headers, the lzma_params field contains the same parameter set as in the
* "lzma alone" format, and the <data...> field is the same as in the "lzma
* alone" format as well. Note that also the zipx format is missing the
* uncompressed_size field.
* This means that the ZIPX file contains an additional magic1 and
* magic2 headers, the lzma_params field contains the same parameter
* set as in the "lzma alone" format, and the <data...> field is the
* same as in the "lzma alone" format as well. Note that also the zipx
* format is missing the uncompressed_size field.
*
* So, in order to use the "lzma alone" decoder for the zipx lzma stream,
* we simply need to shuffle around some fields, prepare a new lzma alone
* header, feed it into lzma alone decoder so it will initialize itself
* properly, and then we can start feeding normal zipx lzma stream into the
* decoder.
* So, in order to use the "lzma alone" decoder for the zipx lzma
* stream, we simply need to shuffle around some fields, prepare a new
* lzma alone header, feed it into lzma alone decoder so it will
* initialize itself properly, and then we can start feeding normal
* zipx lzma stream into the decoder.
*/
/* Read magic1,magic2,lzma_params from the ZIPX stream. */
@ -1514,8 +1608,8 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
return (ARCHIVE_FATAL);
}
/* Prepare an lzma alone header: copy the lzma_params blob into a proper
* place into the lzma alone header. */
/* Prepare an lzma alone header: copy the lzma_params blob into
* a proper place into the lzma alone header. */
memcpy(&alone_header.bytes[0], p + 4, 5);
/* Initialize the 'uncompressed size' field to unknown; we'll manually
@ -1541,8 +1635,9 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
zip->zipx_lzma_stream.total_out = 0;
/* Feed only the header into the lzma alone decoder. This will effectively
* initialize the decoder, and will not produce any output bytes yet. */
/* Feed only the header into the lzma alone decoder. This will
* effectively initialize the decoder, and will not produce any
* output bytes yet. */
r = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
if (r != LZMA_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
@ -1617,7 +1712,8 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
if((int64_t) zip->zipx_lzma_stream.total_in !=
zip->entry_bytes_remaining)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"xz premature end of stream");
return (ARCHIVE_FATAL);
}
@ -1662,12 +1758,13 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
return (ret);
}
/* Fetch more compressed data. The same note as in deflate handler applies
* here as well:
/* Fetch more compressed data. The same note as in deflate handler
* applies here as well:
*
* Note: '1' here is a performance optimization. Recall that the
* decompression layer returns a count of available bytes; asking for more
* than that forces the decompressor to combine reads by copying data.
* decompression layer returns a count of available bytes; asking for
* more than that forces the decompressor to combine reads by copying
* data.
*/
compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
if (bytes_avail < 0) {
@ -1684,8 +1781,9 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
zip->zipx_lzma_stream.total_in = 0;
zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
zip->zipx_lzma_stream.avail_out =
/* 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. */
/* 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,
zip->entry->uncompressed_size -
zip->entry_uncompressed_bytes_read);
@ -1810,7 +1908,8 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
return (ARCHIVE_FATAL);
}
__archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order, restore_method);
__archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order,
restore_method);
/* Allocate the buffer that will hold uncompressed data. */
free(zip->uncompressed_buffer);
@ -1856,8 +1955,8 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
return ret;
}
/* Fetch for more data. We're reading 1 byte here, but libarchive should
* prefetch more bytes. */
/* Fetch for more data. We're reading 1 byte here, but libarchive
* should prefetch more bytes. */
(void) __archive_read_ahead(a, 1, &bytes_avail);
if(bytes_avail < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@ -1871,7 +1970,8 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
/* Decompression loop. */
do {
int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol(&zip->ppmd8);
int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol(
&zip->ppmd8);
if(sym < 0) {
zip->end_of_entry = 1;
break;
@ -1880,8 +1980,9 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
/* This field is set by ppmd_read() when there was no more data
* to be read. */
if(zip->ppmd8_stream_failed) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated PPMd8 file body");
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated PPMd8 file body");
return (ARCHIVE_FATAL);
}
@ -1985,9 +2086,10 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
in_bytes = 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 undesirable. This is
* why we need to make this check manually. */
/* libbz2 doesn't complain when caller feeds avail_in == 0.
* It will actually return success in this case, which is
* undesirable. This is why we need to make this check
* manually. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated bzip2 file body");
@ -2014,16 +2116,18 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
case BZ_OK:
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Failed to clean up bzip2 decompressor");
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Failed to clean up bzip2 "
"decompressor");
return ARCHIVE_FATAL;
}
zip->end_of_entry = 1;
break;
case BZ_OK:
/* The decompressor has successfully decoded this chunk of
* data, but more data is still in queue. */
/* The decompressor has successfully decoded this
* chunk of data, but more data is still in queue. */
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@ -2131,8 +2235,10 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
if (zip->tctx_valid || zip->cctx_valid) {
if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
size_t buff_remaining =
(zip->decrypted_buffer + zip->decrypted_buffer_size)
- (zip->decrypted_ptr + zip->decrypted_bytes_remaining);
(zip->decrypted_buffer +
zip->decrypted_buffer_size)
- (zip->decrypted_ptr +
zip->decrypted_bytes_remaining);
if (buff_remaining > (size_t)bytes_avail)
buff_remaining = (size_t)bytes_avail;
@ -2143,12 +2249,12 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
+ buff_remaining)
> zip->entry_bytes_remaining) {
if (zip->entry_bytes_remaining <
(int64_t)zip->decrypted_bytes_remaining)
(int64_t)zip->decrypted_bytes_remaining)
buff_remaining = 0;
else
buff_remaining =
(size_t)zip->entry_bytes_remaining
- zip->decrypted_bytes_remaining;
- zip->decrypted_bytes_remaining;
}
}
if (buff_remaining > 0) {
@ -2167,7 +2273,8 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
+ zip->decrypted_bytes_remaining,
&dsize);
}
zip->decrypted_bytes_remaining += buff_remaining;
zip->decrypted_bytes_remaining +=
buff_remaining;
}
}
bytes_avail = zip->decrypted_bytes_remaining;
@ -2751,7 +2858,7 @@ archive_read_format_zip_cleanup(struct archive_read *a)
inflateEnd(&zip->stream);
#endif
#if HAVA_LZMA_H && HAVE_LIBLZMA
#if HAVE_LZMA_H && HAVE_LIBLZMA
if (zip->zipx_lzma_valid) {
lzma_end(&zip->zipx_lzma_stream);
}
@ -3391,7 +3498,8 @@ expose_parent_dirs(struct zip *zip, const char *name, size_t name_length)
}
static int
slurp_central_directory(struct archive_read *a, struct zip *zip)
slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
struct zip *zip)
{
ssize_t i;
unsigned found;
@ -3501,8 +3609,10 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
filename_length = archive_le16dec(p + 28);
extra_length = archive_le16dec(p + 30);
comment_length = archive_le16dec(p + 32);
/* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
/* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
/* disk_start = archive_le16dec(p + 34);
* Better be zero.
* internal_attributes = archive_le16dec(p + 36);
* text bit */
external_attributes = archive_le32dec(p + 38);
zip_entry->local_header_offset =
archive_le32dec(p + 42) + correction;
@ -3538,7 +3648,8 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
"Truncated ZIP file header");
return ARCHIVE_FATAL;
}
if (ARCHIVE_OK != process_extra(a, p + filename_length, extra_length, zip_entry)) {
if (ARCHIVE_OK != process_extra(a, entry, p + filename_length,
extra_length, zip_entry)) {
return ARCHIVE_FATAL;
}
@ -3560,7 +3671,8 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
* a directory. We should treat it as a non
* resource fork file to expose it. */
if (name[filename_length-1] != '/' &&
(r - name < 3 || r[0] != '.' || r[1] != '_')) {
(r - name < 3 || r[0] != '.' ||
r[1] != '_')) {
__archive_rb_tree_insert_node(
&zip->tree, &zip_entry->node);
/* Expose its parent directories. */
@ -3637,8 +3749,10 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
switch(rsrc->compression) {
case 0: /* No compression. */
if (rsrc->uncompressed_size != rsrc->compressed_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed OS X metadata entry: inconsistent size");
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Malformed OS X metadata entry: "
"inconsistent size");
return (ARCHIVE_FATAL);
}
#ifdef HAVE_ZLIB_H
@ -3797,7 +3911,7 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
a->archive.archive_format_name = "ZIP";
if (zip->zip_entries == NULL) {
r = slurp_central_directory(a, zip);
r = slurp_central_directory(a, entry, zip);
if (r != ARCHIVE_OK)
return r;
/* Get first entry whose local header offset is lower than
@ -3827,8 +3941,8 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
__archive_read_reset_passphrase(a);
/* File entries are sorted by the header offset, we should mostly
* use __archive_read_consume to advance a read point to avoid redundant
* data reading. */
* use __archive_read_consume to advance a read point to avoid
* redundant data reading. */
offset = archive_filter_bytes(&a->archive, 0);
if (offset < zip->entry->local_header_offset)
__archive_read_consume(a,

View File

@ -449,7 +449,7 @@ __archive_mktemp(const char *tmpdir)
temp_name.s[temp_name.length-1] = '\0';
temp_name.length --;
}
if (stat(temp_name.s, &st) < 0)
if (la_stat(temp_name.s, &st) < 0)
goto exit_tmpfile;
if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;

View File

@ -112,10 +112,7 @@
#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
#define setmode _setmode
#endif
#ifdef stat
#undef stat
#endif
#define stat(path,stref) __la_stat(path,stref)
#define la_stat(path,stref) __la_stat(path,stref)
#if !defined(__WATCOMC__)
#if !defined(__BORLANDC__)
#define strdup _strdup

View File

@ -390,10 +390,13 @@ archive_compressor_xz_options(struct archive_write_filter *f,
data->compression_level = 6;
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
char *endptr;
if (value == NULL)
return (ARCHIVE_WARN);
data->threads = (int)strtoul(value, NULL, 10);
if (data->threads == 0 && errno != 0) {
errno = 0;
data->threads = (int)strtoul(value, &endptr, 10);
if (errno != 0 || *endptr != '\0') {
data->threads = 1;
return (ARCHIVE_WARN);
}

View File

@ -2032,7 +2032,7 @@ restore_entry(struct archive_write_disk *a)
* follow the symlink if we're creating a dir.
*/
if (S_ISDIR(a->mode))
r = stat(a->name, &a->st);
r = la_stat(a->name, &a->st);
/*
* If it's not a dir (or it's a broken symlink),
* then don't follow it.
@ -2198,7 +2198,7 @@ create_filesystem_object(struct archive_write_disk *a)
#ifdef HAVE_LSTAT
r = lstat(a->name, &st);
#else
r = stat(a->name, &st);
r = la_stat(a->name, &st);
#endif
if (r != 0)
r = errno;
@ -2712,7 +2712,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
* This is needed to extract hardlinks over
* symlinks.
*/
r = stat(head, &st);
r = la_stat(head, &st);
if (r != 0) {
tail[0] = c;
if (errno == ENOENT) {
@ -3052,7 +3052,7 @@ create_dir(struct archive_write_disk *a, char *path)
* here loses the ability to extract through symlinks. Also note
* that this should not use the a->st cache.
*/
if (stat(path, &st) == 0) {
if (la_stat(path, &st) == 0) {
if (S_ISDIR(st.st_mode))
return (ARCHIVE_OK);
if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
@ -3110,7 +3110,7 @@ create_dir(struct archive_write_disk *a, char *path)
* don't add it to the fixup list here, as it's already been
* added.
*/
if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
if (la_stat(path, &st) == 0 && S_ISDIR(st.st_mode))
return (ARCHIVE_OK);
archive_set_error(&a->archive, errno, "Failed to create dir '%s'",

View File

@ -205,6 +205,8 @@ struct archive_write_disk {
#define MINIMUM_DIR_MODE 0700
#define MAXIMUM_DIR_MODE 0775
static int disk_unlink(const wchar_t *);
static int disk_rmdir(const wchar_t *);
static int check_symlinks(struct archive_write_disk *);
static int create_filesystem_object(struct archive_write_disk *);
static struct fixup_entry *current_fixup(struct archive_write_disk *,
@ -219,7 +221,10 @@ static int restore_entry(struct archive_write_disk *);
static int set_acls(struct archive_write_disk *, HANDLE h,
const wchar_t *, struct archive_acl *);
static int set_xattrs(struct archive_write_disk *);
static int clear_nochange_fflags(struct archive_write_disk *);
static int set_fflags(struct archive_write_disk *);
static int set_fflags_platform(const wchar_t *, unsigned long,
unsigned long);
static int set_ownership(struct archive_write_disk *);
static int set_mode(struct archive_write_disk *, int mode);
static int set_times(struct archive_write_disk *, HANDLE, int,
@ -556,8 +561,10 @@ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
set = 1;
f = la_GetFunctionKernel32("CreateHardLinkW");
}
if (!f)
if (!f) {
errno = ENOTSUP;
return (0);
}
ret = (*f)(linkname, target, NULL);
if (!ret) {
/* Under windows 2000, it is necessary to remove
@ -582,6 +589,103 @@ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
return (ret);
}
/*
* Create file or directory symolic link
*
* If linktype is AE_SYMLINK_TYPE_UNDEFINED (or unknown), guess linktype from
* the link target
*/
static int
la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
int linktype) {
static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
static int set;
wchar_t *ttarget, *p;
int len;
DWORD attrs = 0;
DWORD flags = 0;
DWORD newflags = 0;
BOOL ret = 0;
if (!set) {
set = 1;
f = la_GetFunctionKernel32("CreateSymbolicLinkW");
}
if (!f)
return (0);
len = wcslen(target);
if (len == 0) {
errno = EINVAL;
return(0);
}
/*
* When writing path targets, we need to translate slashes
* to backslashes
*/
ttarget = malloc((len + 1) * sizeof(wchar_t));
if (ttarget == NULL)
return(0);
p = ttarget;
while(*target != L'\0') {
if (*target == L'/')
*p = L'\\';
else
*p = *target;
target++;
p++;
}
*p = L'\0';
/*
* In case of undefined symlink type we guess it from the target.
* If the target equals ".", "..", ends with a backslash or a
* backslash followed by "." or ".." we assume it is a directory
* symlink. In all other cases we assume a file symlink.
*/
if (linktype != AE_SYMLINK_TYPE_FILE && (
linktype == AE_SYMLINK_TYPE_DIRECTORY ||
*(p - 1) == L'\\' || (*(p - 1) == L'.' && (
len == 1 || *(p - 2) == L'\\' || ( *(p - 2) == L'.' && (
len == 2 || *(p - 3) == L'\\')))))) {
#if defined(SYMBOLIC_LINK_FLAG_DIRECTORY)
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
#else
flags |= 0x1;
#endif
}
#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
newflags = flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
#else
newflags = flags | 0x2;
#endif
/*
* Windows won't overwrite existing links
*/
attrs = GetFileAttributesW(linkname);
if (attrs != INVALID_FILE_ATTRIBUTES) {
if (attrs & FILE_ATTRIBUTE_DIRECTORY)
disk_rmdir(linkname);
else
disk_unlink(linkname);
}
ret = (*f)(linkname, ttarget, newflags);
/*
* Prior to Windows 10 calling CreateSymbolicLinkW() will fail
* if SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE is set
*/
if (!ret) {
ret = (*f)(linkname, ttarget, flags);
}
free(ttarget);
return (ret);
}
static int
la_ftruncate(HANDLE handle, int64_t length)
{
@ -863,9 +967,11 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
}
if (a->deferred & TODO_FFLAGS) {
unsigned long set, clear;
fe = current_fixup(a, archive_entry_pathname_w(entry));
fe->fixup |= TODO_FFLAGS;
/* TODO: Complete this.. defer fflags from below. */
archive_entry_fflags(entry, &set, &clear);
fe->fflags_set = set;
}
/*
@ -1240,7 +1346,7 @@ archive_write_disk_new(void)
}
static int
disk_unlink(wchar_t *path)
disk_unlink(const wchar_t *path)
{
wchar_t *fullname;
int r;
@ -1255,7 +1361,7 @@ disk_unlink(wchar_t *path)
}
static int
disk_rmdir(wchar_t *path)
disk_rmdir(const wchar_t *path)
{
wchar_t *fullname;
int r;
@ -1286,6 +1392,8 @@ restore_entry(struct archive_write_disk *a)
* object is a dir, but that doesn't mean the old
* object isn't a dir.
*/
if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
(void)clear_nochange_fflags(a);
if (disk_unlink(a->name) == 0) {
/* We removed it, reset cached stat. */
a->pst = NULL;
@ -1360,28 +1468,45 @@ restore_entry(struct archive_write_disk *a)
en = create_filesystem_object(a);
} else if (en == EEXIST) {
mode_t st_mode;
mode_t lst_mode;
BY_HANDLE_FILE_INFORMATION lst;
/*
* We know something is in the way, but we don't know what;
* we need to find out before we go any further.
*/
int r = 0;
int dirlnk = 0;
/*
* The SECURE_SYMLINK logic has already removed a
* symlink to a dir if the client wants that. So
* follow the symlink if we're creating a dir.
*/
if (S_ISDIR(a->mode))
r = file_information(a, a->name, &a->st, &st_mode, 0);
/*
* If it's not a dir (or it's a broken symlink),
* then don't follow it.
*
* Windows distinguishes file and directory symlinks.
* A file symlink may erroneously point to a directory
* and a directory symlink to a file. Windows does not follow
* such symlinks. We always need both source and target
* information.
*/
if (r != 0 || !S_ISDIR(a->mode))
r = file_information(a, a->name, &a->st, &st_mode, 1);
r = file_information(a, a->name, &lst, &lst_mode, 1);
if (r != 0) {
archive_set_error(&a->archive, errno,
"Can't stat existing object");
return (ARCHIVE_FAILED);
} else if (S_ISLNK(lst_mode)) {
if (lst.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
dirlnk = 1;
/* In case of a symlink we need target information */
r = file_information(a, a->name, &a->st, &st_mode, 0);
if (r != 0) {
a->st = lst;
st_mode = lst_mode;
}
} else {
a->st = lst;
st_mode = lst_mode;
}
/*
@ -1405,8 +1530,19 @@ restore_entry(struct archive_write_disk *a)
}
if (!S_ISDIR(st_mode)) {
/* A non-dir is in the way, unlink it. */
if (disk_unlink(a->name) != 0) {
/* Edge case: a directory symlink pointing to a file */
if (a->flags &
ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
(void)clear_nochange_fflags(a);
}
if (dirlnk) {
if (disk_rmdir(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't unlink directory symlink");
return (ARCHIVE_FAILED);
}
} else if (disk_unlink(a->name) != 0) {
/* A non-dir is in the way, unlink it. */
archive_set_error(&a->archive, errno,
"Can't unlink already-existing object");
return (ARCHIVE_FAILED);
@ -1416,6 +1552,8 @@ restore_entry(struct archive_write_disk *a)
en = create_filesystem_object(a);
} else if (!S_ISDIR(a->mode)) {
/* A dir is in the way of a non-dir, rmdir it. */
if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
(void)clear_nochange_fflags(a);
if (disk_rmdir(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't remove already-existing dir");
@ -1515,7 +1653,16 @@ create_filesystem_object(struct archive_write_disk *a)
#if HAVE_SYMLINK
return symlink(linkname, a->name) ? errno : 0;
#else
return (EPERM);
errno = 0;
r = la_CreateSymbolicLinkW((const wchar_t *)a->name, linkname,
archive_entry_symlink_type(a->entry));
if (r == 0) {
if (errno == 0)
la_dosmaperr(GetLastError());
r = errno;
} else
r = 0;
return (r);
#endif
}
@ -1668,6 +1815,8 @@ _archive_write_disk_close(struct archive *_a)
la_chmod(p->name, p->mode);
if (p->fixup & TODO_ACLS)
set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl);
if (p->fixup & TODO_FFLAGS)
set_fflags_platform(p->name, p->fflags_set, 0);
next = p->next;
archive_acl_clear(&p->acl);
free(p->name);
@ -1784,6 +1933,7 @@ new_fixup(struct archive_write_disk *a, const wchar_t *pathname)
a->fixup_list = fe;
fe->fixup = 0;
fe->name = _wcsdup(pathname);
fe->fflags_set = 0;
return (fe);
}
@ -1827,6 +1977,9 @@ check_symlinks(struct archive_write_disk *a)
p = a->path_safe.s;
while ((*pn != '\0') && (*p == *pn))
++p, ++pn;
/* Skip leading backslashes */
while (*pn == '\\')
++pn;
c = pn[0];
/* Keep going until we've checked the entire name. */
while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) {
@ -1844,11 +1997,21 @@ check_symlinks(struct archive_write_disk *a)
} else if (S_ISLNK(st_mode)) {
if (c == '\0') {
/*
* Last element is symlink; remove it
* so we can overwrite it with the
* Last element is a file or directory symlink.
* Remove it so we can overwrite it with the
* item being extracted.
*/
if (disk_unlink(a->name)) {
if (a->flags &
ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
(void)clear_nochange_fflags(a);
}
if (st.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY) {
r = disk_rmdir(a->name);
} else {
r = disk_unlink(a->name);
}
if (r) {
archive_set_error(&a->archive, errno,
"Could not remove symlink %ls",
a->name);
@ -1872,7 +2035,17 @@ check_symlinks(struct archive_write_disk *a)
return (0);
} else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
/* User asked us to remove problems. */
if (disk_unlink(a->name) != 0) {
if (a->flags &
ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
(void)clear_nochange_fflags(a);
}
if (st.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY) {
r = disk_rmdir(a->name);
} else {
r = disk_unlink(a->name);
}
if (r != 0) {
archive_set_error(&a->archive, 0,
"Cannot remove intervening "
"symlink %ls", a->name);
@ -1888,6 +2061,8 @@ check_symlinks(struct archive_write_disk *a)
return (ARCHIVE_FAILED);
}
}
pn[0] = c;
pn++;
}
pn[0] = c;
/* We've checked and/or cleaned the whole path, so remember it. */
@ -2438,10 +2613,56 @@ set_mode(struct archive_write_disk *a, int mode)
return (r);
}
static int set_fflags_platform(const wchar_t *name, unsigned long fflags_set,
unsigned long fflags_clear)
{
DWORD oldflags, newflags;
wchar_t *fullname;
const DWORD settable_flags =
FILE_ATTRIBUTE_ARCHIVE |
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_NORMAL |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
FILE_ATTRIBUTE_OFFLINE |
FILE_ATTRIBUTE_READONLY |
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_TEMPORARY;
oldflags = GetFileAttributesW(name);
if (oldflags == (DWORD)-1 &&
GetLastError() == ERROR_INVALID_NAME) {
fullname = __la_win_permissive_name_w(name);
oldflags = GetFileAttributesW(fullname);
}
if (oldflags == (DWORD)-1) {
la_dosmaperr(GetLastError());
return (ARCHIVE_WARN);
}
newflags = ((oldflags & ~fflags_clear) | fflags_set) & settable_flags;
if(SetFileAttributesW(name, newflags) == 0)
return (ARCHIVE_WARN);
return (ARCHIVE_OK);
}
static int
clear_nochange_fflags(struct archive_write_disk *a)
{
return (set_fflags_platform(a->name, 0, FILE_ATTRIBUTE_READONLY));
}
static int
set_fflags(struct archive_write_disk *a)
{
(void)a; /* UNUSED */
unsigned long set, clear;
if (a->todo & TODO_FFLAGS) {
archive_entry_fflags(a->entry, &set, &clear);
if (set == 0 && clear == 0)
return (ARCHIVE_OK);
return (set_fflags_platform(a->name, set, clear));
}
return (ARCHIVE_OK);
}

View File

@ -1114,6 +1114,10 @@ archive_write_pax_header(struct archive_write *a,
if (!need_extension && acl_types != 0)
need_extension = 1;
/* If the symlink type is defined, we need an extension */
if (!need_extension && archive_entry_symlink_type(entry_main) > 0)
need_extension = 1;
/*
* Libarchive used to include these in extended headers for
* restricted pax format, but that confused people who
@ -1247,6 +1251,17 @@ archive_write_pax_header(struct archive_write *a,
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
/* Store extended symlink information */
if (archive_entry_symlink_type(entry_main) ==
AE_SYMLINK_TYPE_FILE) {
add_pax_attr(&(pax->pax_header),
"LIBARCHIVE.symlinktype", "file");
} else if (archive_entry_symlink_type(entry_main) ==
AE_SYMLINK_TYPE_DIRECTORY) {
add_pax_attr(&(pax->pax_header),
"LIBARCHIVE.symlinktype", "dir");
}
}
/* Only regular files have data. */

View File

@ -496,10 +496,13 @@ xar_options(struct archive_write *a, const char *key, const char *value)
return (ARCHIVE_OK);
}
if (strcmp(key, "threads") == 0) {
char *endptr;
if (value == NULL)
return (ARCHIVE_FAILED);
xar->opt_threads = (int)strtoul(value, NULL, 10);
if (xar->opt_threads == 0 && errno != 0) {
errno = 0;
xar->opt_threads = (int)strtoul(value, &endptr, 10);
if (errno != 0 || *endptr != '\0') {
xar->opt_threads = 1;
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,

View File

@ -154,6 +154,7 @@ IF(ENABLE_TEST)
test_read_format_tar.c
test_read_format_tar_concatenated.c
test_read_format_tar_empty_filename.c
test_read_format_tar_empty_with_gnulabel.c
test_read_format_tar_empty_pax.c
test_read_format_tar_filename.c
test_read_format_tbz.c
@ -165,10 +166,12 @@ IF(ENABLE_TEST)
test_read_format_warc.c
test_read_format_xar.c
test_read_format_zip.c
test_read_format_zip_7075_utf8_paths.c
test_read_format_zip_comment_stored.c
test_read_format_zip_encryption_data.c
test_read_format_zip_encryption_header.c
test_read_format_zip_encryption_partially.c
test_read_format_zip_extra_padding.c
test_read_format_zip_filename.c
test_read_format_zip_high_compression.c
test_read_format_zip_jar.c

View File

@ -27,6 +27,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_entry.c 201247 2009-12-30 05:5
#include <locale.h>
#ifdef HAVE_LINUX_FS_H
#include <linux/fs.h> /* for Linux file flags */
#endif
#ifndef HAVE_WCSCPY
static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
{
@ -337,16 +341,37 @@ DEFINE_TEST(test_entry)
/* TODO: Make this system-independent. */
assertEqualString(archive_entry_fflags_text(e),
"uappnd,nouchg,nodump,noopaque,uunlnk,nosystem");
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
/* Test archive_entry_copy_fflags_text_w() */
archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,uunlnk");
archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,hidden");
archive_entry_fflags(e, &set, &clear);
assertEqualInt(16, set);
assertEqualInt(7, clear);
assertEqualInt(UF_HIDDEN, set);
assertEqualInt(UF_NODUMP | UF_IMMUTABLE | UF_APPEND, clear);
/* Test archive_entry_copy_fflags_text() */
archive_entry_copy_fflags_text(e, " ,nouappnd, nouchg, dump,uunlnk");
archive_entry_copy_fflags_text(e, " ,nouappnd, nouchg, dump,hidden");
archive_entry_fflags(e, &set, &clear);
assertEqualInt(16, set);
assertEqualInt(7, clear);
assertEqualInt(UF_HIDDEN, set);
assertEqualInt(UF_NODUMP | UF_IMMUTABLE | UF_APPEND, clear);
#elif defined(_WIN32) && !defined(CYGWIN)
archive_entry_copy_fflags_text_w(e, L"rdonly,hidden,nosystem");
archive_entry_fflags(e, &set, &clear);
assertEqualInt(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN, set);
assertEqualInt(FILE_ATTRIBUTE_SYSTEM, clear);
archive_entry_copy_fflags_text(e, "rdonly,hidden,nosystem");
archive_entry_fflags(e, &set, &clear);
assertEqualInt(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN, set);
assertEqualInt(FILE_ATTRIBUTE_SYSTEM, clear);
#elif defined FS_IOC_GETFLAGS /* Linux */
archive_entry_copy_fflags_text_w(e, L"sappnd,schg,dump,noundel");
archive_entry_fflags(e, &set, &clear);
assertEqualInt(FS_APPEND_FL | FS_IMMUTABLE_FL, set);
assertEqualInt(FS_NODUMP_FL | FS_UNRM_FL, clear);
archive_entry_copy_fflags_text(e, "sappnd,schg,dump,noundel");
archive_entry_fflags(e, &set, &clear);
assertEqualInt(FS_APPEND_FL | FS_IMMUTABLE_FL, set);
assertEqualInt(FS_NODUMP_FL | FS_UNRM_FL, clear);
#endif
/* See test_acl_basic.c for tests of ACL set/get consistency. */

View File

@ -58,6 +58,14 @@ test_fuzz(const struct files *filesets)
size_t blk_size;
int64_t blk_offset;
int n;
const char *skip_fuzz_tests;
skip_fuzz_tests = getenv("SKIP_TEST_FUZZ");
if (skip_fuzz_tests != NULL) {
skipping("Skipping fuzz tests due to SKIP_TEST_FUZZ "
"environment variable");
return;
}
for (n = 0; filesets[n].names != NULL; ++n) {
const size_t buffsize = 30000000;

View File

@ -40,7 +40,30 @@ atimeIsUpdated(void)
{
const char *fn = "fs_noatime";
struct stat st;
#if defined(_WIN32) && !defined(CYGWIN)
char *buff = NULL;
char *ptr;
int r;
r = systemf("fsutil behavior query disableLastAccess > query_atime");
if (r == 0) {
buff = slurpfile(NULL, "query_atime");
if (buff != NULL) {
ptr = buff;
while(*ptr != '\0' && !isdigit(*ptr)) {
ptr++;
}
if (*ptr == '0') {
free(buff);
return(1);
} else if (*ptr == '1' || *ptr == '2') {
free(buff);
return(0);
}
free(buff);
}
}
#endif
if (!assertMakeFile(fn, 0666, "a"))
return (0);
if (!assertUtimes(fn, 1, 0, 1, 0))
@ -570,13 +593,13 @@ test_symlink_hybrid(void)
assertMakeDir("h", 0755);
assertChdir("h");
assertMakeDir("d1", 0755);
assertMakeSymlink("ld1", "d1");
assertMakeSymlink("ld1", "d1", 1);
assertMakeFile("d1/file1", 0644, "d1/file1");
assertMakeFile("d1/file2", 0644, "d1/file2");
assertMakeSymlink("d1/link1", "file1");
assertMakeSymlink("d1/linkX", "fileX");
assertMakeSymlink("link2", "d1/file2");
assertMakeSymlink("linkY", "d1/fileY");
assertMakeSymlink("d1/link1", "file1", 0);
assertMakeSymlink("d1/linkX", "fileX", 0);
assertMakeSymlink("link2", "d1/file2", 0);
assertMakeSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
assert((ae = archive_entry_new()) != NULL);
@ -727,13 +750,13 @@ test_symlink_logical(void)
assertMakeDir("l", 0755);
assertChdir("l");
assertMakeDir("d1", 0755);
assertMakeSymlink("ld1", "d1");
assertMakeSymlink("ld1", "d1", 1);
assertMakeFile("d1/file1", 0644, "d1/file1");
assertMakeFile("d1/file2", 0644, "d1/file2");
assertMakeSymlink("d1/link1", "file1");
assertMakeSymlink("d1/linkX", "fileX");
assertMakeSymlink("link2", "d1/file2");
assertMakeSymlink("linkY", "d1/fileY");
assertMakeSymlink("d1/link1", "file1", 0);
assertMakeSymlink("d1/linkX", "fileX", 0);
assertMakeSymlink("link2", "d1/file2", 0);
assertMakeSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
/* Note: this test uses archive_read_next_header()
@ -961,8 +984,8 @@ test_symlink_logical_loop(void)
assertMakeDir("d1/d2/d3", 0755);
assertMakeDir("d2", 0755);
assertMakeFile("d2/file1", 0644, "d2/file1");
assertMakeSymlink("d1/d2/ld1", "../../d1");
assertMakeSymlink("d1/d2/ld2", "../../d2");
assertMakeSymlink("d1/d2/ld1", "../../d1", 1);
assertMakeSymlink("d1/d2/ld2", "../../d2", 1);
assertChdir("..");
assert((ae = archive_entry_new()) != NULL);
@ -1567,6 +1590,254 @@ test_nodump(void)
archive_entry_free(ae);
}
static void
test_parent(void)
{
struct archive *a;
struct archive_entry *ae;
const void *p;
size_t size;
int64_t offset;
int file_count;
int match_count;
int r;
assertMakeDir("lock", 0311);
assertMakeDir("lock/dir1", 0755);
assertMakeFile("lock/dir1/f1", 0644, "0123456789");
assertMakeDir("lock/lock2", 0311);
assertMakeDir("lock/lock2/dir1", 0755);
assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789");
assert((ae = archive_entry_new()) != NULL);
assert((a = archive_read_disk_new()) != NULL);
/*
* Test1: Traverse lock/dir1 as .
*/
assertChdir("lock/dir1");
failure("Directory traversals should work as well");
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
file_count = 2;
match_count = 0;
while (file_count--) {
archive_entry_clear(ae);
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
if (strcmp(archive_entry_pathname(ae), ".") == 0) {
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
++match_count;
} else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
assertEqualInt(archive_entry_size(ae), 10);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_data_block(a, &p, &size, &offset));
assertEqualInt((int)size, 10);
assertEqualInt((int)offset, 0);
assertEqualMem(p, "0123456789", 10);
assertEqualInt(ARCHIVE_EOF,
archive_read_data_block(a, &p, &size, &offset));
assertEqualInt((int)size, 0);
assertEqualInt((int)offset, 10);
++match_count;
}
if (archive_read_disk_can_descend(a)) {
/* Descend into the current object */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_disk_descend(a));
}
}
failure("Did not match expected filenames");
assertEqualInt(match_count, 2);
/*
* There is no entry. This will however fail if the directory traverse
* tries to ascend past the initial directory, since it lacks permission
* to do so.
*/
failure("There should be no entry and no error");
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
/* Close the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertChdir("../..");
/*
* Test2: Traverse lock/dir1 directly
*/
failure("Directory traversals should work as well");
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1"));
file_count = 2;
match_count = 0;
while (file_count--) {
archive_entry_clear(ae);
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) {
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
++match_count;
} else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) {
assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
assertEqualInt(archive_entry_size(ae), 10);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_data_block(a, &p, &size, &offset));
assertEqualInt((int)size, 10);
assertEqualInt((int)offset, 0);
assertEqualMem(p, "0123456789", 10);
assertEqualInt(ARCHIVE_EOF,
archive_read_data_block(a, &p, &size, &offset));
assertEqualInt((int)size, 0);
assertEqualInt((int)offset, 10);
++match_count;
}
if (archive_read_disk_can_descend(a)) {
/* Descend into the current object */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_disk_descend(a));
}
}
failure("Did not match expected filenames");
assertEqualInt(match_count, 2);
/*
* There is no entry. This will however fail if the directory traverse
* tries to ascend past the initial directory, since it lacks permission
* to do so.
*/
failure("There should be no entry and no error");
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
/* Close the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
/*
* Test3: Traverse lock/dir1/.
*/
failure("Directory traversals should work as well");
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/."));
file_count = 2;
match_count = 0;
while (file_count--) {
archive_entry_clear(ae);
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) {
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
++match_count;
} else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) {
assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
assertEqualInt(archive_entry_size(ae), 10);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_data_block(a, &p, &size, &offset));
assertEqualInt((int)size, 10);
assertEqualInt((int)offset, 0);
assertEqualMem(p, "0123456789", 10);
assertEqualInt(ARCHIVE_EOF,
archive_read_data_block(a, &p, &size, &offset));
assertEqualInt((int)size, 0);
assertEqualInt((int)offset, 10);
++match_count;
}
if (archive_read_disk_can_descend(a)) {
/* Descend into the current object */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_disk_descend(a));
}
}
failure("Did not match expected filenames");
assertEqualInt(match_count, 2);
/*
* There is no entry. This will however fail if the directory traverse
* tries to ascend past the initial directory, since it lacks permission
* to do so.
*/
failure("There should be no entry and no error");
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
/* Close the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
/*
* Test4: Traverse lock/lock2/dir1 from inside lock.
*
* This test is expected to fail on platforms with no O_EXEC or
* equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because
* the current traversal code can't handle the case where it can't
* obtain an open fd for the initial current directory. We need to
* check that condition here, because if O_EXEC _does_ exist, we don't
* want to overlook any failure.
*/
assertChdir("lock");
failure("Directory traversals should work as well");
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1"));
archive_entry_clear(ae);
r = archive_read_next_header2(a, ae);
if (r == ARCHIVE_FAILED) {
#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
assertEqualIntA(a, ARCHIVE_OK, r);
#endif
/* Close the disk object. */
archive_read_close(a);
} else {
file_count = 2;
match_count = 0;
while (file_count--) {
if (file_count == 0)
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header2(a, ae));
if (strcmp(archive_entry_pathname(ae),
"lock2/dir1") == 0) {
assertEqualInt(archive_entry_filetype(ae),
AE_IFDIR);
++match_count;
} else if (strcmp(archive_entry_pathname(ae),
"lock2/dir1/f1") == 0) {
assertEqualInt(archive_entry_filetype(ae),
AE_IFREG);
assertEqualInt(archive_entry_size(ae), 10);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_data_block(a, &p, &size,
&offset));
assertEqualInt((int)size, 10);
assertEqualInt((int)offset, 0);
assertEqualMem(p, "0123456789", 10);
assertEqualInt(ARCHIVE_EOF,
archive_read_data_block(a, &p, &size,
&offset));
assertEqualInt((int)size, 0);
assertEqualInt((int)offset, 10);
++match_count;
}
if (archive_read_disk_can_descend(a)) {
/* Descend into the current object */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_disk_descend(a));
}
}
failure("Did not match expected filenames");
assertEqualInt(match_count, 2);
/*
* There is no entry. This will however fail if the directory
* traverse tries to ascend past the initial directory, since
* it lacks permission to do so.
*/
failure("There should be no entry and no error");
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_next_header2(a, ae));
/* Close the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
}
assertChdir("..");
/* Destroy the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
archive_entry_free(ae);
}
DEFINE_TEST(test_read_disk_directory_traversals)
{
/* Basic test. */
@ -1583,4 +1854,6 @@ DEFINE_TEST(test_read_disk_directory_traversals)
test_callbacks();
/* Test nodump. */
test_nodump();
/* Test parent overshoot. */
test_parent();
}

View File

@ -161,7 +161,7 @@ DEFINE_TEST(test_read_extract)
assertIsDir("dir4/b", 0755);
assertIsDir("dir4/c", 0711);
if (canSymlink())
assertIsSymlink("symlink", "file");
assertIsSymlink("symlink", "file", 0);
free(buff);
free(file_buff);

View File

@ -717,4 +717,28 @@ DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file)
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
* Check mtree file with non-printable ascii characters
*/
DEFINE_TEST(test_read_format_mtree_noprint)
{
const char reffile[] = "test_read_format_mtree_noprint.mtree";
struct archive_entry *ae;
struct archive *a;
extract_reference_file(reffile);
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_filename(a, reffile, 11));
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
assertEqualString("Can't parse line 3", archive_error_string(a));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,4 @@
begin 644 test_read_format_mtree_noprint.mtree
K(VUT<F5E"F1I<E]O:R!T>7!E/61I<@ID:7)?P[;%H<2'('1Y<&4]9&ER"@``
`
end

View File

@ -28,6 +28,22 @@
#include <locale.h>
DEFINE_TEST(test_read_format_rar_set_format)
{
struct archive *a;
struct archive_entry *ae;
const char reffile[] = "test_read_format_rar.rar";
extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_RAR));
assertA(0 == archive_read_open_filename(a, reffile, 10240));
assertA(0 == archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_rar_basic)
{
char buff[64];
@ -3740,3 +3756,26 @@ DEFINE_TEST(test_read_format_rar_multivolume_uncompressed_files)
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_rar_ppmd_use_after_free)
{
uint8_t buf[16];
const char* reffile = "test_read_format_rar_ppmd_use_after_free.rar";
struct archive_entry *ae;
struct archive *a;
extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_open_filename(a, reffile, 10240));
assertA(ARCHIVE_OK == archive_read_next_header(a, &ae));
assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
assertA(ARCHIVE_OK == archive_read_next_header(a, &ae));
assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
begin 644 test_read_format_rar5_distance_overflow.rar
M4F%R(1H'`0"-[P+2``(''/\@("`@_R4``B`@("`@("`@("`@(/__("`@("`@
M(/\@("`@("`@((9ML63,PX"&AK%:S+?_(/\@_R#_(/\@_R#_(/\@`"``!R`@
MR<G)``#_(,G)R?___R#___\@____(/___R#___\@____R4#)R<G___\@____
M(/\@____("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(/__________
M____________________________________________________("`@("`@
.("`@("`@("`@("#_("``
`
end

View File

@ -0,0 +1,10 @@
begin 644 test_read_format_rar5_extra_field_version.rar
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`"BNGU4(0(#!%D&7^V#`I?:-URW@4'R
M@`,!"&)I;B\R=&\S`P0``<7)5B550C]U!#WY13&:5TJ$=$IZ(*3`C\#F0%O\
M)$)*@]X[RK.Z.G*HUT;V5FO&;:X/FDW,W`95I8T%@@C:DD="_8Z.9+CQH^IG
M8!ZF0N)JSY2?R(W@25K`U&W)Q1X"`MD`!M\`[8,"E]HW7+>!0?*``P$(8FEN
M+S)T;S/%R58E54(_=00]^44QFE=*A'1*>B"DP(_`YD!;_"1"2H/>.\JSNCIR
MJ-=&]E9KQFVN#YI-S-P&5:6-!8((VI)'0OV.CF2X\:/J9V`>ID+B:L^4G\B-
,X$E:P!UW5E$#!00`
`
end

View File

@ -0,0 +1,13 @@
begin 640 test_read_format_rar5_fileattr.rar
M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``-$;*1"@"`PN+``2+`"&+W8Z;@```
M#')E861O;FQY+G1X=`H#`J*C5`BE!M4!,3(S-#4V-S@@#0JYZ,#-)@(#"XL`
M!(L`(F^$/86````*:&ED9&5N+G1X=`H#`G(Q.0^E!M4!,C,T-38W.#D@#0H>
M%_EV)@(#"XL`!(L`)"V,TBB````*<WES=&5M+G1X=`H#`F:K01.E!M4!,S0U
M-C<X.3`@#0HQ>$42*0(#"XL`!(L`(RZ?$!V````-<F]?:&ED9&5N+G1X=`H#
M`JIEBD2M!M4!-C<X.3`Q,C,@#0HQAL?6)@(#"P`%`!$`````@```#&1I<E]R
M96%D;VYL>0H#`HS,%ABE!M4!Q!O^+"0"`PL`!0`2`````(````ID:7)?:&ED
M9&5N"@,">JRV&:4&U0'&L*8=)`(#"P`%`!0`````@```"F1I<E]S>7-T96T*
M`P(@+D4;I0;5`2YJ1$0F`@,+``4`$P````"````,9&ER7W)O:&ED9&5N"@,"
0CW7S@JT&U0$==U91`P4$````
`
end

View File

@ -0,0 +1,6 @@
begin 644 test_read_format_rar5_hardlink.rar
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`!KI,1X'@("A0`&A0"D@P(XC;=<(1>3
M?8```0AF:6QE+G1X=#$R,S0*[8@"T2X"`PT`!@6D@P(XC;=<`````(```0QH
@87)D;&EN:RYT>'0,!00`"&9I;&4N='AT'7=640,%!```
`
end

View File

@ -0,0 +1,9 @@
begin 644 test_read_format_rar5_invalid_dict_reference.rar
M4F%R(1H'`0"-[P+2``+#!QR`!P`F^P#_^_O[^_O[^R4``B$<`0(`#@```0``
M`"#2````_____QH(`/__^P#_W5)04(#_`(:&;;%DS+?,L0```````````+%D
MS+*RLK*R/@``____Y`"R````XP```````!4``````.X`````````````````
M%5<M;&@W;3$W"2!S;'$2C5L`_____@D0````$"('``"8F)@+````/__?````
M@```2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$@S2(``2$A(2$A(
>2$A(2$A(2$A(2$A(2$A(2$Q(2$A(2$A(2$A(2)](
`
end

View File

@ -0,0 +1,9 @@
begin 644 test_read_format_rar5_leftshift1.rar
M4F%R(1H'`0"-[P+2``(''(`'`"``_R4``B$<`0(`#@```0```"#2````____
M_P`(`/__^P#_W0`"(8#_`(:&;;%DS+?,L=:NL0#(3`$`````````````````
M``"``````````+!DS+*RL[*RL@```-P``````````````````(``````````
ML&3,LK*RLK*R````W`````#X____````````````````````````%5H>;&@T
M+3HW"2!SB^)_<Z3_`````?40'Q\?'Q\?'Q\?'Q\?'Q\?'Q\?'Q\?'Q\`````
5`````````````````/H`>@``````
`
end

View File

@ -0,0 +1,6 @@
begin 644 test_read_format_rar5_leftshift2.rar
M4F%R(1H'`0"-[P+2``(''(`'`2``_RL``B'+`0(`,O__````-WJ\KR<<)0`"
M(;<*`BY*`!```&;%T#%24%"`_R4`[@K+(2Y*`&$``'__`/\E``(N2@`0`0(`
0(?__`%N&?Q2UH.CHZ.CHZ```
`
end

View File

@ -0,0 +1,9 @@
begin 644 test_read_format_rar5_nonempty_dir_stream.rar
M4F%R(1H'`0"-[P+2``(''($'$7\`_R4``BP<`0(`(0#_Y@```"#2````____
M_P`(`/__^P#_W0`"(8#_`(:&;;%DS+?,L8```!;(&P#>``#__^_P```4```&
M`````````````+`!`@`A`/_F````(-(```#_____``@`___[`/_=``(A``++
M``"`]/^`!P!#^_____\"(2$!`@`A````_R4``B$A`0(`@````0```"#&`/_=
M``(A@/\`AH9ML63,M\R`_P```,@;`````!@`````_0`````````!87(A&@<`
5`(WO`M(``O8'&X`'`#C[_X`E``(A
`
end

View File

@ -0,0 +1,8 @@
begin 644 test_read_format_rar5_owner.rar
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`!W:E-^+0(##H4`!H4`I(,"_8VW7"$7
MDWV```$(<F]O="YT>'0-!@,$<F]O=`5W:&5E;#$R,S0*2J"P0S,"`Q*%``:%
M`*2#`FZ-MUQFP<VL@``!"FYO8F]D>2YT>'01!@,&;F]B;V1Y!VYO9W)O=7`U
M-C<X"L=81/8I`@,'A0`&A0"D@P)LD[=<>B#;(H```0MN=6UE<FEC+G1X=`8&
2#(].N$4Y.3DY"AUW5E$#!00`
`
end

View File

@ -0,0 +1,15 @@
begin 644 test_read_format_rar5_readtables_overflow.rar
M4F%R(1H'`0"-[P+2`)3+'_4`C>\"T@`"T@"4RQ_5]0#O0````,L?Q_T``(`"
MT@"4RQ_=V-C8`)3+']W=]0"-\`+2`)3+']WU`(WO`M(``M(`E,L?U?4`[P+2
M`)3+'\?]``"``M(`E,L?W=C8V`"4RQ_=]0#V`(WO`M'UV,?8V-C8$=C8V-C8
MV(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V-C8!]C8V-C8V-C8V-C8V-C8V-C8
MV-C8V-C8V-C(V-C8V-C2`)3+']W8V-C8V-C8V-C8V-C8V-C8@-C8V-C8V-C8
MV/+8V-C8V-C8V-C8`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8!-C8
MV-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8`(`"V`7V`(WO`M'U`]L?
MW?4`C>\"T@`"T@"4'__U`(WO`N``E,L?W84`C0`0T@"4RQ_=V-C8V-C8V`"4
MR_\R]0#V`(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8
MV-C8V-C8V-C8V-C8R-C8V-C8T@"4RQ_=V-C8V-C8V-C8V-C8V-C8V(#8V-C8
MV-C8````9-C8V-C8V!'8V-C8V-C8]]C8V-C8V-C8V-C8V/+8V-C8V-C8V-C8
=`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-@`
`
end

View File

@ -0,0 +1,8 @@
begin 644 test_read_format_rar5_symlink.rar
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`"$O8RN'@("A0`&A0"D@P(XC;=<(1>3
M?8!``0AF:6QE+G1X=#$R,S0*8QI3.2T"`PT`!@CMPP)7C;=<`````(!``0MS
M>6UL:6YK+G1X=`P%`0`(9FEL92YT>'2.NOQU)`(#"``&`^W#`DF6MUP`````
M@$`!!V1I<FQI;FL'!0$!`V1I<J/_?\87`@(`!P#M@P%&EK=<`````(```0-D
*:7(==U91`P4$````
`
end

View File

@ -0,0 +1,7 @@
begin 644 test_read_format_rar5_truncated_huff.rar
M4F%R(1H'`0"-[P+2``'#]#P\7P$'`0"-[P+2``+2`!;#M#Q::7!)2?__'`!I
M?_O_0B\*0RX-,'%O.\(#!-'^T#4````0`P1_``!#(3`P,./H`P```*^OKZ^O
MKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ\0`*^OKZ^A``KZ``$`2^\#
9T>WMNP$+-5H*^@`!`$OOB]$````0"S5:*@``
`
end

View File

@ -1,68 +1,69 @@
begin 644 test_read_format_rar5_win32.rar
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
;0];M1^11#SKD/'L0\&IZ_]!^T!UW5E$#!00`
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
KJ,`Z/SC^]Q#CZ_LA]/M(_0T0][6AZ>"'E94/$R(?'_N'S0`==U91`P4$````
`
end

View File

@ -0,0 +1,10 @@
begin 644 test_read_format_rar_ppmd_use_after_free.rar
M4F%R(1H'``1G=$Q26`!W````>U!+`P0R`'#_J7\`+@TU'`#]`0`7__]"0D)"
M+W5N<V5T"6=I9`UD#1T+``!"`````````&%R(1H'``1G>TQ26`!W=&@`[E!+
M`P0Q`'#_(````"`@(+<@!/T`("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(`1G=$Q26`!W````
M>U!+`P0R`'#_J7\`+@TU'`#]`0`7__]"0D)"+W5N<V5T"6=I9`UD#1T+``!"
@`````````&%R(1H'``1G>TQ26`!W=&@`[E!+`P0Q`'``
`
end

View File

@ -36,6 +36,7 @@ DEFINE_TEST(test_read_format_raw)
const char *reffile1 = "test_read_format_raw.data";
const char *reffile2 = "test_read_format_raw.data.Z";
const char *reffile3 = "test_read_format_raw.bufr";
const char *reffile4 = "test_read_format_raw.data.gz";
/* First, try pulling data out of an uninterpretable file. */
extract_reference_file(reffile1);
@ -117,4 +118,30 @@ DEFINE_TEST(test_read_format_raw)
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Fourth, try with gzip which has metadata. */
extract_reference_file(reffile4);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, reffile4, 1));
/* First (and only!) Entry */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("test-file-name.data", archive_entry_pathname(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
assert(archive_entry_mtime_is_set(ae));
assertEqualIntA(a, archive_entry_mtime(ae), 0x5cbafd25);
/* Most fields should be unset (unknown) */
assert(!archive_entry_size_is_set(ae));
assert(!archive_entry_atime_is_set(ae));
assert(!archive_entry_ctime_is_set(ae));
/* Test EOF */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,4 @@
begin 644 test_read_format_raw.data.gz
L'XL(""7]NEP``W1E<W0M9FEL92UN86UE+F1A=&$`2\O/YP(`J&4R?@0`````
`
end

View File

@ -0,0 +1,53 @@
/*-
* Copyright (c) 2019 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
/*
* Tar archives with with just a GNU label (or ending with one) should
* be treated as valid (empty) archives
*/
DEFINE_TEST(test_read_format_tar_empty_with_gnulabel)
{
char name[] = "test_read_format_tar_empty_with_gnulabel.tar";
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_EOF, archive_read_next_header(a, &ae));
/* Verify that the format detection worked. */
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,231 @@
begin 664 test_read_format_tar_empty_with_gnulabel.tar
M;&%B96P`````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`#$S-#8W-S,V,C`S`#`P,C8R,``@5@``````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
9````````````````````````````````````
`
end

View File

@ -32,29 +32,29 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_zip.c 189482 2009-
static
int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc)
{
la_ssize_t fsize, bytes_read;
uint8_t* buf;
int ret = 1;
uint32_t computed_crc;
la_ssize_t fsize, bytes_read;
uint8_t* buf;
int ret = 1;
uint32_t computed_crc;
fsize = (la_ssize_t) archive_entry_size(ae);
buf = malloc(fsize);
if(buf == NULL)
return 1;
fsize = (la_ssize_t) archive_entry_size(ae);
buf = malloc(fsize);
if(buf == NULL)
return 1;
bytes_read = archive_read_data(a, buf, fsize);
if(bytes_read != fsize) {
assertEqualInt(bytes_read, fsize);
goto fn_exit;
}
bytes_read = archive_read_data(a, buf, fsize);
if(bytes_read != fsize) {
assertEqualInt(bytes_read, fsize);
goto fn_exit;
}
computed_crc = crc32(0, buf, fsize);
assertEqualInt(computed_crc, crc);
ret = 0;
computed_crc = crc32(0, buf, fsize);
assertEqualInt(computed_crc, crc);
ret = 0;
fn_exit:
free(buf);
return ret;
free(buf);
return ret;
}
static
@ -111,7 +111,7 @@ verify_basic(struct archive *a, int seek_checks)
int64_t o;
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a));
assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a));
assertEqualString("dir/", archive_entry_pathname(ae));
assertEqualInt(1179604249, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_size(ae));
@ -124,7 +124,7 @@ verify_basic(struct archive *a, int seek_checks)
assertEqualInt((int)s, 0);
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
assertEqualString("file1", archive_entry_pathname(ae));
assertEqualInt(1179604289, archive_entry_mtime(ae));
if (seek_checks)
@ -144,7 +144,7 @@ verify_basic(struct archive *a, int seek_checks)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
assertEqualString("file2", archive_entry_pathname(ae));
assertEqualInt(1179605932, archive_entry_mtime(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
@ -166,7 +166,7 @@ verify_basic(struct archive *a, int seek_checks)
assert(archive_errno(a) != 0);
}
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
/* Verify the number of files read. */
failure("the archive file has three files");
assertEqualInt(3, archive_file_count(a));
@ -493,9 +493,14 @@ DEFINE_TEST(test_read_format_zip_lzma_one_file)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading not fully supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@ -513,9 +518,14 @@ DEFINE_TEST(test_read_format_zip_lzma_one_file_blockread)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading not fully supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@ -533,9 +543,14 @@ DEFINE_TEST(test_read_format_zip_lzma_multi)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading not fully supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
@ -565,9 +580,14 @@ DEFINE_TEST(test_read_format_zip_lzma_multi_blockread)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading not fully supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
@ -598,9 +618,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_one_file)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
skipping("bzip2 is not fully supported on this platform");
archive_read_close(a);
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@ -618,9 +643,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_one_file_blockread)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
skipping("bzip2 is not fully supported on this platform");
archive_read_close(a);
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@ -638,9 +668,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_multi)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
skipping("bzip2 is not fully supported on this platform");
archive_read_close(a);
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
@ -670,9 +705,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_multi_blockread)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
skipping("bzip2 is not fully supported on this platform");
archive_read_close(a);
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
@ -702,9 +742,14 @@ DEFINE_TEST(test_read_format_zip_xz_multi)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading not fully supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
@ -734,9 +779,14 @@ DEFINE_TEST(test_read_format_zip_xz_multi_blockread)
struct archive *a;
struct archive_entry *ae;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading not fully supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
@ -789,9 +839,14 @@ DEFINE_TEST(test_read_format_zip_bz2_hang_on_invalid)
struct archive_entry *ae;
char buf[8];
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
skipping("bzip2 is not fully supported on this platform");
archive_read_close(a);
return;
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@ -823,3 +878,41 @@ DEFINE_TEST(test_read_format_zip_ppmd8_crash_2)
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_zip_lzma_alone_leak)
{
const char *refname = "test_read_format_zip_lzma_alone_leak.zipx";
struct archive *a;
struct archive_entry *ae;
char buf[64];
/* OSSFuzz #14470 sample file. */
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
if(ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading is not fully supported on this platform");
archive_read_close(a);
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
/* Extraction of this file should fail, because the sample file is invalid.
* But it shouldn't crash. */
assertEqualIntA(a, ARCHIVE_FAILED, archive_read_data(a, buf, sizeof(buf)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
/* Extraction of this file should fail, because the sample file is invalid.
* But it shouldn't crash. */
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, sizeof(buf)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
/* This testcase shouldn't produce any memory leaks. When running test
* suite under Valgrind or ASan, the test runner won't return with
* exit code 0 in case if a memory leak. */
}

View File

@ -0,0 +1,102 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2011 Michihiro NAKAJIMA
* Copyright (c) 2019 Mike Frysinger
* 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"
__FBSDID("$FreeBSD$");
#include <locale.h>
static void
verify(struct archive *a) {
struct archive_entry *ae;
const char *p;
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
assertEqualUTF8String(p, "File 1.txt");
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
#if defined(__APPLE__)
/* Compare NFD string. */
assertEqualUTF8String(p, "File 2 - o\xCC\x88.txt");
#else
/* Compare NFC string. */
assertEqualUTF8String(p, "File 2 - \xC3\xB6.txt");
#endif
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
#if defined(__APPLE__)
/* Compare NFD string. */
assertEqualUTF8String(p, "File 3 - a\xCC\x88.txt");
#else
/* Compare NFC string. */
assertEqualUTF8String(p, "File 3 - \xC3\xA4.txt");
#endif
/* The CRC of the filename fails, so fall back to CDE. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
assertEqualUTF8String(p, "File 4 - xx.txt");
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
}
DEFINE_TEST(test_read_format_zip_utf8_paths)
{
const char *refname = "test_read_format_zip_7075_utf8_paths.zip";
struct archive *a;
char *p;
size_t s;
extract_reference_file(refname);
if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
skipping("en_US.UTF-8 locale not available on this system.");
return;
}
/* Verify with seeking reader. */
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_filename(a, refname, 10240));
verify(a);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
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, read_open_memory(a, p, s, 31));
verify(a);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_free(a));
free(p);
}

View File

@ -0,0 +1,20 @@
begin 644 test_read_format_zip_7075_utf8_paths.zip
M4$L#!!0````(`,$^9D5BZ95P"P````D````*````1FEL92`Q+G1X=`M)+2Y1
M2,O,204`4$L#!!0````(`,$^9D5BZ95P"P````D````/`!@`1FEL92`R("T@
M>'@N='AT=7`4``$NSPQQ1FEL92`R("T@P[8N='AT"TDM+E%(R\Q)!0!02P,$
M%`````@`P3YF16+IE7`+````"0````\`&`!&:6QE(#,@+2!X>"YT>'1U<!0`
M`1"DSIY&:6QE(#,@+2##I"YT>'0+22TN44C+S$D%`%!+`P04````"`#!/F9%
M8NF5<`L````)````#P`8`$9I;&4@-"`M('AX+G1X='5P%``!G[AP'$9I;&4@
M-"`M(,.E+G1X=`M)+2Y12,O,204`4$L!`A\`%`````@`P3YF16+IE7`+````
M"0````H`)``````````@`````````$9I;&4@,2YT>'0*`"````````$`&``Q
M6UASCOG/`5^OQVV.^<\!7Z_';8[YSP%02P$"'P`4````"`#!/F9%8NF5<`L`
M```)````#@`\`````````"`````S````1FEL92`R("T@E"YT>'0*`"``````
M``$`&``Q6UASCOG/`2M.B72.^<\!*TZ)=([YSP%U<!0``2[/#'%&:6QE(#(@
M+2##MBYT>'102P$"'P`4````"`#!/F9%8NF5<`L````)````#@`\````````
M`"````"#````1FEL92`S("T@A"YT>'0*`"````````$`&``Q6UASCOG/`5<$
M&W>.^<\!5P0;=X[YSP%U<!0``1"DSIY&:6QE(#,@+2##I"YT>'102P$"'P`4
M````"`#!/F9%8NF5<`L````)````#@`\`````````"````#3````1FEL92`T
M("T@ABYT>'0*`"````````$`&``Q6UASCOG/`6#)ZG:.^<\!8,GJ=H[YSP%U
M<!0``9^X<!Q&:6QE(#0@+2##I2YT>'102P4&``````0`!`#$`0``(P$`````
`
end

View File

@ -0,0 +1,93 @@
/*-
* Copyright (c) 2003-2018 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"
/*
* Test archive verifies that we ignore padding in the extra field.
*
* APPNOTE.txt does not provide any provision for padding the extra
* field, so libarchive used to error when there were unconsumed
* bytes. Apparently, some Zip writers do routinely put zero padding
* in the extra field.
*
* The extra fields in this test (for both the local file header
* and the central directory entry) are formatted as follows:
*
* 0000 0000 - unrecognized field with type zero, zero bytes
* 5554 0900 03d258155cdb58155c - UX field with length 9
* 0000 0400 00000000 - unrecognized field with type zero, four bytes
* 000000 - three bytes padding
*
* The two valid type zero fields should be skipped and ignored, as
* should the three bytes padding (which is too short to be a valid
* extra data object). If there were no errors and we read the UX
* field correctly, then we've correctly handled all of the padding
* fields above.
*/
static void verify(struct archive *a) {
struct archive_entry *ae;
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("a", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae));
assertEqualInt(0x5c1558d2, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_ctime(ae));
assertEqualInt(0x5c1558db, archive_entry_atime(ae));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
}
DEFINE_TEST(test_read_format_zip_extra_padding)
{
const char *refname = "test_read_format_zip_extra_padding.zip";
struct archive *a;
char *p;
size_t s;
extract_reference_file(refname);
/* Verify with seeking reader. */
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_filename(a, refname, 7));
verify(a);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
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, read_open_memory(a, p, s, 3));
verify(a);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
free(p);
}

View File

@ -0,0 +1,7 @@
begin 644 test_read_format_zip_extra_padding.zip
M4$L#!`H``````"-=CTW$\L?V`@````(````!`!P`80````!55`D``])8%5S;
M6!5<```$``````````!B"E!+`0(>`PH``````"-=CTW$\L?V`@````(````!
M`!@```````$```"D@0````!A`````%54"0`#TE@57-M8%5P```0``````$L%
3!@`````!``$`1P```#T`````````
`
end

View File

@ -0,0 +1,5 @@
begin 644 test_read_format_zip_lzma_alone_leak.zipx
M4$L#!"`@6B`.("`@("`@("`@%0```"`@("````4``0`!`"`@(`4``"``````
J(/\@("`@("`@("!02P,$("`@(`X@(/________\@("`@("`@(``````@
`
end

View File

@ -68,6 +68,14 @@ struct sparse {
static void create_sparse_file(const char *, const struct sparse *);
#if defined(__APPLE__)
/* On APFS holes need to be at least 4096x4097 bytes */
#define MIN_HOLE 16781312
#else
/* Elsewhere we work with 4096*10 bytes */
#define MIN_HOLE 409600
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <winioctl.h>
/*
@ -491,6 +499,7 @@ DEFINE_TEST(test_sparse_basic)
{
char *cwd;
struct archive *a;
const char *skip_sparse_tests;
/*
* The alignment of the hole of sparse files deeply depends
* on filesystem. In my experience, sparse_file2 test with
@ -501,42 +510,42 @@ DEFINE_TEST(test_sparse_basic)
*/
const struct sparse sparse_file0[] = {
// 0 // 1024
{ DATA, 1024 }, { HOLE, 2048000 },
{ DATA, 1024 }, { HOLE, MIN_HOLE + 1638400 },
// 2049024 // 2051072
{ DATA, 2048 }, { HOLE, 2048000 },
{ DATA, 2048 }, { HOLE, MIN_HOLE + 1638400 },
// 4099072 // 4103168
{ DATA, 4096 }, { HOLE, 20480000 },
{ DATA, 4096 }, { HOLE, MIN_HOLE + 20070400 },
// 24583168 // 24591360
{ DATA, 8192 }, { HOLE, 204800000 },
{ DATA, 8192 }, { HOLE, MIN_HOLE + 204390400 },
// 229391360 // 229391361
{ DATA, 1 }, { END, 0 }
};
const struct sparse sparse_file1[] = {
{ HOLE, 409600 }, { DATA, 1 },
{ HOLE, 409600 }, { DATA, 1 },
{ HOLE, 409600 }, { END, 0 }
{ HOLE, MIN_HOLE }, { DATA, 1 },
{ HOLE, MIN_HOLE }, { DATA, 1 },
{ HOLE, MIN_HOLE }, { END, 0 }
};
const struct sparse sparse_file2[] = {
{ HOLE, 409600 * 1 }, { DATA, 1024 },
{ HOLE, 409600 * 2 }, { DATA, 1024 },
{ HOLE, 409600 * 3 }, { DATA, 1024 },
{ HOLE, 409600 * 4 }, { DATA, 1024 },
{ HOLE, 409600 * 5 }, { DATA, 1024 },
{ HOLE, 409600 * 6 }, { DATA, 1024 },
{ HOLE, 409600 * 7 }, { DATA, 1024 },
{ HOLE, 409600 * 8 }, { DATA, 1024 },
{ HOLE, 409600 * 9 }, { DATA, 1024 },
{ HOLE, 409600 * 10}, { DATA, 1024 },/* 10 */
{ HOLE, 409600 * 1 }, { DATA, 1024 * 1 },
{ HOLE, 409600 * 2 }, { DATA, 1024 * 2 },
{ HOLE, 409600 * 3 }, { DATA, 1024 * 3 },
{ HOLE, 409600 * 4 }, { DATA, 1024 * 4 },
{ HOLE, 409600 * 5 }, { DATA, 1024 * 5 },
{ HOLE, 409600 * 6 }, { DATA, 1024 * 6 },
{ HOLE, 409600 * 7 }, { DATA, 1024 * 7 },
{ HOLE, 409600 * 8 }, { DATA, 1024 * 8 },
{ HOLE, 409600 * 9 }, { DATA, 1024 * 9 },
{ HOLE, 409600 * 10}, { DATA, 1024 * 10},/* 20 */
{ HOLE, MIN_HOLE }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 1 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 2 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 3 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 4 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 5 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 6 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 7 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 8 }, { DATA, 1024 },
{ HOLE, MIN_HOLE + 409600 * 9}, { DATA, 1024 },/* 10 */
{ HOLE, MIN_HOLE }, { DATA, 1024 * 1 },
{ HOLE, MIN_HOLE + 409600 * 1 }, { DATA, 1024 * 2 },
{ HOLE, MIN_HOLE + 409600 * 2 }, { DATA, 1024 * 3 },
{ HOLE, MIN_HOLE + 409600 * 3 }, { DATA, 1024 * 4 },
{ HOLE, MIN_HOLE + 409600 * 4 }, { DATA, 1024 * 5 },
{ HOLE, MIN_HOLE + 409600 * 5 }, { DATA, 1024 * 6 },
{ HOLE, MIN_HOLE + 409600 * 6 }, { DATA, 1024 * 7 },
{ HOLE, MIN_HOLE + 409600 * 7 }, { DATA, 1024 * 8 },
{ HOLE, MIN_HOLE + 409600 * 8 }, { DATA, 1024 * 9 },
{ HOLE, MIN_HOLE + 409600 * 9}, { DATA, 1024 * 10},/* 20 */
{ END, 0 }
};
const struct sparse sparse_file3[] = {
@ -553,6 +562,13 @@ DEFINE_TEST(test_sparse_basic)
*/
test_sparse_whole_file_data();
skip_sparse_tests = getenv("SKIP_TEST_SPARSE");
if (skip_sparse_tests != NULL) {
skipping("Skipping sparse tests due to SKIP_TEST_SPARSE "
"environment variable");
return;
}
/* Check if the filesystem where CWD on can
* report the number of the holes of a sparse file. */
#ifdef PATH_MAX
@ -599,10 +615,19 @@ DEFINE_TEST(test_fully_sparse_files)
{
char *cwd;
struct archive *a;
const char *skip_sparse_tests;
const struct sparse sparse_file[] = {
{ HOLE, 409600 }, { END, 0 }
{ HOLE, MIN_HOLE }, { END, 0 }
};
skip_sparse_tests = getenv("SKIP_TEST_SPARSE");
if (skip_sparse_tests != NULL) {
skipping("Skipping sparse tests due to SKIP_TEST_SPARSE "
"environment variable");
return;
}
/* Check if the filesystem where CWD on can
* report the number of the holes of a sparse file. */
#ifdef PATH_MAX

View File

@ -99,6 +99,139 @@ DEFINE_TEST(test_write_disk_symlink)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: dot -> . */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dot");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, ".");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: dotdot -> .. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dotdot");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "..");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: slash -> / */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "slash");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "/");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: sldot -> /. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "sldot");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "/.");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: sldotdot -> /.. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "sldotdot");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "/..");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Dir: d1 */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "d1");
archive_entry_set_mode(ae, AE_IFDIR | 0777);
archive_entry_unset_size(ae);
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: d1nosl -> d1 */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "d1nosl");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "d1");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: d1slash -> d1/ */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "d1slash");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "d1/");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: d1sldot -> d1/. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "d1sldot");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "d1/.");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: d1slddot -> d1/.. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "d1slddot");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "d1/..");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: d1dir -> d1 */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "d1dir");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_set_symlink_type(ae, AE_SYMLINK_TYPE_DIRECTORY);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "d1");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
/* Symbolic link: d1file -> d1 */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "d1file");
archive_entry_set_mode(ae, AE_IFLNK | 0642);
archive_entry_set_symlink_type(ae, AE_SYMLINK_TYPE_FILE);
archive_entry_unset_size(ae);
archive_entry_copy_symlink(ae, "d1");
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
if (r >= ARCHIVE_WARN)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
assertEqualInt(ARCHIVE_OK, archive_write_free(ad));
/* Test the entries on disk. */
@ -107,11 +240,30 @@ DEFINE_TEST(test_write_disk_symlink)
assertIsReg("link1a", -1);
assertFileSize("link1a", sizeof(data));
assertFileNLinks("link1a", 1);
assertIsSymlink("link1b", "link1a");
assertIsSymlink("link1b", "link1a", 0);
/* Test #2: Should produce identical results to test #1 */
assertIsReg("link2a", -1);
assertFileSize("link2a", sizeof(data));
assertFileNLinks("link2a", 1);
assertIsSymlink("link2b", "link2a");
assertIsSymlink("link2b", "link2a", 0);
/* Test #3: Special symlinks */
assertIsSymlink("dot", ".", 1);
assertIsSymlink("dotdot", "..", 1);
assertIsSymlink("slash", "/", 1);
assertIsSymlink("sldot", "/.", 1);
assertIsSymlink("sldotdot", "/..", 1);
/* Test #4: Directory symlink mixed with . and .. */
assertIsDir("d1", -1);
/* On Windows, d1nosl should be a file symlink */
assertIsSymlink("d1nosl", "d1", 0);
assertIsSymlink("d1slash", "d1/", 1);
assertIsSymlink("d1sldot", "d1/.", 1);
assertIsSymlink("d1slddot", "d1/..", 1);
/* Test #5: symlink_type is set */
assertIsSymlink("d1dir", "d1", 1);
assertIsSymlink("d1file", "d1", 0);
}

View File

@ -204,6 +204,18 @@ Do not process files or directories that match the
specified pattern.
Note that exclusions take precedence over patterns or filenames
specified on the command line.
.It Fl Fl exclude-vcs
Do not process files or directories internally used by the
version control systems
.Sq CVS ,
.Sq RCS ,
.Sq SCCS ,
.Sq SVN ,
.Sq Arch ,
.Sq Bazaar ,
.Sq Mercurial
and
.Sq Darcs .
.It Fl Fl fflags
(c, r, u, x modes only)
Archive or extract file flags. This is the reverse of
@ -386,8 +398,7 @@ and the default behavior in c, r, and u modes or if
.Nm
is run in x mode as root.
.It Fl n , Fl Fl norecurse , Fl Fl no-recursion
(c, r, u modes only)
Do not recursively archive the contents of directories.
Do not operate recursively on the content of directories.
.It Fl Fl newer Ar date
(c, r, u modes only)
Only include files and directories newer than the specified date.

View File

@ -129,6 +129,28 @@ static void version(void) __LA_DEAD;
(ARCHIVE_EXTRACT_SECURE_SYMLINKS \
| ARCHIVE_EXTRACT_SECURE_NODOTDOT)
static char const * const vcs_files[] = {
/* CVS */
"CVS", ".cvsignore",
/* RCS */
"RCS",
/* SCCS */
"SCCS",
/* SVN */
".svn",
/* git */
".git", ".gitignore", ".gitattributes", ".gitmodules",
/* Arch */
".arch-ids", "{arch}", "=RELEASE-ID", "=meta-update", "=update",
/* Bazaar */
".bzr", ".bzrignore", ".bzrtags",
/* Mercurial */
".hg", ".hgignore", ".hgtags",
/* darcs */
"_darcs",
NULL
};
int
main(int argc, char **argv)
{
@ -318,6 +340,15 @@ main(int argc, char **argv)
lafe_errc(1, 0,
"Couldn't exclude %s\n", bsdtar->argument);
break;
case OPTION_EXCLUDE_VCS: /* GNU tar */
for(t=0; vcs_files[t]; t++) {
if (archive_match_exclude_pattern(
bsdtar->matching,
vcs_files[t]) != ARCHIVE_OK)
lafe_errc(1, 0, "Couldn't "
"exclude %s\n", vcs_files[t]);
}
break;
case OPTION_FFLAGS:
bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_FFLAGS;
@ -808,8 +839,6 @@ main(int argc, char **argv)
break;
}
}
if (bsdtar->flags & OPTFLAG_NO_SUBDIRS)
only_mode(bsdtar, "-n", "cru");
if (bsdtar->flags & OPTFLAG_STDOUT)
only_mode(bsdtar, "-O", "xt");
if (bsdtar->flags & OPTFLAG_UNLINK_FIRST)
@ -859,6 +888,16 @@ main(int argc, char **argv)
only_mode(bsdtar, buff, "cru");
}
/*
* When creating an archive from a directory tree, the directory
* walking code will already avoid entering directories when
* recursive inclusion of directory content is disabled, therefore
* changing the matching behavior has no effect for creation modes.
* It is relevant for extraction or listing.
*/
archive_match_set_inclusion_recursion(bsdtar->matching,
!(bsdtar->flags & OPTFLAG_NO_SUBDIRS));
/* Filename "-" implies stdio. */
if (strcmp(bsdtar->filename, "-") == 0)
bsdtar->filename = NULL;

View File

@ -135,6 +135,7 @@ enum {
OPTION_CHROOT,
OPTION_CLEAR_NOCHANGE_FFLAGS,
OPTION_EXCLUDE,
OPTION_EXCLUDE_VCS,
OPTION_FFLAGS,
OPTION_FORMAT,
OPTION_GID,

View File

@ -85,6 +85,7 @@ static const struct bsdtar_option {
{ "disable-copyfile", 0, OPTION_NO_MAC_METADATA },
{ "exclude", 1, OPTION_EXCLUDE },
{ "exclude-from", 1, 'X' },
{ "exclude-vcs", 0, OPTION_EXCLUDE_VCS },
{ "extract", 0, 'x' },
{ "fast-read", 0, 'q' },
{ "fflags", 0, OPTION_FFLAGS },

View File

@ -40,6 +40,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
test_option_b.c
test_option_b64encode.c
test_option_exclude.c
test_option_exclude_vcs.c
test_option_fflags.c
test_option_gid_gname.c
test_option_grzip.c

View File

@ -42,7 +42,7 @@ make_files(void)
/* Symlink to above file. */
if (canSymlink())
assertMakeSymlink("symlink", "file");
assertMakeSymlink("symlink", "file", 0);
/* Directory. */
assertMakeDir("dir", 0775);
@ -78,7 +78,7 @@ verify_files(const char *target)
/* Symlink */
if (canSymlink())
assertIsSymlink("symlink", "file");
assertIsSymlink("symlink", "file", 0);
/* dir */
failure("%s", target);

View File

@ -176,7 +176,7 @@ create_tree(void)
sprintf(buff, "s/%s", filenames[i]);
sprintf(buff2, "../f/%s", filenames[i]);
failure("buff=\"%s\" buff2=\"%s\"", buff, buff2);
assertMakeSymlink(buff, buff2);
assertMakeSymlink(buff, buff2, 0);
}
/* Create a dir named "d/abcdef...". */
buff[0] = 'd';
@ -222,7 +222,7 @@ verify_tree(size_t limit)
sprintf(name1, "s/%s", filenames[i]);
sprintf(name2, "../f/%s", filenames[i]);
if (strlen(name2) <= limit)
assertIsSymlink(name1, name2);
assertIsSymlink(name1, name2, 0);
}
/* Verify dir "d/abcdef...". */

View File

@ -36,6 +36,9 @@ DEFINE_TEST(test_option_C_mtree)
p0 = NULL;
char *content = "./foo type=file uname=root gname=root mode=0755\n";
char *filename = "output.tar";
#if defined(_WIN32) && !defined(CYGWIN)
char *p;
#endif
/* an absolute path to mtree file */
char *mtree_file = "/METALOG.mtree";
@ -48,9 +51,21 @@ DEFINE_TEST(test_option_C_mtree)
assertMakeDir("bar", 0775);
assertMakeFile("bar/foo", 0777, "abc");
r = systemf("%s -cf %s -C bar \"@%s\" >step1.out 2>step1.err", testprog, filename, absolute_path);
#if defined(_WIN32) && !defined(CYGWIN)
p = absolute_path;
while(*p != '\0') {
if (*p == '/')
*p = '\\';
p++;
}
r = systemf("%s -cf %s -C bar @%s >step1.out 2>step1.err", testprog, filename, absolute_path);
failure("Error invoking %s -cf %s -C bar @%s", testprog, filename, absolute_path);
#else
r = systemf("%s -cf %s -C bar \"@%s\" >step1.out 2>step1.err", testprog, filename, absolute_path);
failure("Error invoking %s -cf %s -C bar \"@%s\"", testprog, filename, absolute_path);
#endif
assertEqualInt(r, 0);
assertEmptyFile("step1.out");
assertEmptyFile("step1.err");
@ -68,6 +83,7 @@ DEFINE_TEST(test_option_C_mtree)
assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8);
done:
free(p0);
free(absolute_path);
}

View File

@ -39,13 +39,13 @@ DEFINE_TEST(test_option_H_upper)
assertMakeDir("in", 0755);
assertChdir("in");
assertMakeDir("d1", 0755);
assertMakeSymlink("ld1", "d1");
assertMakeSymlink("ld1", "d1", 1);
assertMakeFile("d1/file1", 0644, "d1/file1");
assertMakeFile("d1/file2", 0644, "d1/file2");
assertMakeSymlink("d1/link1", "file1");
assertMakeSymlink("d1/linkX", "fileX");
assertMakeSymlink("link2", "d1/file2");
assertMakeSymlink("linkY", "d1/fileY");
assertMakeSymlink("d1/link1", "file1", 0);
assertMakeSymlink("d1/linkX", "fileX", 0);
assertMakeSymlink("link2", "d1/file2", 0);
assertMakeSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
/* Test 1: Without -H */
@ -55,11 +55,11 @@ DEFINE_TEST(test_option_H_upper)
assertChdir("test1");
assertEqualInt(0,
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
assertIsSymlink("ld1", "d1");
assertIsSymlink("d1/link1", "file1");
assertIsSymlink("d1/linkX", "fileX");
assertIsSymlink("link2", "d1/file2");
assertIsSymlink("linkY", "d1/fileY");
assertIsSymlink("ld1", "d1", 1);
assertIsSymlink("d1/link1", "file1", 0);
assertIsSymlink("d1/linkX", "fileX", 0);
assertIsSymlink("link2", "d1/file2", 0);
assertIsSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
/* Test 2: With -H, no symlink on command line. */
@ -69,11 +69,11 @@ DEFINE_TEST(test_option_H_upper)
assertChdir("test2");
assertEqualInt(0,
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
assertIsSymlink("ld1", "d1");
assertIsSymlink("d1/link1", "file1");
assertIsSymlink("d1/linkX", "fileX");
assertIsSymlink("link2", "d1/file2");
assertIsSymlink("linkY", "d1/fileY");
assertIsSymlink("ld1", "d1", 1);
assertIsSymlink("d1/link1", "file1", 0);
assertIsSymlink("d1/linkX", "fileX", 0);
assertIsSymlink("link2", "d1/file2", 0);
assertIsSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
/* Test 3: With -H, some symlinks on command line. */
@ -84,9 +84,9 @@ DEFINE_TEST(test_option_H_upper)
assertEqualInt(0,
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
assertIsDir("ld1", umasked(0755));
assertIsSymlink("d1/linkX", "fileX");
assertIsSymlink("d1/link1", "file1");
assertIsSymlink("d1/linkX", "fileX", 0);
assertIsSymlink("d1/link1", "file1", 0);
assertIsReg("link2", umasked(0644));
assertIsSymlink("linkY", "d1/fileY");
assertIsSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
}

View File

@ -39,13 +39,13 @@ DEFINE_TEST(test_option_L_upper)
assertMakeDir("in", 0755);
assertChdir("in");
assertMakeDir("d1", 0755);
assertMakeSymlink("ld1", "d1");
assertMakeSymlink("ld1", "d1", 1);
assertMakeFile("d1/file1", 0644, "d1/file1");
assertMakeFile("d1/file2", 0644, "d1/file2");
assertMakeSymlink("d1/link1", "file1");
assertMakeSymlink("d1/linkX", "fileX");
assertMakeSymlink("link2", "d1/file2");
assertMakeSymlink("linkY", "d1/fileY");
assertMakeSymlink("d1/link1", "file1", 0);
assertMakeSymlink("d1/linkX", "fileX", 0);
assertMakeSymlink("link2", "d1/file2", 0);
assertMakeSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
/* Test 1: Without -L */
@ -55,11 +55,11 @@ DEFINE_TEST(test_option_L_upper)
assertChdir("test1");
assertEqualInt(0,
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
assertIsSymlink("ld1", "d1");
assertIsSymlink("d1/link1", "file1");
assertIsSymlink("d1/linkX", "fileX");
assertIsSymlink("link2", "d1/file2");
assertIsSymlink("linkY", "d1/fileY");
assertIsSymlink("ld1", "d1", 1);
assertIsSymlink("d1/link1", "file1", 0);
assertIsSymlink("d1/linkX", "fileX", 0);
assertIsSymlink("link2", "d1/file2", 0);
assertIsSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
/* Test 2: With -L, no symlink on command line. */
@ -71,9 +71,9 @@ DEFINE_TEST(test_option_L_upper)
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
assertIsDir("ld1", umasked(0755));
assertIsReg("d1/link1", umasked(0644));
assertIsSymlink("d1/linkX", "fileX");
assertIsSymlink("d1/linkX", "fileX", 0);
assertIsReg("link2", umasked(0644));
assertIsSymlink("linkY", "d1/fileY");
assertIsSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
/* Test 3: With -L, some symlinks on command line. */
@ -85,8 +85,8 @@ DEFINE_TEST(test_option_L_upper)
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
assertIsDir("ld1", umasked(0755));
assertIsReg("d1/link1", umasked(0644));
assertIsSymlink("d1/linkX", "fileX");
assertIsSymlink("d1/linkX", "fileX", 0);
assertIsReg("link2", umasked(0644));
assertIsSymlink("linkY", "d1/fileY");
assertIsSymlink("linkY", "d1/fileY", 0);
assertChdir("..");
}

View File

@ -79,10 +79,10 @@ DEFINE_TEST(test_option_U_upper)
assertMakeDir("test3", 0755);
assertChdir("test3");
assertMakeDir("realDir", 0755);
assertMakeSymlink("d1", "realDir");
assertMakeSymlink("d1", "realDir", 1);
r = systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog);
assert(r != 0);
assertIsSymlink("d1", "realDir");
assertIsSymlink("d1", "realDir", 1);
assertFileNotExists("d1/file1");
assertEmptyFile("test.out");
assertNonEmptyFile("test.err");
@ -92,7 +92,7 @@ DEFINE_TEST(test_option_U_upper)
assertMakeDir("test4", 0755);
assertChdir("test4");
assertMakeDir("realDir", 0755);
assertMakeSymlink("d1", "realDir");
assertMakeSymlink("d1", "realDir", 1);
assertEqualInt(0,
systemf("%s -xUf ../archive.tar >test.out 2>test.err", testprog));
assertIsDir("d1", -1);
@ -105,10 +105,10 @@ DEFINE_TEST(test_option_U_upper)
assertMakeDir("test5", 0755);
assertChdir("test5");
assertMakeDir("realDir", 0755);
assertMakeSymlink("d1", "realDir");
assertMakeSymlink("d1", "realDir", 1);
assertEqualInt(0,
systemf("%s -xPf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
assertIsSymlink("d1", "realDir");
assertIsSymlink("d1", "realDir", 1);
assertFileContents("d1/file1", 8, "d1/file1");
assertEmptyFile("test.out");
assertEmptyFile("test.err");
@ -118,10 +118,10 @@ DEFINE_TEST(test_option_U_upper)
assertMakeDir("test6", 0755);
assertChdir("test6");
assertMakeDir("realDir", 0755);
assertMakeSymlink("d1", "realDir");
assertMakeSymlink("d1", "realDir", 1);
assertEqualInt(0,
systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
assertIsSymlink("d1", "realDir");
assertIsSymlink("d1", "realDir", 1);
assertFileContents("d1/file1", 8, "d1/file1");
assertEmptyFile("test.out");
assertEmptyFile("test.err");
@ -132,7 +132,7 @@ DEFINE_TEST(test_option_U_upper)
assertChdir("test7");
assertMakeDir("d1", 0755);
assertMakeFile("d1/realfile1", 0644, "realfile1");
assertMakeSymlink("d1/file1", "d1/realfile1");
assertMakeSymlink("d1/file1", "d1/realfile1", 0);
assertEqualInt(0,
systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
assertIsReg("d1/file1", umasked(0644));
@ -147,7 +147,7 @@ DEFINE_TEST(test_option_U_upper)
assertChdir("test8");
assertMakeDir("d1", 0755);
assertMakeFile("d1/realfile1", 0644, "realfile1");
assertMakeSymlink("d1/file1", "d1/realfile1");
assertMakeSymlink("d1/file1", "d1/realfile1", 0);
assertEqualInt(0,
systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
assertIsReg("d1/file1", umasked(0644));

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