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:
parent
360aa1a4fa
commit
e9183e37fe
137
.cirrus.yml
137
.cirrus.yml
@ -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
|
||||
|
@ -1,9 +0,0 @@
|
||||
language: C
|
||||
matrix:
|
||||
include:
|
||||
- os: windows
|
||||
env: BS=msbuild
|
||||
- os: windows
|
||||
env: BS=mingw
|
||||
script:
|
||||
- build/ci/travis_ci.sh
|
@ -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
|
||||
|
55
Makefile.am
55
Makefile.am
@ -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
10
NEWS
@ -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
|
||||
|
@ -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}"
|
||||
|
4
build/ci/cirrus_ci/Dockerfile.cygwin
Normal file
4
build/ci/cirrus_ci/Dockerfile.cygwin
Normal 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
|
3
build/ci/cirrus_ci/Dockerfile.fc29
Normal file
3
build/ci/cirrus_ci/Dockerfile.fc29
Normal 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
|
3
build/ci/cirrus_ci/Dockerfile.fc29.distcheck
Normal file
3
build/ci/cirrus_ci/Dockerfile.fc29.distcheck
Normal 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
|
8
build/ci/cirrus_ci/Dockerfile.mingw
Normal file
8
build/ci/cirrus_ci/Dockerfile.mingw
Normal 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
|
9
build/ci/cirrus_ci/Dockerfile.msvc
Normal file
9
build/ci/cirrus_ci/Dockerfile.msvc
Normal 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
|
12
build/ci/cirrus_ci/Dockerfile.windows
Normal file
12
build/ci/cirrus_ci/Dockerfile.windows
Normal 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
122
build/ci/cirrus_ci/ci.cmd
Executable 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
|
@ -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
|
@ -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
218
contrib/archivetest.c
Normal 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);
|
||||
}
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -71,8 +71,13 @@ test_create(void)
|
||||
* #ifdef this section out. Most of the test below is
|
||||
* still valid. */
|
||||
memset(×, 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, ×));
|
||||
|
||||
/* Record whatever atime the file ended up with. */
|
||||
|
@ -85,7 +85,7 @@ DEFINE_TEST(test_option_c)
|
||||
|
||||
/* "symlink" */
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("symlink", "file");
|
||||
assertMakeSymlink("symlink", "file", 0);
|
||||
fprintf(filelist, "symlink\n");
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 *,
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
62
libarchive/archive_entry_misc.3
Normal file
62
libarchive/archive_entry_misc.3
Normal 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
|
@ -176,6 +176,9 @@ struct archive_entry {
|
||||
|
||||
/* Miscellaneous. */
|
||||
char strmode[12];
|
||||
|
||||
/* Symlink type support */
|
||||
int ae_symlink_type;
|
||||
};
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 ?
|
||||
*/
|
||||
|
@ -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 *);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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'",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
4
libarchive/test/test_read_format_mtree_noprint.mtree.uu
Normal file
4
libarchive/test/test_read_format_mtree_noprint.mtree.uu
Normal 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
|
@ -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
@ -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
|
@ -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
|
13
libarchive/test/test_read_format_rar5_fileattr.rar.uu
Normal file
13
libarchive/test/test_read_format_rar5_fileattr.rar.uu
Normal 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
|
6
libarchive/test/test_read_format_rar5_hardlink.rar.uu
Normal file
6
libarchive/test/test_read_format_rar5_hardlink.rar.uu
Normal 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
|
@ -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
|
9
libarchive/test/test_read_format_rar5_leftshift1.rar.uu
Normal file
9
libarchive/test/test_read_format_rar5_leftshift1.rar.uu
Normal 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
|
6
libarchive/test/test_read_format_rar5_leftshift2.rar.uu
Normal file
6
libarchive/test/test_read_format_rar5_leftshift2.rar.uu
Normal 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
|
@ -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
|
8
libarchive/test/test_read_format_rar5_owner.rar.uu
Normal file
8
libarchive/test/test_read_format_rar5_owner.rar.uu
Normal 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
|
@ -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
|
8
libarchive/test/test_read_format_rar5_symlink.rar.uu
Normal file
8
libarchive/test/test_read_format_rar5_symlink.rar.uu
Normal 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
|
@ -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
|
@ -1,68 +1,69 @@
|
||||
begin 644 test_read_format_rar5_win32.rar
|
||||
M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``/^"F5B0"`POI`@2P"2#-<,I\@`4`
|
||||
M"'1E<W0N8FEN"@,"/.U\@0U:U`'*]&4!)V5@5!]5=EV_E))QR<]EEED,<-EE
|
||||
MDQC%DA.&0DDDX9"0DDDD)..222$(220A"220DDA"$A+-M6][?3,.@'T=`ZX_
|
||||
MGKJ?]T'^]]KWW7FO.E_H`$`!`,@@GY^/;U]/+Q[^[LZ^KIZ.?EY./BX>#?W=
|
||||
MS:V=?6U=33TM#/S<S*R<C'QL7$P\&_O;R[N;BWMK6TL[*QKZZMJZJIIZ6DHZ
|
||||
M*AH)^=G)N9EY:4DTLE(R$>A0'XZ,BHF'.G#9J&A(*`?GQ[>GAV='-R<6]M:V
|
||||
MEG96-A7UU;65=54R$W]?R/T"4^B4Y_A$ET6*,&>6%VHX*:8IE!?F0M%VG48R
|
||||
MPSC`J$?_H)3&:0I?95"L5E8+BP&1:#<N!W7A!L`/,02,@GF85C0+IJ&6V#>;
|
||||
MAX.`8'(/KF$3H*9V&`\#;>A[O8=7T(W\6$"-&#'G"AY-"8-B^.#F.APB!*GA
|
||||
MA18[8T/Y\5"`;"$-"(32,9R0+R4`8B?AZB4"`POG`@2`("#&LA-^@`4`"71E
|
||||
M<W0Q+F)I;@H#`A*5H8`-6M0!R/!C`1!D168O5P5_4DDDDDDDDDDDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD^_/D;F=O/:[?;Z2Z_N
|
||||
M[6[OF=&;N]._TF,S#.GS#C<WS/.'/XKG;\@`@`@!L,/'3AM\>_MZ^GGY>/AW
|
||||
M]W;V=?5T]'/S<O)Q\7#P;^]N[FWM;.QKZVKJ:>EHZ&?G9N9EY63D8^-BXF'A
|
||||
M8.!?WU[>7=U<W%O;6MI9V5C85]=6UE755-13TU+24=%0T$_/3LY-S4S,2\M*
|
||||
MRDG)2,A'QT;&1<5$Q$/#0L)!P4#`/[\^^]['VA2X4M7TE0H#.Q@!;-"-XC0$
|
||||
M.A"U@6`X1/;M+3@AZ=F@%F`%LT(W2-`0Z$+6!8#A$]N4M."'IR:`68`6S0C<
|
||||
M(T!#H0M8%@.$3VW2TX(>FYH!9@!;-"-LC0$.A"U@6`X1-8__0K^QS*_>TU/6
|
||||
MRJ_(8IKGE-.XIH6GK_HGV@`)6BG`)0(#"^8"!(`@(,NO9O&`!0`)=&5S=#(N
|
||||
M8FEN"@,"A/;"@`U:U`'/]F(!$&1%9B]7!7]2222222222222222222222222
|
||||
M2222222222222222222222222222222222223[\^1N9V\]KM]OI+K^[M;N^9
|
||||
MT9N[T[_28S,,Z?,.-S?,\X<_BN=OR`"`"`&IAXZ<-OCW]O7T\_+Q\._N[>SK
|
||||
MZNGHY^;EY./BX>#?WMW<V]K9V-?6U=33TM'0S\[-S,O*R<C'QL7$P\+!P+^^
|
||||
MO;R[NKFXM[:UM+.RL;"OKJVLJZJIJ*>FI:2CHJ&@GYZ=G)N:F9B7EI64DY*1
|
||||
MD(^.C8R+BHF(AX:%A(."@8!_?GWWO8^T*7"EJ^DJ%`9V,`+9H1O$:`AT(6L"
|
||||
MP'")[=I:<$/3LT`LP`MFA&Z1H"'0A:P+`<(GMREIP0].30"S`"V:$;A&@(="
|
||||
M%K`L!PB>VZ6G!#TW-`+,`+9H1MD:`AT(6L"P'")K'_Z%?V.97[VFIZV57Y#%
|
||||
M-<\IIW%-"T]?]$^TVMWAVR4"`POT`@2`("#9([&?@`4`"71E<W0S+F)I;@H#
|
||||
M`H1PWX`-6M0!RN%P`1!D554O5P5^))))))))))))))))))))))))))))))))
|
||||
M))))))))))))))))))))))))))))))SO.\[S<:UGCPYS=>O+LEY]]M9^&\\,
|
||||
MWO7CO^DQF89X_9MAKF??:-?Q7/7Y`!`!`#848765^/?V]?3S\O'P[^[M[.OJ
|
||||
MZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`O[Z]
|
||||
MO+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV<FYJ9F)>6E923DI&0
|
||||
MCXZ-C(N*B8B'AH6$@X*!@']^??=]3[8AOPALOH4&#J;"`FDX$V"95@TP3;@P
|
||||
MF6DRPI=O")0\&G@!T,0$TG`FN3*KFER;<&$RTF6%+MV1*'@T[`.AB`FDX$UB
|
||||
M958T/&FX`#:3+"EVZ(E#P:=`'0Q`32<":I,JJ:'C3<`!M)EA2^4__8C^QK(_
|
||||
M>\:'K=J/R*(<ZY#CV(<&IZ_]"_:`$R,0$"4"`POT`@2`("#4/L00@`4`"71E
|
||||
M<W0T+F)I;@H#`@*,&8$-6M0!R^!P`1!D554O5P5^I)))))))))))))))))))
|
||||
M))))))))))))))))))))))))))))))))))))))))))SO.\YS<:UGCPYS=>O+
|
||||
MLEY]]M9^&\\,WO7CO^DQF89X_9MAKF??:-?Q7/7Y`!`!`#7=,+*J?'O[>OIY
|
||||
M^7CX=_=V]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGYV;F9>5DY&/C
|
||||
M8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!/ST[.3<U,
|
||||
MS$O+2LI)R4C(1\=&QD7%1,1#PT+"0<%`P#^_/ON^Z^V(;\(;+Z%!@ZFP@)I.
|
||||
M!-@F58-,$VX,)EI,L*7:Y$H>#2X!T,0$TG`FL3*K&EB;<&$RTF6%+MX1*'@T
|
||||
M\`.AB`FDX$U2954T/&FX`#:3+"EV[(E#P:=@'0Q`32<":A,JH:'C3<`!M)EA
|
||||
M2^=?_L1_8UD?O>-#UNU'Y%$.=<AQ[$.#4]?^A?M`Y!DD9R4"`PO\`@2`("#R
|
||||
M5=&Y@`4`"71E<W0U+F)I;@H#`BI\2($-6M0!S.]X`1!D554O=6ZDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG.\[SO-Q
|
||||
MFM>/..;N7KV[)>??;>LS[/'-[UX[_28S,,\?L,TUS/OM&_Q7/7Y`!`!`#6<+
|
||||
MK*J?'O[>OIY^7CX=_=V]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGY
|
||||
MV;F9>5DY&/C8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14
|
||||
M-!/ST[.3<U,S$O+2LI)R4C(1\=&QD7%1,1#PT+"0<%`P#^_/ON^X^W$)PA)M
|
||||
MD@@5^H.&2UDI2.+AC"BYI<-/"!MIL`Z/;L$0M;)V8*FSADM9*4CBP8PHL:6#
|
||||
M3P@;:;`.CVZ!$+6R=&"ILX9+62E(XJ&,**FE0T\(&VFP#H]N01"ULG)@J;.&
|
||||
M2UDI2.*!C"BAI0-/"!MIL`Z/G'_[B/[&LC][QH>MVH_(HAYUR'CV(>#4]?^@
|
||||
M_:`_"MBZ)0(#"_P"!(`@(/](I#:`!0`)=&5S=#8N8FEN"@,"%79G@0U:U`'-
|
||||
M[G@!$&1552]U;J2222222222222222222222222222222222222222222222
|
||||
M222222222222222<[SO.\W&:UX\XYNY>O;LEY]]MZS/L\<WO7CO])C,PSQ^P
|
||||
MS37,^^T;_%<]?D`$`$`-TX7654^/?V]?3S\O'P[^[M[.OJZ>CGYN7DX^+AX-
|
||||
M_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`O[Z]O+NZN;BWMK6TL[
|
||||
M*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV<FYJ9F)>6E923DI&0CXZ-C(N*B8B'AH
|
||||
M6$@X*!@']^??=]Q]N(3A"3;)!`K]0<,EK)2D<7#&%%S2X:>$#;38!T>W8(A:
|
||||
MV3LP5-G#):R4I'%@QA18TL&GA`VTV`='MT"(6MDZ,%39PR6LE*1Q4,845-*A
|
||||
MIX0-M-@'1[<@B%K9.3!4V<,EK)2D<4#&%%#2@:>$#;38!T?./_W$?V-9'[WC
|
||||
;0];M1^11#SKD/'L0\&IZ_]!^T!UW5E$#!00`
|
||||
M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``EV&"+"$"`PL`!0`0`````(````=T
|
||||
M97-T9&ER"@,"5N<QTHH!U0&_NE<D)`(#"^D"!+`)(,UPRGR``P`(=&5S="YB
|
||||
M:6X*`P(\[7R!#5K4`<KT90$G96!4'U5V7;^4DG')SV6660QPV663&,62$X9"
|
||||
M223AD)"2220DXY))(0A))"$)))"22$(2$LVU;WM],PZ`?1T#KC^>NI_W0?[W
|
||||
MVO?=>:\Z7^@`0`$`R""?GX]O7T\O'O[NSKZNGHY^7DX^+AX-_=W-K9U];5U-
|
||||
M/2T,_-S,K)R,?&Q<3#P;^]O+NYN+>VM;2SLK&OKJVKJJFGI:2CHJ&@GYV<FY
|
||||
MF7EI232R4C(1Z%`?CHR*B8<Z<-FH:$@H!^?'MZ>'9T<W)Q;VUK:6=E8V%?75
|
||||
MM95U53(3?U_(_0)3Z)3G^$2718HP9Y87:C@IIBF4%^9"T7:=1C+#.,"H1_^@
|
||||
ME,9I"E]E4*Q65@N+`9%H-RX'=>$&P`\Q!(R">9A6-`NFH9;8-YN'@X!@<@^N
|
||||
M81.@IG88#P-MZ'N]AU?0C?Q80(T8,><*'DT)@V+XX.8Z'"($J>&%%CMC0_GQ
|
||||
M4(!L(0T(A-(QG)`O)0`QGD%J)0(#"^L"!(`@(,:R$WZ``P`)=&5S=#$N8FEN
|
||||
M"@,"$I6A@`U:U`'-\6<!$&1&92]7!7^22222222222222222222222222222
|
||||
M222222222222222222222222222222223GY^RW,[??J[><7#G7SNUN[YG1F[
|
||||
MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&PPZ<-FGU\_'O[>OIY^7CX=_=V
|
||||
M]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGYV;F9>5DY&/C8N)AX6#@
|
||||
M7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!/ST[.3<U,S$O+2LI)
|
||||
MR4C(1\=&QD7%1,1#PT+"0<%`P#_[WL?R%+A2U?J5"@,[&`%LT(W2-`0Z$+6!
|
||||
M8#A$]N4M."'IR:`68`6S0C<(T!#H0M8%@.$3VW2TX(>FYH!9@!;-"-LC0$.A
|
||||
M"U@6`X1/;5+3@AZ:F@%F`%LT(VB-`0Z$+6!8#A$UA]Z%,?GS*>SVE?X8*>=C
|
||||
M4\-BG=.J=HXIZ?]R?M!(:PP')0(#"^L"!(`@(<NO9O&``P`)=&5S=#(N8FEN
|
||||
M"@,"A/;"@`U:U`',\&<!$&1&92]7!7^22222222222222222222222222222
|
||||
M222222222222222222222222222222223GY^RW,[??J[><7#G7SNUN[YG1F[
|
||||
MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&IATX;-/KY^/?V]?3S\O'P[^[M
|
||||
M[.OJZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`
|
||||
MO[Z]O+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV<FYJ9F)>6E923
|
||||
MDI&0CXZ-C(N*B8B'AH6$@X*!@'_WO8_D*7"EJ_4J%`9V,`+9H1ND:`AT(6L"
|
||||
MP'")[<I:<$/3DT`LP`MFA&X1H"'0A:P+`<(GMNEIP0]-S0"S`"V:$;9&@(="
|
||||
M%K`L!PB>VJ6G!#TU-`+,`+9H1M$:`AT(6L"P'")K#[T*8_/F4]GM*_PP4\[&
|
||||
MIX;%.Z=4[1Q3T_[D_:#Z7*U;)0(#"_<"!(`@(-DCL9^``P`)=&5S=#,N8FEN
|
||||
M"@,"A'#?@`U:U`'.YG,!$&1552]7!7XDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG>\[SO-RUK/'AS>Z]>]72\[VUGX;
|
||||
MSPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!LK,L+N/CW]O7T\_+Q\._N
|
||||
M[>SKZNGHY^;EY./BX>#?WMW<V]K9V-?6U=33TM'0S\[-S,O*R<C'QL7$P\+!
|
||||
MP+^^O;R[NKFXM[:UM+.RL;"OKJVLJZJIJ*>FI:2CHJ&@GYZ=G)N:F9B7EI64
|
||||
MDY*1D(^.C8R+BHF(AX:%A(."@8!_?O_[[UOQB$^$)+[%!@ZJP@)I6!-DF59-
|
||||
M,DTP85+::84MW9$H?1AV`=#$!-*P)L$RK!I@FF#"I;33"ENZ(E#Z,.@#H8@)
|
||||
MI6!-<F57-#AI,`!MIIA2W<D2A]&'(!T,0$TK`FX)E7!H<-)@`-M-,*7RW][$
|
||||
M+?7[(?3[2/T-$/>UH>G1#RK4/$L0^/_<7F@SHER0)0(#"_<"!(`@(-0^Q!"`
|
||||
M`P`)=&5S=#0N8FEN"@,"`HP9@0U:U`'/YW,!$&1552]7!7XDDDDDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG.\[SG-RUK/'
|
||||
MASFZ]>]72\[VUGX;SPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!L*,KK
|
||||
M*_'O[>OIY^7CX=_=V]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGYV;
|
||||
MF9>5DY&/C8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!
|
||||
M/ST[.3<U,S$O+2LI)R4C(1\=&QD7%1,1#PT+"0<%`P#^_?_WWJ?C$.>$.%]B
|
||||
M@P=380$TG`FR3*LFF2;D&$RVFF%+=@B4/HPP`=#$!-)P)KDRJYI<FY!A,MII
|
||||
MA2W=D2A]&'8!T,0$TG`FL3*K&APTY``;::84MW1$H?1AT`=#$!-)P)JDRJIH
|
||||
M<-.0`&VFF%+Y3^]B%/K]D/I]I'Z&B'O:T/3HAY5J'B6(?'_N+S0M?'0I)0(#
|
||||
M"X`#!(`@(/)5T;F``P`)=&5S=#4N8FEN"@,"*GQ(@0U:U`'([WP!$&1552]U
|
||||
M;J2222222222222222222222222222222222222222222222222222222222
|
||||
M222<[SO.\W+-:\><<W<O7O5TO.]MYF?9XZUO?CO]%F,,\?C,,TUW/OM&_7OX
|
||||
M'GK\@`@`@!K.%UE5/CW]O7T\_+Q\._N[>SKZNGHY^;EY./BX>#?WMW<V]K9V
|
||||
M-?6U=33TM'0S\[-S,O*R<C'QL7$P\+!P+^^O;R[NKFXM[:UM+.RL;"OKJVLJ
|
||||
MZJIJ*>FI:2CHJ&@GYZ=G)N:F9B7EI64DY*1D(^.C8R+BHF(AX:%A(."@8!_?
|
||||
MO_[[W'XXA.D)1LT$"OW!PR6LE*QQ<,847-+AIH@;:C`.CV[!$+6S=F"ILX9+
|
||||
M62E8XL&,*+&E@TT0-M1@'1[=`B%K9NC!4V<,EK)2L<5#&%%32H::(&VHP#H]
|
||||
MN01"ULW)@J;.&2UDI6.*!C"BAI0--$#;48!T?G'][B''U_9#Z?:1^AHA[VM#
|
||||
MT\$/*RH>)D0^/_</F@#V;XCT)0(#"X`#!(`@(/](I#:``P`)=&5S=#8N8FEN
|
||||
M"@,"%79G@0U:U`')[GP!$&1552]U;J222222222222222222222222222222
|
||||
M2222222222222222222222222222222<[SO.\W+-:\><<W<O7O5TO.]MYF?9
|
||||
MXZUO?CO]%F,,\?C,,TUW/OM&_7OX'GK\@`@`@!NG"ZRJGQ[^WKZ>?EX^'?W=
|
||||
MO9U]73T<_-R\G'Q</!O[V[N;>UL[&OK:NIIZ6CH9^=FYF7E9.1CXV+B8>%@X
|
||||
M%_?7MY=W5S<6]M:VEG96-A7UU;65=54U%/34M)1T5#03\].SDW-3,Q+RTK*2
|
||||
M<E(R$?'1L9%Q43$0\-"PD'!0,`_OW_]][C\<0G2$HV:"!7[@X9+62E8XN&,*
|
||||
M+FEPTT0-M1@'1[=@B%K9NS!4V<,EK)2L<6#&%%C2P::(&VHP#H]N@1"ULW1@
|
||||
MJ;.&2UDI6.*AC"BII4--$#;48!T>W((A:V;DP5-G#):R4K'%`QA10TH&FB!M
|
||||
KJ,`Z/SC^]Q#CZ_LA]/M(_0T0][6AZ>"'E94/$R(?'_N'S0`==U91`P4$````
|
||||
`
|
||||
end
|
||||
|
@ -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
|
@ -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));
|
||||
}
|
||||
|
4
libarchive/test/test_read_format_raw.data.gz.uu
Normal file
4
libarchive/test/test_read_format_raw.data.gz.uu
Normal 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
|
53
libarchive/test/test_read_format_tar_empty_with_gnulabel.c
Normal file
53
libarchive/test/test_read_format_tar_empty_with_gnulabel.c
Normal 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));
|
||||
}
|
231
libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu
Normal file
231
libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu
Normal 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
|
@ -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. */
|
||||
}
|
||||
|
102
libarchive/test/test_read_format_zip_7075_utf8_paths.c
Normal file
102
libarchive/test/test_read_format_zip_7075_utf8_paths.c
Normal 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);
|
||||
}
|
20
libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu
Normal file
20
libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu
Normal 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
|
93
libarchive/test/test_read_format_zip_extra_padding.c
Normal file
93
libarchive/test/test_read_format_zip_extra_padding.c
Normal 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);
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
15
tar/bsdtar.1
15
tar/bsdtar.1
@ -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.
|
||||
|
43
tar/bsdtar.c
43
tar/bsdtar.c
@ -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;
|
||||
|
@ -135,6 +135,7 @@ enum {
|
||||
OPTION_CHROOT,
|
||||
OPTION_CLEAR_NOCHANGE_FFLAGS,
|
||||
OPTION_EXCLUDE,
|
||||
OPTION_EXCLUDE_VCS,
|
||||
OPTION_FFLAGS,
|
||||
OPTION_FORMAT,
|
||||
OPTION_GID,
|
||||
|
@ -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 },
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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...". */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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("..");
|
||||
}
|
||||
|
@ -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("..");
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user