aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2019-12-28 23:40:32 +0000
committerMartin Matuska <mm@FreeBSD.org>2019-12-28 23:40:32 +0000
commit6922acad9a482c17c7af1acdb4d11d03f19bb1dc (patch)
treeb7e2717582504805f31e2195f7c74c5d6fa82a45
parenta297901e6c90d415ac49c88002dd4e02dc49e32b (diff)
downloadsrc-6922acad9a482c17c7af1acdb4d11d03f19bb1dc.tar.gz
src-6922acad9a482c17c7af1acdb4d11d03f19bb1dc.zip
Update vendor/libarchive/dist to git 1dae5a549fe4ab99fd3a49a9edcf897a7b2b1844
Relevant vendor changes: Issue #351: Refactor and implement private state logic for write filters PR #1252: RAR5 reader - verify window size for solid files (OSS-Fuzz 15482) PR #1255: zip writer - don't append unused NUL for directories PR #1260: Fix sparse file offset overflow on 32-bit systems PR #1263: UNICODE filename support for reading lha/lzh format Issue #1276: Bugfix and optimize archive_wstring_append_from_mbs() PR #1288: Add the "xattrhdr" option to pax write options PR #1295: 7z reader - fix reading archives with digests in PackInfo PR #1296: RAR5 reader - verify window size for multivolume archives PR #1297: ZIP reader - support LZMA_STREAM_END marker in 'lzma alone' files Issue #1298: Fix a heap-buffer-overflow in archive_string_append_from_wcs() OSS-Fuzz 19360, 19362: LHA reader - plug two memory leaks on error Fix possible off-by-one when dealing with readlink(2)
Notes
Notes: svn path=/vendor/libarchive/dist/; revision=356163
-rw-r--r--.cirrus.yml71
-rw-r--r--.github/workflows/ci.yml85
-rw-r--r--Makefile.am10
-rw-r--r--build/ci/cirrus_ci/Dockerfile.fc30.distcheck2
-rwxr-xr-xbuild/ci/github_actions/ci.cmd79
-rwxr-xr-xbuild/ci/github_actions/macos.sh10
-rw-r--r--configure.ac2
-rw-r--r--examples/minitar/minitar.c3
-rw-r--r--libarchive/archive_entry.h3
-rw-r--r--libarchive/archive_entry_acl.321
-rw-r--r--libarchive/archive_hmac.c2
-rw-r--r--libarchive/archive_read_disk_entry_from_file.c6
-rw-r--r--libarchive/archive_read_disk_posix.c12
-rw-r--r--libarchive/archive_read_support_format_7zip.c2
-rw-r--r--libarchive/archive_read_support_format_lha.c191
-rw-r--r--libarchive/archive_read_support_format_rar5.c50
-rw-r--r--libarchive/archive_read_support_format_zip.c17
-rw-r--r--libarchive/archive_string.c37
-rw-r--r--libarchive/archive_write.c80
-rw-r--r--libarchive/archive_write_add_filter_b64encode.c12
-rw-r--r--libarchive/archive_write_add_filter_bzip2.c10
-rw-r--r--libarchive/archive_write_add_filter_compress.c22
-rw-r--r--libarchive/archive_write_add_filter_gzip.c9
-rw-r--r--libarchive/archive_write_add_filter_lz4.c11
-rw-r--r--libarchive/archive_write_add_filter_lzop.c10
-rw-r--r--libarchive/archive_write_add_filter_program.c12
-rw-r--r--libarchive/archive_write_add_filter_uuencode.c12
-rw-r--r--libarchive/archive_write_add_filter_xz.c9
-rw-r--r--libarchive/archive_write_add_filter_zstd.c12
-rw-r--r--libarchive/archive_write_disk_posix.c2
-rw-r--r--libarchive/archive_write_private.h8
-rw-r--r--libarchive/archive_write_set_format_pax.c22
-rw-r--r--libarchive/archive_write_set_format_zip.c15
-rw-r--r--libarchive/archive_write_set_options.328
-rw-r--r--libarchive/test/CMakeLists.txt3
-rw-r--r--libarchive/test/test_open_failure.c16
-rw-r--r--libarchive/test/test_open_fd.c27
-rw-r--r--libarchive/test/test_pax_xattr_header.c130
-rw-r--r--libarchive/test/test_pax_xattr_header_all.tar.uu72
-rw-r--r--libarchive/test/test_pax_xattr_header_libarchive.tar.uu72
-rw-r--r--libarchive/test/test_pax_xattr_header_schily.tar.uu72
-rw-r--r--libarchive/test/test_read_disk_directory_traversals.c3
-rw-r--r--libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu7
-rw-r--r--libarchive/test/test_read_format_7zip_packinfo_digests.c77
-rw-r--r--libarchive/test/test_read_format_lha_filename_utf16.c143
-rw-r--r--libarchive/test/test_read_format_lha_filename_utf16.lzh.uu19
-rw-r--r--libarchive/test/test_read_format_rar5.c90
-rw-r--r--libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu73
-rw-r--r--libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu16
-rw-r--r--libarchive/test/test_sparse_basic.c11
-rw-r--r--test_utils/test_main.c2
51 files changed, 1346 insertions, 364 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index d87e48983e8e..25c256113e62 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -10,9 +10,9 @@ FreeBSD_task:
BS: cmake
matrix:
freebsd_instance:
- image: freebsd-12-0-release-amd64
+ image_family: freebsd-12-1
freebsd_instance:
- image: freebsd-11-2-release-amd64
+ image: freebsd-11-3-stable-amd64-v20190801
prepare_script:
- ./build/ci/cirrus_ci/ci.sh prepare
configure_script:
@@ -26,28 +26,6 @@ FreeBSD_task:
install_script:
- ./build/ci/build.sh -a install
-MacOS_task:
- matrix:
- env:
- BS: autotools
- env:
- BS: cmake
- matrix:
- osx_instance:
- image: mojave-xcode-10.2
- 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_30_task:
container:
dockerfile: build/ci/cirrus_ci/Dockerfile.fc30
@@ -66,51 +44,6 @@ Fedora_30_task:
install_script:
- ./build/ci/build.sh -a install
-Fedora_30_distcheck_task:
- container:
- dockerfile: build/ci/cirrus_ci/Dockerfile.fc30.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
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 11fa1b6b8464..7d5ba4fa4d80 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,16 +1,44 @@
-name: Ubuntu
+name: CI
on: [push, pull_request]
jobs:
- Build-and-test:
+ MacOS:
+ runs-on: macos-latest
+ strategy:
+ matrix:
+ bs: [autotools, cmake]
+ steps:
+ - uses: actions/checkout@master
+ - name: Install dependencies
+ run: ./build/ci/github_actions/macos.sh prepare
+ - name: Autogen
+ run: ./build/ci/build.sh -a autogen
+ env:
+ BS: ${{ matrix.bs }}
+ - name: Configure
+ run: ./build/ci/build.sh -a configure
+ env:
+ BS: ${{ matrix.bs }}
+ - name: Build
+ run: ./build/ci/build.sh -a build
+ env:
+ BS: ${{ matrix.bs }}
+ - name: Test
+ run: ./build/ci/build.sh -a test
+ env:
+ BS: ${{ matrix.bs }}
+ SKIP_OPEN_FD_ERR_TEST: 1
+ - name: Install
+ run: ./build/ci/build.sh -a install
+ env:
+ BS: ${{ matrix.bs }}
+ Ubuntu:
runs-on: ubuntu-latest
-
strategy:
matrix:
bs: [autotools, cmake]
-
steps:
- uses: actions/checkout@master
- name: Install dependencies
@@ -31,7 +59,56 @@ jobs:
run: ./build/ci/build.sh -a test
env:
BS: ${{ matrix.bs }}
+ SKIP_OPEN_FD_ERR_TEST: 1
- name: Install
run: ./build/ci/build.sh -a install
env:
BS: ${{ matrix.bs }}
+
+ Ubuntu-distcheck:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - name: Install dependencies
+ run: sudo apt-get install -y build-essential cmake libssl-dev libacl1-dev libbz2-dev liblzma-dev libzip-dev liblz4-dev libzstd-dev lzop groff ghostscript
+ - name: Autogen
+ run: ./build/ci/build.sh -a autogen
+ - name: Configure
+ run: ./build/ci/build.sh -a configure
+ - name: Distcheck
+ run: ./build/ci/build.sh -a distcheck
+ env:
+ SKIP_OPEN_FD_ERR_TEST: 1
+
+ Windows:
+ runs-on: windows-latest
+ strategy:
+ matrix:
+ be: [mingw-gcc, msvc]
+ steps:
+ - uses: actions/checkout@master
+ - name: Install dependencies
+ run: ./build/ci/github_actions/ci.cmd deplibs
+ shell: cmd
+ env:
+ BE: ${{ matrix.be }}
+ - name: Configure
+ run: ./build/ci/github_actions/ci.cmd configure
+ shell: cmd
+ env:
+ BE: ${{ matrix.be }}
+ - name: Build
+ run: ./build/ci/github_actions/ci.cmd build
+ shell: cmd
+ env:
+ BE: ${{ matrix.be }}
+ - name: Test
+ run: ./build/ci/github_actions/ci.cmd test
+ shell: cmd
+ env:
+ BE: ${{ matrix.be }}
+ - name: Install
+ run: ./build/ci/github_actions/ci.cmd install
+ shell: cmd
+ env:
+ BE: ${{ matrix.be }}
diff --git a/Makefile.am b/Makefile.am
index 20eb5312e275..781bbf726c2d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -429,6 +429,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_open_file.c \
libarchive/test/test_open_filename.c \
libarchive/test/test_pax_filename_encoding.c \
+ libarchive/test/test_pax_xattr_header.c \
libarchive/test/test_read_data_large.c \
libarchive/test/test_read_disk.c \
libarchive/test/test_read_disk_directory_traversals.c \
@@ -448,6 +449,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_7zip_encryption_partially.c \
libarchive/test/test_read_format_7zip_encryption_header.c \
libarchive/test/test_read_format_7zip_malformed.c \
+ libarchive/test/test_read_format_7zip_packinfo_digests.c \
libarchive/test/test_read_format_ar.c \
libarchive/test/test_read_format_cab.c \
libarchive/test/test_read_format_cab_filename.c \
@@ -488,6 +490,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_lha.c \
libarchive/test/test_read_format_lha_bugfix_0.c \
libarchive/test/test_read_format_lha_filename.c \
+ libarchive/test/test_read_format_lha_filename_utf16.c \
libarchive/test/test_read_format_mtree.c \
libarchive/test/test_read_format_mtree_crash747.c \
libarchive/test/test_read_format_pax_bz2.c \
@@ -701,6 +704,9 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_fuzz.lzh.uu \
libarchive/test/test_fuzz_1.iso.Z.uu \
libarchive/test/test_pax_filename_encoding.tar.uu \
+ libarchive/test/test_pax_xattr_header_all.tar.uu \
+ libarchive/test/test_pax_xattr_header_libarchive.tar.uu \
+ libarchive/test/test_pax_xattr_header_schily.tar.uu \
libarchive/test/test_rar_multivolume_multiple_files.part1.rar.uu \
libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu \
libarchive/test/test_rar_multivolume_multiple_files.part3.rar.uu \
@@ -757,6 +763,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_7zip_lzma2.7z.uu \
libarchive/test/test_read_format_7zip_malformed.7z.uu \
libarchive/test/test_read_format_7zip_malformed2.7z.uu \
+ libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu \
libarchive/test/test_read_format_7zip_ppmd.7z.uu \
libarchive/test/test_read_format_7zip_symbolic_name.7z.uu \
libarchive/test/test_read_format_ar.ar.uu \
@@ -798,6 +805,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_iso_zisofs.iso.Z.uu \
libarchive/test/test_read_format_lha_bugfix_0.lzh.uu \
libarchive/test/test_read_format_lha_filename_cp932.lzh.uu \
+ libarchive/test/test_read_format_lha_filename_utf16.lzh.uu \
libarchive/test/test_read_format_lha_header0.lzh.uu \
libarchive/test/test_read_format_lha_header1.lzh.uu \
libarchive/test/test_read_format_lha_header2.lzh.uu \
@@ -835,6 +843,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar5_blake2.rar.uu \
libarchive/test/test_read_format_rar5_compressed.rar.uu \
libarchive/test/test_read_format_rar5_different_window_size.rar.uu \
+ libarchive/test/test_read_format_rar5_different_solid_window_size.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 \
@@ -866,6 +875,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar5_truncated_huff.rar.uu \
libarchive/test/test_read_format_rar5_win32.rar.uu \
libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \
+ libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \
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 \
diff --git a/build/ci/cirrus_ci/Dockerfile.fc30.distcheck b/build/ci/cirrus_ci/Dockerfile.fc30.distcheck
index b59044be37a8..0129ec44e92a 100644
--- a/build/ci/cirrus_ci/Dockerfile.fc30.distcheck
+++ b/build/ci/cirrus_ci/Dockerfile.fc30.distcheck
@@ -1,3 +1,3 @@
FROM fedora:30
-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
+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 xz zip
diff --git a/build/ci/github_actions/ci.cmd b/build/ci/github_actions/ci.cmd
new file mode 100755
index 000000000000..30626d5c2a40
--- /dev/null
+++ b/build/ci/github_actions/ci.cmd
@@ -0,0 +1,79 @@
+@ECHO OFF
+SET ZLIB_VERSION=1.2.11
+IF NOT "%BE%"=="mingw-gcc" (
+ IF NOT "%BE%"=="msvc" (
+ ECHO Environment variable BE must be mingw-gcc or msvc
+ EXIT /b 1
+ )
+)
+
+IF "%1"=="deplibs" (
+ 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
+ )
+ CD zlib-%ZLIB_VERSION%
+ IF "%BE%"=="mingw-gcc" (
+ SET PATH=C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
+ 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 16 2019" . || 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%"=="mingw-gcc" (
+ SET 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" (
+ MKDIR build_ci\cmake
+ CD build_ci\cmake
+ cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE="Release" ..\.. || EXIT /b 1
+ )
+) ELSE IF "%1%"=="build" (
+ IF "%BE%"=="mingw-gcc" (
+ SET 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" (
+ CD build_ci\cmake
+ cmake --build . --target ALL_BUILD --config Release
+ )
+) ELSE IF "%1%"=="test" (
+ IF "%BE%"=="mingw-gcc" (
+ SET 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" (
+ 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%"=="mingw-gcc" (
+ SET 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" (
+ cmake --build . --target INSTALL --config Release
+ )
+) ELSE (
+ ECHO "Usage: %0% deplibs|configure|build|test|install"
+ @EXIT /b 0
+)
+@EXIT /b 0
diff --git a/build/ci/github_actions/macos.sh b/build/ci/github_actions/macos.sh
new file mode 100755
index 000000000000..e51574cb6dfa
--- /dev/null
+++ b/build/ci/github_actions/macos.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+if [ "$1" = "prepare" ]
+then
+ set -x -e
+ 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
+fi
diff --git a/configure.ac b/configure.ac
index d77143e3fbc4..c7b1a5943e1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ AC_CONFIG_AUX_DIR([build/autoconf])
# M4 scripts
AC_CONFIG_MACRO_DIR([build/autoconf])
# Must follow AC_CONFIG macros above...
-AM_INIT_AUTOMAKE()
+AM_INIT_AUTOMAKE([1.11 dist-xz dist-zip])
AM_MAINTAINER_MODE([enable])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
diff --git a/examples/minitar/minitar.c b/examples/minitar/minitar.c
index 0b4b4147ca99..881f94b2d33e 100644
--- a/examples/minitar/minitar.c
+++ b/examples/minitar/minitar.c
@@ -398,6 +398,9 @@ extract(const char *filename, int do_extract, int flags)
}
archive_read_close(a);
archive_read_free(a);
+
+ archive_write_close(ext);
+ archive_write_free(ext);
exit(0);
}
diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h
index a1989ffa80f8..b7b3498a2035 100644
--- a/libarchive/archive_entry.h
+++ b/libarchive/archive_entry.h
@@ -524,9 +524,6 @@ __LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const char ** /* name */);
-__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
- int * /* type */, int * /* permset */, int * /* tag */,
- int * /* qual */, const wchar_t ** /* name */);
/*
* Construct a text-format ACL. The flags argument is a bitmask that
diff --git a/libarchive/archive_entry_acl.3 b/libarchive/archive_entry_acl.3
index 7dcc5854ce10..50dd642c20c6 100644
--- a/libarchive/archive_entry_acl.3
+++ b/libarchive/archive_entry_acl.3
@@ -34,7 +34,6 @@
.Nm archive_entry_acl_from_text ,
.Nm archive_entry_acl_from_text_w ,
.Nm archive_entry_acl_next ,
-.Nm archive_entry_acl_next_w ,
.Nm archive_entry_acl_reset ,
.Nm archive_entry_acl_to_text ,
.Nm archive_entry_acl_to_text_w ,
@@ -89,16 +88,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "const char **ret_name"
.Fc
.Ft int
-.Fo archive_entry_acl_next_w
-.Fa "struct archive_entry *a"
-.Fa "int type"
-.Fa "int *ret_type"
-.Fa "int *ret_permset"
-.Fa "int *ret_tag"
-.Fa "int *ret_qual"
-.Fa "const wchar_t **ret_name"
-.Fc
-.Ft int
.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
.Ft char *
.Fo archive_entry_acl_to_text
@@ -349,8 +338,6 @@ character
are skipped.
.Pp
.Fn archive_entry_acl_next
-and
-.Fn archive_entry_acl_next_w
return the next entry of the ACL list.
This functions may only be called after
.Fn archive_entry_acl_reset
@@ -358,9 +345,7 @@ has indicated the presence of extended ACL entries.
.Pp
.Fn archive_entry_acl_reset
prepare reading the list of ACL entries with
-.Fn archive_entry_acl_next
-or
-.Fn archive_entry_acl_next_w .
+.Fn archive_entry_acl_next .
The function returns 0 if no non-extended ACLs are found.
In this case, the access permissions should be obtained by
.Xr archive_entry_mode 3
@@ -447,9 +432,7 @@ if all entries were successfully parsed and
if one or more entries were invalid or non-parseable.
.Pp
.Fn archive_entry_acl_next
-and
-.Fn archive_entry_acl_next_w
-return
+returns
.Dv ARCHIVE_OK
on success,
.Dv ARCHIVE_EOF
diff --git a/libarchive/archive_hmac.c b/libarchive/archive_hmac.c
index 392916de5b7b..7c626df6e1f1 100644
--- a/libarchive/archive_hmac.c
+++ b/libarchive/archive_hmac.c
@@ -83,7 +83,9 @@ __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)
{
+#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
DWORD hash_len;
diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c
index 45417e9ac763..2a8cec8d1178 100644
--- a/libarchive/archive_read_disk_entry_from_file.c
+++ b/libarchive/archive_read_disk_entry_from_file.c
@@ -249,11 +249,11 @@ archive_read_disk_entry_from_file(struct archive *_a,
#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
if (S_ISLNK(st->st_mode)) {
- size_t linkbuffer_len = st->st_size + 1;
+ size_t linkbuffer_len = st->st_size;
char *linkbuffer;
int lnklen;
- linkbuffer = malloc(linkbuffer_len);
+ linkbuffer = malloc(linkbuffer_len + 1);
if (linkbuffer == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Couldn't read link data");
@@ -280,7 +280,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
free(linkbuffer);
return (ARCHIVE_FAILED);
}
- linkbuffer[lnklen] = 0;
+ linkbuffer[lnklen] = '\0';
archive_entry_set_symlink(entry, linkbuffer);
free(linkbuffer);
}
diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
index 87963c3c7c28..183ca1e8790d 100644
--- a/libarchive/archive_read_disk_posix.c
+++ b/libarchive/archive_read_disk_posix.c
@@ -694,6 +694,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
struct tree *t = a->tree;
int r;
ssize_t bytes;
+ int64_t sparse_bytes;
size_t buffbytes;
int empty_sparse_region = 0;
@@ -792,9 +793,9 @@ _archive_read_data_block(struct archive *_a, const void **buff,
a->archive.state = ARCHIVE_STATE_FATAL;
goto abort_read_data;
}
- bytes = t->current_sparse->offset - t->entry_total;
- t->entry_remaining_bytes -= bytes;
- t->entry_total += bytes;
+ sparse_bytes = t->current_sparse->offset - t->entry_total;
+ t->entry_remaining_bytes -= sparse_bytes;
+ t->entry_total += sparse_bytes;
}
/*
@@ -2172,7 +2173,7 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
#elif defined(O_SEARCH)
/* SunOS */
const int o_flag = O_SEARCH;
-#elif defined(O_EXEC)
+#elif defined(__FreeBSD__) && defined(O_EXEC)
/* FreeBSD */
const int o_flag = O_EXEC;
#endif
@@ -2198,7 +2199,8 @@ 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)
+#if defined(O_PATH) || defined(O_SEARCH) || \
+ (defined(__FreeBSD__) && 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
diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
index 8ca422ec0669..87c6c5272197 100644
--- a/libarchive/archive_read_support_format_7zip.c
+++ b/libarchive/archive_read_support_format_7zip.c
@@ -1787,7 +1787,7 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
return (0);
}
- if (*p != kSize)
+ if (*p != kCRC)
return (-1);
if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c
index 95c99bb1f31e..35405bcdd97f 100644
--- a/libarchive/archive_read_support_format_lha.c
+++ b/libarchive/archive_read_support_format_lha.c
@@ -175,7 +175,9 @@ struct lha {
struct archive_string gname;
uint16_t header_crc;
uint16_t crc;
- struct archive_string_conv *sconv;
+ /* dirname and filename could be in different codepages */
+ struct archive_string_conv *sconv_dir;
+ struct archive_string_conv *sconv_fname;
struct archive_string_conv *opt_sconv;
struct archive_string dirname;
@@ -232,8 +234,8 @@ static time_t lha_dos_time(const unsigned char *);
static time_t lha_win_time(uint64_t, long *);
static unsigned char lha_calcsum(unsigned char, const void *,
int, size_t);
-static int lha_parse_linkname(struct archive_string *,
- struct archive_string *);
+static int lha_parse_linkname(struct archive_wstring *,
+ struct archive_wstring *);
static int lha_read_data_none(struct archive_read *, const void **,
size_t *, int64_t *);
static int lha_read_data_lzh(struct archive_read *, const void **,
@@ -473,13 +475,15 @@ static int
archive_read_format_lha_read_header(struct archive_read *a,
struct archive_entry *entry)
{
- struct archive_string linkname;
- struct archive_string pathname;
+ struct archive_wstring linkname;
+ struct archive_wstring pathname;
struct lha *lha;
const unsigned char *p;
const char *signature;
int err;
-
+ struct archive_mstring conv_buffer;
+ const wchar_t *conv_buffer_p;
+
lha_crc16_init();
a->archive.archive_format = ARCHIVE_FORMAT_LHA;
@@ -561,10 +565,13 @@ archive_read_format_lha_read_header(struct archive_read *a,
archive_string_empty(&lha->dirname);
archive_string_empty(&lha->filename);
lha->dos_attr = 0;
- if (lha->opt_sconv != NULL)
- lha->sconv = lha->opt_sconv;
- else
- lha->sconv = NULL;
+ if (lha->opt_sconv != NULL) {
+ lha->sconv_dir = lha->opt_sconv;
+ lha->sconv_fname = lha->opt_sconv;
+ } else {
+ lha->sconv_dir = NULL;
+ lha->sconv_fname = NULL;
+ }
switch (p[H_LEVEL_OFFSET]) {
case 0:
@@ -594,12 +601,54 @@ archive_read_format_lha_read_header(struct archive_read *a,
return (truncated_error(a));
/*
- * Make a pathname from a dirname and a filename.
- */
- archive_string_concat(&lha->dirname, &lha->filename);
+ * Make a pathname from a dirname and a filename, after converting to Unicode.
+ * This is because codepages might differ between dirname and filename.
+ */
archive_string_init(&pathname);
archive_string_init(&linkname);
- archive_string_copy(&pathname, &lha->dirname);
+ archive_string_init(&conv_buffer.aes_mbs);
+ archive_string_init(&conv_buffer.aes_mbs_in_locale);
+ archive_string_init(&conv_buffer.aes_utf8);
+ archive_string_init(&conv_buffer.aes_wcs);
+ if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to Unicode.",
+ archive_string_conversion_charset_name(lha->sconv_dir));
+ err = ARCHIVE_FATAL;
+ } else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
+ err = ARCHIVE_FATAL;
+ if (err == ARCHIVE_FATAL) {
+ archive_mstring_clean(&conv_buffer);
+ archive_wstring_free(&pathname);
+ archive_wstring_free(&linkname);
+ return (err);
+ }
+ archive_wstring_copy(&pathname, &conv_buffer.aes_wcs);
+
+ archive_string_empty(&conv_buffer.aes_mbs);
+ archive_string_empty(&conv_buffer.aes_mbs_in_locale);
+ archive_string_empty(&conv_buffer.aes_utf8);
+ archive_wstring_empty(&conv_buffer.aes_wcs);
+ if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to Unicode.",
+ archive_string_conversion_charset_name(lha->sconv_fname));
+ err = ARCHIVE_FATAL;
+ }
+ else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
+ err = ARCHIVE_FATAL;
+ if (err == ARCHIVE_FATAL) {
+ archive_mstring_clean(&conv_buffer);
+ archive_wstring_free(&pathname);
+ archive_wstring_free(&linkname);
+ return (err);
+ }
+ archive_wstring_concat(&pathname, &conv_buffer.aes_wcs);
+ archive_mstring_clean(&conv_buffer);
if ((lha->mode & AE_IFMT) == AE_IFLNK) {
/*
@@ -610,8 +659,8 @@ archive_read_format_lha_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Unknown symlink-name");
- archive_string_free(&pathname);
- archive_string_free(&linkname);
+ archive_wstring_free(&pathname);
+ archive_wstring_free(&linkname);
return (ARCHIVE_FAILED);
}
} else {
@@ -629,39 +678,13 @@ archive_read_format_lha_read_header(struct archive_read *a,
/*
* Set basic file parameters.
*/
- if (archive_entry_copy_pathname_l(entry, pathname.s,
- pathname.length, lha->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(lha->sconv));
- err = ARCHIVE_WARN;
- }
- archive_string_free(&pathname);
+ archive_entry_copy_pathname_w(entry, pathname.s);
+ archive_wstring_free(&pathname);
if (archive_strlen(&linkname) > 0) {
- if (archive_entry_copy_symlink_l(entry, linkname.s,
- linkname.length, lha->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Linkname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(lha->sconv));
- err = ARCHIVE_WARN;
- }
+ archive_entry_copy_symlink_w(entry, linkname.s);
} else
archive_entry_set_symlink(entry, NULL);
- archive_string_free(&linkname);
+ archive_wstring_free(&linkname);
/*
* When a header level is 0, there is a possibility that
* a pathname and a symlink has '\' character, a directory
@@ -1208,6 +1231,26 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
archive_strncpy(&lha->filename,
(const char *)extdheader, datasize);
break;
+ case EXT_UTF16_FILENAME:
+ if (datasize == 0) {
+ /* maybe directory header */
+ archive_string_empty(&lha->filename);
+ break;
+ } else if (datasize & 1) {
+ /* UTF-16 characters take always 2 or 4 bytes */
+ goto invalid;
+ }
+ if (extdheader[0] == '\0')
+ goto invalid;
+ archive_string_empty(&lha->filename);
+ archive_array_append(&lha->filename,
+ (const char *)extdheader, datasize);
+ /* Setup a string conversion for a filename. */
+ lha->sconv_fname = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (lha->sconv_fname == NULL)
+ return (ARCHIVE_FATAL);
+ break;
case EXT_DIRECTORY:
if (datasize == 0 || extdheader[0] == '\0')
/* no directory name data. exit this case. */
@@ -1228,6 +1271,36 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
/* invalid directory data */
goto invalid;
break;
+ case EXT_UTF16_DIRECTORY:
+ /* UTF-16 characters take always 2 or 4 bytes */
+ if (datasize == 0 || (datasize & 1) || extdheader[0] == '\0')
+ /* no directory name data. exit this case. */
+ goto invalid;
+
+ archive_string_empty(&lha->dirname);
+ archive_array_append(&lha->dirname,
+ (const char *)extdheader, datasize);
+ lha->sconv_dir = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (lha->sconv_dir == NULL)
+ return (ARCHIVE_FATAL);
+ else {
+ /*
+ * Convert directory delimiter from 0xFF
+ * to '/' for local system.
+ */
+ /* UTF-16LE character */
+ uint16_t *utf16name = (uint16_t *)lha->dirname.s;
+ for (i = 0; i < lha->dirname.length / 2; i++) {
+ if (utf16name[i] == 0xFFFF)
+ utf16name[i] = L'/';
+ }
+ /* Is last character directory separator? */
+ if (utf16name[lha->dirname.length / 2 - 1] != L'/')
+ /* invalid directory data */
+ goto invalid;
+ }
+ break;
case EXT_DOS_ATTR:
if (datasize == 2)
lha->dos_attr = (unsigned char)
@@ -1276,11 +1349,16 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
charset = cp.s;
break;
}
- lha->sconv =
+ lha->sconv_dir =
+ archive_string_conversion_from_charset(
+ &(a->archive), charset, 1);
+ lha->sconv_fname =
archive_string_conversion_from_charset(
&(a->archive), charset, 1);
archive_string_free(&cp);
- if (lha->sconv == NULL)
+ if (lha->sconv_dir == NULL)
+ return (ARCHIVE_FATAL);
+ if (lha->sconv_fname == NULL)
return (ARCHIVE_FATAL);
}
break;
@@ -1336,8 +1414,7 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
}
break;
case EXT_TIMEZONE: /* Not supported */
- case EXT_UTF16_FILENAME: /* Not supported */
- case EXT_UTF16_DIRECTORY: /* Not supported */
+ break;
default:
break;
}
@@ -1600,19 +1677,19 @@ archive_read_format_lha_cleanup(struct archive_read *a)
* then a archived pathname is 'xxx/bbb|aaa/bb/cc'
*/
static int
-lha_parse_linkname(struct archive_string *linkname,
- struct archive_string *pathname)
+lha_parse_linkname(struct archive_wstring *linkname,
+ struct archive_wstring *pathname)
{
- char * linkptr;
+ wchar_t * linkptr;
size_t symlen;
- linkptr = strchr(pathname->s, '|');
+ linkptr = wcschr(pathname->s, L'|');
if (linkptr != NULL) {
- symlen = strlen(linkptr + 1);
- archive_strncpy(linkname, linkptr+1, symlen);
+ symlen = wcslen(linkptr + 1);
+ archive_wstrncpy(linkname, linkptr+1, symlen);
*linkptr = 0;
- pathname->length = strlen(pathname->s);
+ pathname->length = wcslen(pathname->s);
return (1);
}
diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c
index e58cbbf6d829..ce38b1fc990f 100644
--- a/libarchive/archive_read_support_format_rar5.c
+++ b/libarchive/archive_read_support_format_rar5.c
@@ -63,6 +63,7 @@
#if defined DEBUG
#define DEBUG_CODE if(1)
+#define LOG(...) do { printf("rar5: " __VA_ARGS__); puts(""); } while(0)
#else
#define DEBUG_CODE if(0)
#endif
@@ -115,6 +116,8 @@ struct file_header {
/* Optional redir fields */
uint64_t redir_type;
uint64_t redir_flags;
+
+ ssize_t solid_window_size; /* Used in file format check. */
};
enum EXTRA {
@@ -1177,7 +1180,7 @@ static int process_main_locator_extra_block(struct archive_read* a,
static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
ssize_t* extra_data_size)
{
- size_t hash_type;
+ size_t hash_type = 0;
size_t value_len;
if(!read_var_sized(a, &hash_type, &value_len))
@@ -1303,7 +1306,7 @@ static int parse_file_extra_htime(struct archive_read* a,
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
{
char unix_time = 0;
- size_t flags;
+ size_t flags = 0;
size_t value_len;
enum HTIME_FLAGS {
@@ -1665,6 +1668,17 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
g_unpack_window_size << ((compression_info >> 10) & 15);
rar->cstate.method = c_method;
rar->cstate.version = c_version + 50;
+ rar->file.solid = (compression_info & SOLID) > 0;
+
+ /* Archives which declare solid files without initializing the window
+ * buffer first are invalid. */
+
+ if(rar->file.solid > 0 && rar->cstate.window_buf == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Declared solid file, but no window buffer "
+ "initialized yet.");
+ return ARCHIVE_FATAL;
+ }
/* Check if window_size is a sane value. Also, if the file is not
* declared as a directory, disallow window_size == 0. */
@@ -1676,12 +1690,36 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
return ARCHIVE_FATAL;
}
- /* Values up to 64M should fit into ssize_t on every
- * architecture. */
- rar->cstate.window_size = (ssize_t) window_size;
+ if(rar->file.solid > 0) {
+ /* Re-check if current window size is the same as previous
+ * window size (for solid files only). */
+ if(rar->file.solid_window_size > 0 &&
+ rar->file.solid_window_size != (ssize_t) window_size)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Window size for this solid file doesn't match "
+ "the window size used in previous solid file. ");
+ return ARCHIVE_FATAL;
+ }
+ }
+
+ /* If we're currently switching volumes, ignore the new definition of
+ * window_size. */
+ if(rar->cstate.switch_multivolume == 0) {
+ /* Values up to 64M should fit into ssize_t on every
+ * architecture. */
+ rar->cstate.window_size = (ssize_t) window_size;
+ }
+
+ if(rar->file.solid > 0 && rar->file.solid_window_size == 0) {
+ /* Solid files have to have the same window_size across
+ whole archive. Remember the window_size parameter
+ for first solid file found. */
+ rar->file.solid_window_size = rar->cstate.window_size;
+ }
+
init_window_mask(rar);
- rar->file.solid = (compression_info & SOLID) > 0;
rar->file.service = 0;
if(!read_var_sized(a, &host_os, NULL))
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
index 9934bf1504dc..6581ca0acf6d 100644
--- a/libarchive/archive_read_support_format_zip.c
+++ b/libarchive/archive_read_support_format_zip.c
@@ -1797,6 +1797,23 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
"lzma data error (error %d)", (int) lz_ret);
return (ARCHIVE_FATAL);
+ /* This case is optional in lzma alone format. It can happen,
+ * but most of the files don't have it. (GitHub #1257) */
+ case LZMA_STREAM_END:
+ lzma_end(&zip->zipx_lzma_stream);
+ zip->zipx_lzma_valid = 0;
+ if((int64_t) zip->zipx_lzma_stream.total_in !=
+ zip->entry_bytes_remaining)
+ {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "lzma alone premature end of stream");
+ return (ARCHIVE_FATAL);
+ }
+
+ zip->end_of_entry = 1;
+ break;
+
case LZMA_OK:
break;
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
index 979a418b6779..399299ea631f 100644
--- a/libarchive/archive_string.c
+++ b/libarchive/archive_string.c
@@ -75,6 +75,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t))
#endif
+#undef max
+#define max(a, b) ((a)>(b)?(a):(b))
+
struct archive_string_conv {
struct archive_string_conv *next;
char *from_charset;
@@ -591,7 +594,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
* No single byte will be more than one wide character,
* so this length estimate will always be big enough.
*/
- size_t wcs_length = len;
+ // size_t wcs_length = len;
size_t mbs_length = len;
const char *mbs = p;
wchar_t *wcs;
@@ -600,7 +603,11 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
memset(&shift_state, 0, sizeof(shift_state));
#endif
- if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
+ /*
+ * As we decided to have wcs_length == mbs_length == len
+ * we can use len here instead of wcs_length
+ */
+ if (NULL == archive_wstring_ensure(dest, dest->length + len + 1))
return (-1);
wcs = dest->s + dest->length;
/*
@@ -609,6 +616,12 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
* multi bytes.
*/
while (*mbs && mbs_length > 0) {
+ /*
+ * The buffer we allocated is always big enough.
+ * Keep this code path in a comment if we decide to choose
+ * smaller wcs_length in the future
+ */
+/*
if (wcs_length == 0) {
dest->length = wcs - dest->s;
dest->s[dest->length] = L'\0';
@@ -618,24 +631,20 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
return (-1);
wcs = dest->s + dest->length;
}
+*/
#if HAVE_MBRTOWC
- r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
+ r = mbrtowc(wcs, mbs, mbs_length, &shift_state);
#else
- r = mbtowc(wcs, mbs, wcs_length);
+ r = mbtowc(wcs, mbs, mbs_length);
#endif
if (r == (size_t)-1 || r == (size_t)-2) {
ret_val = -1;
- if (errno == EILSEQ) {
- ++mbs;
- --mbs_length;
- continue;
- } else
- break;
+ break;
}
if (r == 0 || r > mbs_length)
break;
wcs++;
- wcs_length--;
+ // wcs_length--;
mbs += r;
mbs_length -= r;
}
@@ -798,7 +807,8 @@ archive_string_append_from_wcs(struct archive_string *as,
as->s[as->length] = '\0';
/* Re-allocate buffer for MBS. */
if (archive_string_ensure(as,
- as->length + len * 2 + 1) == NULL)
+ as->length + max(len * 2,
+ (size_t)MB_CUR_MAX) + 1) == NULL)
return (-1);
p = as->s + as->length;
end = as->s + as->buffer_length - MB_CUR_MAX -1;
@@ -3440,7 +3450,8 @@ strncat_from_utf8_libarchive2(struct archive_string *as,
as->length = p - as->s;
/* Re-allocate buffer for MBS. */
if (archive_string_ensure(as,
- as->length + len * 2 + 1) == NULL)
+ as->length + max(len * 2,
+ (size_t)MB_CUR_MAX) + 1) == NULL)
return (-1);
p = as->s + as->length;
end = as->s + as->buffer_length - MB_CUR_MAX -1;
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
index e8daf530d260..e7a973ae41a7 100644
--- a/libarchive/archive_write.c
+++ b/libarchive/archive_write.c
@@ -212,6 +212,7 @@ __archive_write_allocate_filter(struct archive *_a)
f = calloc(1, sizeof(*f));
f->archive = _a;
+ f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
if (a->filter_first == NULL)
a->filter_first = f;
else
@@ -228,6 +229,9 @@ __archive_write_filter(struct archive_write_filter *f,
const void *buff, size_t length)
{
int r;
+ /* Never write to non-open filters */
+ if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN)
+ return(ARCHIVE_FATAL);
if (length == 0)
return(ARCHIVE_OK);
if (f->write == NULL)
@@ -240,27 +244,70 @@ __archive_write_filter(struct archive_write_filter *f,
}
/*
- * Open a filter.
+ * Recursive function for opening the filter chain
+ * Last filter is opened first
*/
-int
+static int
__archive_write_open_filter(struct archive_write_filter *f)
{
- if (f->open == NULL)
+ int ret;
+
+ ret = ARCHIVE_OK;
+ if (f->next_filter != NULL)
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW)
+ return (ARCHIVE_FATAL);
+ if (f->open == NULL) {
+ f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
return (ARCHIVE_OK);
- return (f->open)(f);
+ }
+ ret = (f->open)(f);
+ if (ret == ARCHIVE_OK)
+ f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
+ else
+ f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
+ return (ret);
}
/*
- * Close a filter.
+ * Open all filters
*/
-int
-__archive_write_close_filter(struct archive_write_filter *f)
+static int
+__archive_write_filters_open(struct archive_write *a)
{
- if (f->close != NULL)
- return (f->close)(f);
- if (f->next_filter != NULL)
- return (__archive_write_close_filter(f->next_filter));
- return (ARCHIVE_OK);
+ return (__archive_write_open_filter(a->filter_first));
+}
+
+/*
+ * Close all filtes
+ */
+static int
+__archive_write_filters_close(struct archive_write *a)
+{
+ struct archive_write_filter *f;
+ int ret, ret1;
+ ret = ARCHIVE_OK;
+ for (f = a->filter_first; f != NULL; f = f->next_filter) {
+ /* Do not close filters that are not open */
+ if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) {
+ if (f->close != NULL) {
+ ret1 = (f->close)(f);
+ if (ret1 < ret)
+ ret = ret1;
+ if (ret1 == ARCHIVE_OK) {
+ f->state =
+ ARCHIVE_WRITE_FILTER_STATE_CLOSED;
+ } else {
+ f->state =
+ ARCHIVE_WRITE_FILTER_STATE_FATAL;
+ }
+ } else
+ f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
+ }
+ }
+ return (ret);
}
int
@@ -440,7 +487,7 @@ archive_write_client_close(struct archive_write_filter *f)
free(state->buffer);
free(state);
/* Clear the close handler myself not to be called again. */
- f->close = NULL;
+ f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
a->client_data = NULL;
/* Clear passphrase. */
if (a->passphrase != NULL) {
@@ -477,9 +524,10 @@ archive_write_open(struct archive *_a, void *client_data,
client_filter->write = archive_write_client_write;
client_filter->close = archive_write_client_close;
- ret = __archive_write_open_filter(a->filter_first);
+ ret = __archive_write_filters_open(a);
if (ret < ARCHIVE_WARN) {
- r1 = __archive_write_close_filter(a->filter_first);
+ r1 = __archive_write_filters_close(a);
+ __archive_write_filters_free(_a);
return (r1 < ret ? r1 : ret);
}
@@ -521,7 +569,7 @@ _archive_write_close(struct archive *_a)
}
/* Finish the compression and close the stream. */
- r1 = __archive_write_close_filter(a->filter_first);
+ r1 = __archive_write_filters_close(a);
if (r1 < r)
r = r1;
diff --git a/libarchive/archive_write_add_filter_b64encode.c b/libarchive/archive_write_add_filter_b64encode.c
index b46b19a0c74d..87fdb73ecb09 100644
--- a/libarchive/archive_write_add_filter_b64encode.c
+++ b/libarchive/archive_write_add_filter_b64encode.c
@@ -149,11 +149,6 @@ archive_filter_b64encode_open(struct archive_write_filter *f)
{
struct private_b64encode *state = (struct private_b64encode *)f->data;
size_t bs = 65536, bpb;
- int ret;
-
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
@@ -266,7 +261,6 @@ static int
archive_filter_b64encode_close(struct archive_write_filter *f)
{
struct private_b64encode *state = (struct private_b64encode *)f->data;
- int ret, ret2;
/* Flush remaining bytes. */
if (state->hold_len != 0)
@@ -274,12 +268,8 @@ archive_filter_b64encode_close(struct archive_write_filter *f)
archive_string_sprintf(&state->encoded_buff, "====\n");
/* Write the last block */
archive_write_set_bytes_in_last_block(f->archive, 1);
- ret = __archive_write_filter(f->next_filter,
+ return __archive_write_filter(f->next_filter,
state->encoded_buff.s, archive_strlen(&state->encoded_buff));
- ret2 = __archive_write_close_filter(f->next_filter);
- if (ret > ret2)
- ret = ret2;
- return (ret);
}
static int
diff --git a/libarchive/archive_write_add_filter_bzip2.c b/libarchive/archive_write_add_filter_bzip2.c
index 68ed9579b027..7001e9c6b309 100644
--- a/libarchive/archive_write_add_filter_bzip2.c
+++ b/libarchive/archive_write_add_filter_bzip2.c
@@ -167,10 +167,6 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
struct private_data *data = (struct private_data *)f->data;
int ret;
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != 0)
- return (ret);
-
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -262,7 +258,7 @@ static int
archive_compressor_bzip2_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int ret, r1;
+ int ret;
/* Finish compression cycle. */
ret = drive_compressor(f, data, 1);
@@ -281,9 +277,7 @@ archive_compressor_bzip2_close(struct archive_write_filter *f)
"Failed to clean up compressor");
ret = ARCHIVE_FATAL;
}
-
- r1 = __archive_write_close_filter(f->next_filter);
- return (r1 < ret ? r1 : ret);
+ return ret;
}
static int
diff --git a/libarchive/archive_write_add_filter_compress.c b/libarchive/archive_write_add_filter_compress.c
index 26fcef4d42bc..d404fae7dba4 100644
--- a/libarchive/archive_write_add_filter_compress.c
+++ b/libarchive/archive_write_add_filter_compress.c
@@ -146,17 +146,12 @@ archive_write_add_filter_compress(struct archive *_a)
static int
archive_compressor_compress_open(struct archive_write_filter *f)
{
- int ret;
struct private_data *state;
size_t bs = 65536, bpb;
f->code = ARCHIVE_FILTER_COMPRESS;
f->name = "compress";
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
-
state = (struct private_data *)calloc(1, sizeof(*state));
if (state == NULL) {
archive_set_error(f->archive, ENOMEM,
@@ -426,30 +421,27 @@ static int
archive_compressor_compress_close(struct archive_write_filter *f)
{
struct private_data *state = (struct private_data *)f->data;
- int ret, ret2;
+ int ret;
ret = output_code(f, state->cur_code);
if (ret != ARCHIVE_OK)
- goto cleanup;
+ return ret;
ret = output_flush(f);
if (ret != ARCHIVE_OK)
- goto cleanup;
+ return ret;
/* Write the last block */
ret = __archive_write_filter(f->next_filter,
state->compressed, state->compressed_offset);
-cleanup:
- ret2 = __archive_write_close_filter(f->next_filter);
- if (ret > ret2)
- ret = ret2;
- free(state->compressed);
- free(state);
return (ret);
}
static int
archive_compressor_compress_free(struct archive_write_filter *f)
{
- (void)f; /* UNUSED */
+ struct private_data *state = (struct private_data *)f->data;
+
+ free(state->compressed);
+ free(state);
return (ARCHIVE_OK);
}
diff --git a/libarchive/archive_write_add_filter_gzip.c b/libarchive/archive_write_add_filter_gzip.c
index e4b3435e4206..8670d5ca7403 100644
--- a/libarchive/archive_write_add_filter_gzip.c
+++ b/libarchive/archive_write_add_filter_gzip.c
@@ -184,10 +184,6 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
struct private_data *data = (struct private_data *)f->data;
int ret;
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
-
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -307,7 +303,7 @@ archive_compressor_gzip_close(struct archive_write_filter *f)
{
unsigned char trailer[8];
struct private_data *data = (struct private_data *)f->data;
- int ret, r1;
+ int ret;
/* Finish compression cycle */
ret = drive_compressor(f, data, 1);
@@ -338,8 +334,7 @@ archive_compressor_gzip_close(struct archive_write_filter *f)
"Failed to clean up compressor");
ret = ARCHIVE_FATAL;
}
- r1 = __archive_write_close_filter(f->next_filter);
- return (r1 < ret ? r1 : ret);
+ return ret;
}
/*
diff --git a/libarchive/archive_write_add_filter_lz4.c b/libarchive/archive_write_add_filter_lz4.c
index 15fd494a4197..cf19fadd5633 100644
--- a/libarchive/archive_write_add_filter_lz4.c
+++ b/libarchive/archive_write_add_filter_lz4.c
@@ -223,16 +223,11 @@ static int
archive_filter_lz4_open(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int ret;
size_t required_size;
static size_t const bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024,
4 * 1024 * 1024 };
size_t pre_block_size;
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != 0)
- return (ret);
-
if (data->block_maximum_size < 4)
data->block_size = bkmap[0];
else
@@ -343,7 +338,7 @@ static int
archive_filter_lz4_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int ret, r1;
+ int ret;
/* Finish compression cycle. */
ret = (int)lz4_write_one_block(f, NULL, 0);
@@ -366,9 +361,7 @@ archive_filter_lz4_close(struct archive_write_filter *f)
ret = __archive_write_filter(f->next_filter,
data->out_buffer, data->out - data->out_buffer);
}
-
- r1 = __archive_write_close_filter(f->next_filter);
- return (r1 < ret ? r1 : ret);
+ return ret;
}
static int
diff --git a/libarchive/archive_write_add_filter_lzop.c b/libarchive/archive_write_add_filter_lzop.c
index ad705c4a0687..3bd9062e4d32 100644
--- a/libarchive/archive_write_add_filter_lzop.c
+++ b/libarchive/archive_write_add_filter_lzop.c
@@ -228,11 +228,6 @@ static int
archive_write_lzop_open(struct archive_write_filter *f)
{
struct write_lzop *data = (struct write_lzop *)f->data;
- int ret;
-
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
switch (data->compression_level) {
case 1:
@@ -439,10 +434,7 @@ archive_write_lzop_close(struct archive_write_filter *f)
}
/* Write a zero uncompressed size as the end mark of the series of
* compressed block. */
- r = __archive_write_filter(f->next_filter, &endmark, sizeof(endmark));
- if (r != ARCHIVE_OK)
- return (r);
- return (__archive_write_close_filter(f->next_filter));
+ return __archive_write_filter(f->next_filter, &endmark, sizeof(endmark));
}
#else
diff --git a/libarchive/archive_write_add_filter_program.c b/libarchive/archive_write_add_filter_program.c
index 660f693f29d0..a4bc1d90eda8 100644
--- a/libarchive/archive_write_add_filter_program.c
+++ b/libarchive/archive_write_add_filter_program.c
@@ -212,11 +212,6 @@ __archive_write_program_open(struct archive_write_filter *f,
struct archive_write_program_data *data, const char *cmd)
{
pid_t child;
- int ret;
-
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
if (data->child_buf == NULL) {
data->child_buf_len = 65536;
@@ -353,11 +348,11 @@ int
__archive_write_program_close(struct archive_write_filter *f,
struct archive_write_program_data *data)
{
- int ret, r1, status;
+ int ret, status;
ssize_t bytes_read;
if (data->child == 0)
- return __archive_write_close_filter(f->next_filter);
+ return ARCHIVE_OK;
ret = 0;
close(data->child_stdin);
@@ -409,7 +404,6 @@ cleanup:
"Error closing program: %s", data->program_name);
ret = ARCHIVE_FATAL;
}
- r1 = __archive_write_close_filter(f->next_filter);
- return (r1 < ret ? r1 : ret);
+ return ret;
}
diff --git a/libarchive/archive_write_add_filter_uuencode.c b/libarchive/archive_write_add_filter_uuencode.c
index 23d9c150d17f..1ad458921928 100644
--- a/libarchive/archive_write_add_filter_uuencode.c
+++ b/libarchive/archive_write_add_filter_uuencode.c
@@ -138,11 +138,6 @@ archive_filter_uuencode_open(struct archive_write_filter *f)
{
struct private_uuencode *state = (struct private_uuencode *)f->data;
size_t bs = 65536, bpb;
- int ret;
-
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
@@ -257,7 +252,6 @@ static int
archive_filter_uuencode_close(struct archive_write_filter *f)
{
struct private_uuencode *state = (struct private_uuencode *)f->data;
- int ret, ret2;
/* Flush remaining bytes. */
if (state->hold_len != 0)
@@ -265,12 +259,8 @@ archive_filter_uuencode_close(struct archive_write_filter *f)
archive_string_sprintf(&state->encoded_buff, "`\nend\n");
/* Write the last block */
archive_write_set_bytes_in_last_block(f->archive, 1);
- ret = __archive_write_filter(f->next_filter,
+ return __archive_write_filter(f->next_filter,
state->encoded_buff.s, archive_strlen(&state->encoded_buff));
- ret2 = __archive_write_close_filter(f->next_filter);
- if (ret > ret2)
- ret = ret2;
- return (ret);
}
static int
diff --git a/libarchive/archive_write_add_filter_xz.c b/libarchive/archive_write_add_filter_xz.c
index 0f7c8cfc31a5..8c1ebb805b10 100644
--- a/libarchive/archive_write_add_filter_xz.c
+++ b/libarchive/archive_write_add_filter_xz.c
@@ -309,10 +309,6 @@ archive_compressor_xz_open(struct archive_write_filter *f)
struct private_data *data = f->data;
int ret;
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
-
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -448,7 +444,7 @@ static int
archive_compressor_xz_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int ret, r1;
+ int ret;
ret = drive_compressor(f, data, 1);
if (ret == ARCHIVE_OK) {
@@ -466,8 +462,7 @@ archive_compressor_xz_close(struct archive_write_filter *f)
}
}
lzma_end(&(data->stream));
- r1 = __archive_write_close_filter(f->next_filter);
- return (r1 < ret ? r1 : ret);
+ return ret;
}
static int
diff --git a/libarchive/archive_write_add_filter_zstd.c b/libarchive/archive_write_add_filter_zstd.c
index 671fc6affbaa..4c91551ed3e1 100644
--- a/libarchive/archive_write_add_filter_zstd.c
+++ b/libarchive/archive_write_add_filter_zstd.c
@@ -172,11 +172,6 @@ static int
archive_compressor_zstd_open(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
if (data->out.dst == NULL) {
size_t bs = ZSTD_CStreamOutSize(), bpb;
@@ -238,14 +233,9 @@ static int
archive_compressor_zstd_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int r1, r2;
/* Finish zstd frame */
- r1 = drive_compressor(f, data, 1, NULL, 0);
-
- r2 = __archive_write_close_filter(f->next_filter);
-
- return r1 < r2 ? r1 : r2;
+ return drive_compressor(f, data, 1, NULL, 0);
}
/*
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
index 6ae8a6a89bbf..df4b02f5efa1 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -419,7 +419,7 @@ la_opendirat(int fd, const char *path) {
| O_PATH
#elif defined(O_SEARCH)
| O_SEARCH
-#elif defined(O_EXEC)
+#elif defined(__FreeBSD__) && defined(O_EXEC)
| O_EXEC
#else
| O_RDONLY
diff --git a/libarchive/archive_write_private.h b/libarchive/archive_write_private.h
index 0dfd1b1bca91..1c182f136801 100644
--- a/libarchive/archive_write_private.h
+++ b/libarchive/archive_write_private.h
@@ -38,6 +38,11 @@
#include "archive_string.h"
#include "archive_private.h"
+#define ARCHIVE_WRITE_FILTER_STATE_NEW 1U
+#define ARCHIVE_WRITE_FILTER_STATE_OPEN 2U
+#define ARCHIVE_WRITE_FILTER_STATE_CLOSED 4U
+#define ARCHIVE_WRITE_FILTER_STATE_FATAL 0x8000U
+
struct archive_write;
struct archive_write_filter {
@@ -55,6 +60,7 @@ struct archive_write_filter {
int code;
int bytes_per_block;
int bytes_in_last_block;
+ int state;
};
#if ARCHIVE_VERSION < 4000000
@@ -66,8 +72,6 @@ struct archive_write_filter *__archive_write_allocate_filter(struct archive *);
int __archive_write_output(struct archive_write *, const void *, size_t);
int __archive_write_nulls(struct archive_write *, size_t);
int __archive_write_filter(struct archive_write_filter *, const void *, size_t);
-int __archive_write_open_filter(struct archive_write_filter *);
-int __archive_write_close_filter(struct archive_write_filter *);
struct archive_write {
struct archive archive;
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
index cf2a1f959e34..7c5e63bb3a23 100644
--- a/libarchive/archive_write_set_format_pax.c
+++ b/libarchive/archive_write_set_format_pax.c
@@ -199,6 +199,28 @@ archive_write_pax_options(struct archive_write *a, const char *key,
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"pax: invalid charset name");
return (ret);
+ } else if (strcmp(key, "xattrheader") == 0) {
+ if (val == NULL || val[0] == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: xattrheader requires a value");
+ } else if (strcmp(val, "ALL") == 0 ||
+ strcmp(val, "all") == 0) {
+ pax->flags |= WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(val, "SCHILY") == 0 ||
+ strcmp(val, "schily") == 0) {
+ pax->flags |= WRITE_SCHILY_XATTR;
+ pax->flags &= ~WRITE_LIBARCHIVE_XATTR;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(val, "LIBARCHIVE") == 0 ||
+ strcmp(val, "libarchive") == 0) {
+ pax->flags |= WRITE_LIBARCHIVE_XATTR;
+ pax->flags &= ~WRITE_SCHILY_XATTR;
+ ret = ARCHIVE_OK;
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: invalid xattr header name");
+ return (ret);
}
/* Note: The "warn" return is just to inform the options
diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c
index 7fcd1a07b3f5..f28a8c3a341f 100644
--- a/libarchive/archive_write_set_format_zip.c
+++ b/libarchive/archive_write_set_format_zip.c
@@ -1402,18 +1402,17 @@ path_length(struct archive_entry *entry)
{
mode_t type;
const char *path;
+ size_t len;
type = archive_entry_filetype(entry);
path = archive_entry_pathname(entry);
if (path == NULL)
return (0);
- if (type == AE_IFDIR &&
- (path[0] == '\0' || path[strlen(path) - 1] != '/')) {
- return strlen(path) + 1;
- } else {
- return strlen(path);
- }
+ len = strlen(path);
+ if (type == AE_IFDIR && (path[0] == '\0' || path[len - 1] != '/'))
+ ++len; /* Space for the trailing / */
+ return len;
}
static int
@@ -1461,10 +1460,8 @@ copy_path(struct archive_entry *entry, unsigned char *p)
memcpy(p, path, pathlen);
/* Folders are recognized by a trailing slash. */
- if ((type == AE_IFDIR) & (path[pathlen - 1] != '/')) {
+ if ((type == AE_IFDIR) && (path[pathlen - 1] != '/'))
p[pathlen] = '/';
- p[pathlen + 1] = '\0';
- }
}
diff --git a/libarchive/archive_write_set_options.3 b/libarchive/archive_write_set_options.3
index a9f70a664092..09eb95ea5aa9 100644
--- a/libarchive/archive_write_set_options.3
+++ b/libarchive/archive_write_set_options.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 27, 2019
+.Dd December 3, 2019
.Dt ARCHIVE_WRITE_OPTIONS 3
.Os
.Sh NAME
@@ -404,6 +404,32 @@ Specifies a filename that should not be compressed when using
This option can be provided multiple times to suppress compression
on many files.
.El
+.It Format pax
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+This sets the character set used for filenames, uname and gname.
+The value is one of
+.Dq BINARY
+or
+.Dq UTF-8 .
+With
+.Dq BINARY
+there is no character conversion, with
+.Dq UTF-8
+names are converted to UTF-8.
+.It Cm xattrheader
+When storing extended attributes, this option configures which
+headers should be written. The value is one of
+.Dq all ,
+.Dq LIBARCHIVE ,
+or
+.Dq SCHILY .
+By default, both
+.Dq LIBARCHIVE.xattr
+and
+.Dq SCHILY.xattr
+headers are written.
+.El
.It Format 7zip
.Bl -tag -compact -width indent
.It Cm compression
diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
index 2f451d2a0649..df34d3e3200b 100644
--- a/libarchive/test/CMakeLists.txt
+++ b/libarchive/test/CMakeLists.txt
@@ -82,6 +82,7 @@ IF(ENABLE_TEST)
test_open_file.c
test_open_filename.c
test_pax_filename_encoding.c
+ test_pax_xattr_header.c
test_read_data_large.c
test_read_disk.c
test_read_disk_directory_traversals.c
@@ -101,6 +102,7 @@ IF(ENABLE_TEST)
test_read_format_7zip_encryption_header.c
test_read_format_7zip_encryption_partially.c
test_read_format_7zip_malformed.c
+ test_read_format_7zip_packinfo_digests.c
test_read_format_ar.c
test_read_format_cab.c
test_read_format_cab_filename.c
@@ -141,6 +143,7 @@ IF(ENABLE_TEST)
test_read_format_lha.c
test_read_format_lha_bugfix_0.c
test_read_format_lha_filename.c
+ test_read_format_lha_filename_utf16.c
test_read_format_mtree.c
test_read_format_mtree_crash747.c
test_read_format_pax_bz2.c
diff --git a/libarchive/test/test_open_failure.c b/libarchive/test/test_open_failure.c
index 845486cf9216..5316a872b6a8 100644
--- a/libarchive/test/test_open_failure.c
+++ b/libarchive/test/test_open_failure.c
@@ -160,11 +160,11 @@ DEFINE_TEST(test_open_failure)
archive_write_open(a, &private, my_open, my_write, my_close));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
memset(&private, 0, sizeof(private));
private.magic = MAGIC;
@@ -177,11 +177,11 @@ DEFINE_TEST(test_open_failure)
archive_write_open(a, &private, my_open, my_write, my_close));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
memset(&private, 0, sizeof(private));
private.magic = MAGIC;
@@ -193,11 +193,11 @@ DEFINE_TEST(test_open_failure)
archive_write_open(a, &private, my_open, my_write, my_close));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
memset(&private, 0, sizeof(private));
private.magic = MAGIC;
@@ -209,10 +209,10 @@ DEFINE_TEST(test_open_failure)
archive_write_open(a, &private, my_open, my_write, my_close));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- assertEqualInt(1, private.close_called);
+ assertEqualInt(0, private.close_called);
}
diff --git a/libarchive/test/test_open_fd.c b/libarchive/test/test_open_fd.c
index ff5fab1ad45b..7da8b5ebcb56 100644
--- a/libarchive/test/test_open_fd.c
+++ b/libarchive/test/test_open_fd.c
@@ -42,6 +42,7 @@ DEFINE_TEST(test_open_fd)
struct archive_entry *ae;
struct archive *a;
int fd;
+ const char *skip_open_fd_err_test;
#if defined(__BORLANDC__)
fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY);
@@ -116,16 +117,18 @@ DEFINE_TEST(test_open_fd)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
close(fd);
-
- /*
- * Verify some of the error handling.
- */
- assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
- /* FD 100 shouldn't be open. */
- assertEqualIntA(a, ARCHIVE_FATAL,
- archive_read_open_fd(a, 100, 512));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skip_open_fd_err_test = getenv("SKIP_OPEN_FD_ERR_TEST");
+ if(skip_open_fd_err_test == NULL) {
+ /*
+ * Verify some of the error handling.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ /* FD 100 shouldn't be open. */
+ assertEqualIntA(a, ARCHIVE_FATAL,
+ archive_read_open_fd(a, 100, 512));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ }
}
diff --git a/libarchive/test/test_pax_xattr_header.c b/libarchive/test/test_pax_xattr_header.c
new file mode 100644
index 000000000000..d0394aa09eda
--- /dev/null
+++ b/libarchive/test/test_pax_xattr_header.c
@@ -0,0 +1,130 @@
+/*-
+ * 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$");
+
+static struct archive_entry*
+create_archive_entry(void) {
+ struct archive_entry *ae;
+
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_nlink(ae, 2);
+ archive_entry_set_size(ae, 8);
+ archive_entry_xattr_add_entry(ae, "user.data1", "ABCDEFG", 7);
+ archive_entry_xattr_add_entry(ae, "user.data2", "XYZ", 3);
+
+ return (ae);
+}
+
+DEFINE_TEST(test_pax_xattr_header)
+{
+ static const char *reffiles[] = {
+ "test_pax_xattr_header_all.tar",
+ "test_pax_xattr_header_libarchive.tar",
+ "test_pax_xattr_header_schily.tar",
+ NULL
+ };
+ struct archive *a;
+ struct archive_entry *ae;
+
+ extract_reference_files(reffiles);
+
+ /* First archive, no options */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, 0, archive_write_set_format_pax(a));
+ assertEqualIntA(a, 0, archive_write_add_filter_none(a));
+ assertEqualInt(0,
+ archive_write_open_filename(a, "test1.tar"));
+ ae = create_archive_entry();
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ assertEqualFile("test1.tar","test_pax_xattr_header_all.tar");
+
+ /* Second archive, xattrheader=SCHILY */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, 0, archive_write_set_format_pax(a));
+ assertEqualIntA(a, 0, archive_write_add_filter_none(a));
+ assertEqualIntA(a, 0, archive_write_set_options(a,
+ "xattrheader=SCHILY"));
+ assertEqualInt(0,
+ archive_write_open_filename(a, "test2.tar"));
+
+ ae = create_archive_entry();
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ assertEqualFile("test2.tar","test_pax_xattr_header_schily.tar");
+
+ /* Third archive, xattrheader=LIBARCHIVE */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, 0, archive_write_set_format_pax(a));
+ assertEqualIntA(a, 0, archive_write_add_filter_none(a));
+ assertEqualIntA(a, 0, archive_write_set_options(a,
+ "xattrheader=LIBARCHIVE"));
+ assertEqualInt(0,
+ archive_write_open_filename(a, "test3.tar"));
+
+ ae = create_archive_entry();
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ assertEqualFile("test3.tar","test_pax_xattr_header_libarchive.tar");
+
+ /* Fourth archive, xattrheader=ALL */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, 0, archive_write_set_format_pax(a));
+ assertEqualIntA(a, 0, archive_write_add_filter_none(a));
+ assertEqualIntA(a, 0, archive_write_set_options(a, "xattrheader=ALL"));
+ assertEqualInt(0,
+ archive_write_open_filename(a, "test4.tar"));
+
+ ae = create_archive_entry();
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ assertEqualFile("test4.tar","test_pax_xattr_header_all.tar");
+}
diff --git a/libarchive/test/test_pax_xattr_header_all.tar.uu b/libarchive/test/test_pax_xattr_header_all.tar.uu
new file mode 100644
index 000000000000..086428e7144b
--- /dev/null
+++ b/libarchive/test/test_pax_xattr_header_all.tar.uu
@@ -0,0 +1,72 @@
+begin 644 test_pax_xattr_header_all.tar
+M4&%X2&5A9&5R+V9I;&4`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````#`P,#<U-2``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,S$T
+M(#`P,#`P,#`P,#`U(#`Q,C`P-@`@>```````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````!U<W1A<@`P,```````
+M````````````````````````````````````````````````````````````
+M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````R,"!C=&EM93TT+C`P,#`P,#`T"C(P(&%T:6UE
+M/3(N,#`P,#`P,#(*,C`@;71I;64]-2XP,#`P,#`P-0HS-B!,24)!4D-(259%
+M+GAA='1R+G5S97(N9&%T83(]5T9L80HS,2!30TA)3%DN>&%T='(N=7-E<BYD
+M871A,CU865H*-#(@3$E"05)#2$E612YX871T<BYU<V5R+F1A=&$Q/5%52D12
+M159'4G<*,S4@4T-(24Q9+GAA='1R+G5S97(N9&%T83$]04)#1$5&1PH`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````&9I;&4`````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````````````P
+M,#`W-34@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`Q,"`P,#`P,#`P,#`P
+M-2`P,3`P,C8`(#``````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````=7-T87(`,#``````````````````````
+M````````````````````````````````````````````````````````````
+M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````,3(S-#4V-S@`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/libarchive/test/test_pax_xattr_header_libarchive.tar.uu b/libarchive/test/test_pax_xattr_header_libarchive.tar.uu
new file mode 100644
index 000000000000..1d15980365c5
--- /dev/null
+++ b/libarchive/test/test_pax_xattr_header_libarchive.tar.uu
@@ -0,0 +1,72 @@
+begin 644 test_pax_xattr_header_libarchive.tar
+M4&%X2&5A9&5R+V9I;&4`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````#`P,#<U-2``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,C$R
+M(#`P,#`P,#`P,#`U(#`Q,C`P,P`@>```````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````!U<W1A<@`P,```````
+M````````````````````````````````````````````````````````````
+M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````R,"!C=&EM93TT+C`P,#`P,#`T"C(P(&%T:6UE
+M/3(N,#`P,#`P,#(*,C`@;71I;64]-2XP,#`P,#`P-0HS-B!,24)!4D-(259%
+M+GAA='1R+G5S97(N9&%T83(]5T9L80HT,B!,24)!4D-(259%+GAA='1R+G5S
+M97(N9&%T83$]455*1%)%5D=2=PH`````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````&9I;&4`````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````````````P
+M,#`W-34@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`Q,"`P,#`P,#`P,#`P
+M-2`P,3`P,C8`(#``````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````=7-T87(`,#``````````````````````
+M````````````````````````````````````````````````````````````
+M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````,3(S-#4V-S@`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/libarchive/test/test_pax_xattr_header_schily.tar.uu b/libarchive/test/test_pax_xattr_header_schily.tar.uu
new file mode 100644
index 000000000000..aafea17c54dd
--- /dev/null
+++ b/libarchive/test/test_pax_xattr_header_schily.tar.uu
@@ -0,0 +1,72 @@
+begin 644 test_pax_xattr_header_schily.tar
+M4&%X2&5A9&5R+V9I;&4`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````#`P,#<U-2``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,3<V
+M(#`P,#`P,#`P,#`U(#`Q,C`Q-``@>```````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````!U<W1A<@`P,```````
+M````````````````````````````````````````````````````````````
+M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````R,"!C=&EM93TT+C`P,#`P,#`T"C(P(&%T:6UE
+M/3(N,#`P,#`P,#(*,C`@;71I;64]-2XP,#`P,#`P-0HS,2!30TA)3%DN>&%T
+M='(N=7-E<BYD871A,CU865H*,S4@4T-(24Q9+GAA='1R+G5S97(N9&%T83$]
+M04)#1$5&1PH`````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````&9I;&4`````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````````````P
+M,#`W-34@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`Q,"`P,#`P,#`P,#`P
+M-2`P,3`P,C8`(#``````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````=7-T87(`,#``````````````````````
+M````````````````````````````````````````````````````````````
+M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````,3(S-#4V-S@`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/libarchive/test/test_read_disk_directory_traversals.c b/libarchive/test/test_read_disk_directory_traversals.c
index 7dd19157d4d2..bbfe91ab8e5e 100644
--- a/libarchive/test/test_read_disk_directory_traversals.c
+++ b/libarchive/test/test_read_disk_directory_traversals.c
@@ -1775,7 +1775,8 @@ test_parent(void)
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)
+#if defined(O_PATH) || defined(O_SEARCH) || \
+ (defined(__FreeBSD__) && defined(O_EXEC))
assertEqualIntA(a, ARCHIVE_OK, r);
#endif
/* Close the disk object. */
diff --git a/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu b/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu
new file mode 100644
index 000000000000..4c216170a8e2
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu
@@ -0,0 +1,7 @@
+begin 644 test_read_format_7zip_packinfo_digests.7z
+M-WJ\KR<<``*^Y_3?$`````````!E`````````&/C(9T!``-A86$*``$``V)B
+M8@H``00&``()"`@*`5\J+KLX07WL``<+`@`!(2$!%@$A(0$6#`0$"@&57?AW
+MX1\F3``(```%`A$9`&$`+@!T`'@`=````&(`+@!T`'@`=````!02`0"`FYCT
+.W+;5`8";F/3<MM4!````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_packinfo_digests.c b/libarchive/test/test_read_format_7zip_packinfo_digests.c
new file mode 100644
index 000000000000..94cd1ad32e42
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_packinfo_digests.c
@@ -0,0 +1,77 @@
+/*-
+ * 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");
+
+/* Read archive with digests in PackInfo */
+DEFINE_TEST(test_read_format_7zip_packinfo_digests)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[4];
+ const char *refname = "test_read_format_7zip_packinfo_digests.7z";
+
+ extract_reference_file(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,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
+ assertEqualString("a.txt", archive_entry_pathname(ae));
+ assertEqualInt(1576808819, archive_entry_mtime(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+ assertEqualInt(4, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaa\n", 4);
+
+ /* Verify regular file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
+ assertEqualString("b.txt", archive_entry_pathname(ae));
+ assertEqualInt(1576808819, archive_entry_mtime(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+ assertEqualInt(4, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "bbb\n", 4);
+
+ assertEqualInt(2, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
diff --git a/libarchive/test/test_read_format_lha_filename_utf16.c b/libarchive/test/test_read_format_lha_filename_utf16.c
new file mode 100644
index 000000000000..7ab13e43bdd3
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_filename_utf16.c
@@ -0,0 +1,143 @@
+/*-
+ * 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");
+
+#include <locale.h>
+
+static void
+test_read_format_lha_filename_UTF16_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read LHA filename in en_US.UTF-8.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+ /*
+ * Create a read object only for a test that platform support
+ * a character-set conversion because we can read a character-set
+ * of filenames from the header of an lha archive file and so we
+ * want to test that it works well.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skipping("This system cannot convert character-set"
+ " from CP932 to UTF-8.");
+ return;
+ }
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-16")) {
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skipping("This system cannot convert character-set"
+ " from UTF-16 to UTF-8.");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Note that usual Japanese filenames are tested in other cases */
+#if defined(__APPLE__)
+ /* NFD normalization */
+ /* U:O:A:u:o:a: */
+ #define UMLAUT_DIRNAME "\x55\xcc\x88\x4f\xcc\x88\x41\xcc\x88\x75\xcc\x88\x6f"\
+ "\xcc\x88\x61\xcc\x88/"
+ /* a:o:u:A:O:U:.txt */
+ #define UMLAUT_FNAME "\x61\xcc\x88\x6f\xcc\x88\x75\xcc\x88\x41\xcc\x88"\
+ "\x4f\xcc\x88\x55\xcc\x88.txt"
+#else
+ /* NFC normalization */
+ /* U:O:A:u:o:a: */
+ #define UMLAUT_DIRNAME "\xc3\x9c\xc3\x96\xc3\x84\xc3\xbc\xc3\xb6\xc3\xa4/"
+ /* a:o:u:A:O:U:.txt */
+ #define UMLAUT_FNAME "\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c.txt"
+#endif
+
+/* "Test" in Japanese Katakana */
+#define KATAKANA_FNAME "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
+#define KATAKANA_DIRNAME "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88/"
+
+ /* Verify regular file. U:O:A:u:o:a:/a:o:u:A:O:U:.txt */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(UMLAUT_DIRNAME UMLAUT_FNAME, archive_entry_pathname(ae));
+ assertEqualInt(12, archive_entry_size(ae));
+
+ /* Verify directory. U:O:A:u:o:a:/ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(UMLAUT_DIRNAME, archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify regular file. U:O:A:u:o:a:/("Test" in Japanese).txt */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(UMLAUT_DIRNAME KATAKANA_FNAME,
+ archive_entry_pathname(ae));
+ assertEqualInt(25, archive_entry_size(ae));
+
+ /* Verify regular file. ("Test" in Japanese)/a:o:u:A:O:U:.txt */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(KATAKANA_DIRNAME UMLAUT_FNAME,
+ archive_entry_pathname(ae));
+ assertEqualInt(12, archive_entry_size(ae));
+
+ /* Verify directory. ("Test" in Japanese)/ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(KATAKANA_DIRNAME, archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify regular file. a:o:u:A:O:U:.txt */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(UMLAUT_FNAME, archive_entry_pathname(ae));
+ assertEqualInt(12, archive_entry_size(ae));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_lha_filename_UTF16)
+{
+ /* A sample file was created with Unlha32.dll. */
+ const char *refname = "test_read_format_lha_filename_utf16.lzh";
+ extract_reference_file(refname);
+
+ test_read_format_lha_filename_UTF16_UTF8(refname);
+}
+
diff --git a/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu b/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu
new file mode 100644
index 000000000000..ca5da7a64e59
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu
@@ -0,0 +1,19 @@
+begin 644 test_read_format_lha_filename_utf16.lzh
+M@0`M;&@P+0P````,````L/5872`"IW%-!P!&I`,```T``5]?7U]?7RYT>'0*
+M``)?7U]?7U__%P!$Y`#V`/P`Q`#6`-P`+@!T`'@`=``1`$7<`-8`Q`#\`/8`
+MY`#__QL`078S<F.15=4!]0V8@I%5U0'U#9B"D575`08```\:!P``PZ3#ML.\
+MPX3#EL.<90`M;&AD+0``````````PX"D72`"``!-!P!&I`,```,``0H``E]?
+M7U]?7_\%`$`0`!$`1=P`U@#$`/P`]@#D`/__&P!!FDHB>9B"U0$H^DQ_F(+5
+M`2CZ3'^8@M4!!@``GW<'``!J`"UL:#`M&0```!D```!V)L1=(`*CNTT'`$:D
+M`P``#0`!@V6#6(-G+G1X=`H``E]?7U]?7_\1`$7<`-8`Q`#\`/8`Y`#__QL`
+M00IF#4J@E-4!L"5C?'65U0&P)6-\=975`08``$%^!P``5&5S="!I;B!*87!A
+M;F5S92!+871A:V%N87L`+6QH,"T,````#````+#U6%T@`J=Q30<`1J0#```-
+M``%?7U]?7U\N='AT"@`"@V6#6(-G_Q<`1.0`]@#\`,0`U@#<`"X`=`!X`'0`
+M"P!%QC"Y,,@P__\;`$'D5O!-H)35`?4-F(*15=4!Y%;P3:"4U0$&``"A+0<`
+M`,.DP[;#O,.$PY;#G%0`+6QH9"T``````````-3`PET@`@``30<`1J0#```#
+M``$*``*#98-8@V?_!0!`$``;`$%%!\Y.H)35`3/_]%&@E-4!,__T4:"4U0$&
+M``!>;@<``&8`+6QH,"T,````#````+#U6%T@`J=Q30<`1J0#```-``%?7U]?
+M7U\N='AT%P!$Y`#V`/P`Q`#6`-P`+@!T`'@`=``;`$'D5O!-H)35`?4-F(*1
+@5=4!Y%;P3:"4U0$&``"M>`<``,.DP[;#O,.$PY;#G`#D
+`
+end
diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c
index b4ef29e464bf..bb94d4e34e25 100644
--- a/libarchive/test/test_read_format_rar5.c
+++ b/libarchive/test/test_read_format_rar5.c
@@ -969,13 +969,12 @@ DEFINE_TEST(test_read_format_rar5_readtables_overflow)
PROLOGUE("test_read_format_rar5_readtables_overflow.rar");
- assertA(0 == archive_read_next_header(a, &ae));
/* This archive is invalid. However, processing it shouldn't cause any
* buffer overflow errors during reading rar5 tables. */
- assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
- /* This test only cares about not returning success here. */
- assertA(ARCHIVE_OK != archive_read_next_header(a, &ae));
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
EPILOGUE();
}
@@ -986,13 +985,12 @@ DEFINE_TEST(test_read_format_rar5_leftshift1)
PROLOGUE("test_read_format_rar5_leftshift1.rar");
- assertA(0 == archive_read_next_header(a, &ae));
/* This archive is invalid. However, processing it shouldn't cause any
* errors related to undefined operations when using -fsanitize. */
- assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
- /* This test only cares about not returning success here. */
- assertA(ARCHIVE_OK != archive_read_next_header(a, &ae));
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
EPILOGUE();
}
@@ -1003,14 +1001,12 @@ DEFINE_TEST(test_read_format_rar5_leftshift2)
PROLOGUE("test_read_format_rar5_leftshift2.rar");
- assertA(0 == archive_read_next_header(a, &ae));
-
/* This archive is invalid. However, processing it shouldn't cause any
* errors related to undefined operations when using -fsanitize. */
- assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
- /* This test only cares about not returning success here. */
- assertA(ARCHIVE_OK != archive_read_next_header(a, &ae));
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
EPILOGUE();
}
@@ -1021,14 +1017,12 @@ DEFINE_TEST(test_read_format_rar5_truncated_huff)
PROLOGUE("test_read_format_rar5_truncated_huff.rar");
- assertA(0 == archive_read_next_header(a, &ae));
-
/* This archive is invalid. However, processing it shouldn't cause any
* errors related to undefined operations when using -fsanitize. */
- assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
- /* This test only cares about not returning success here. */
- assertA(ARCHIVE_OK != archive_read_next_header(a, &ae));
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
EPILOGUE();
}
@@ -1058,14 +1052,12 @@ DEFINE_TEST(test_read_format_rar5_distance_overflow)
PROLOGUE("test_read_format_rar5_distance_overflow.rar");
- assertA(0 == archive_read_next_header(a, &ae));
-
/* This archive is invalid. However, processing it shouldn't cause any
* errors related to variable overflows when using -fsanitize. */
- assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
- /* This test only cares about not returning success here. */
- assertA(ARCHIVE_OK != archive_read_next_header(a, &ae));
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
EPILOGUE();
}
@@ -1076,14 +1068,12 @@ DEFINE_TEST(test_read_format_rar5_nonempty_dir_stream)
PROLOGUE("test_read_format_rar5_nonempty_dir_stream.rar");
- assertA(0 == archive_read_next_header(a, &ae));
-
/* This archive is invalid. However, processing it shouldn't cause any
* errors related to buffer overflows when using -fsanitize. */
- assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
- /* This test only cares about not returning success here. */
- assertA(ARCHIVE_OK != archive_read_next_header(a, &ae));
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
EPILOGUE();
}
@@ -1205,13 +1195,13 @@ DEFINE_TEST(test_read_format_rar5_different_window_size)
* errors during processing. */
(void) archive_read_next_header(a, &ae);
- while(0 != archive_read_data(a, buf, sizeof(buf))) {}
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
(void) archive_read_next_header(a, &ae);
- while(0 != archive_read_data(a, buf, sizeof(buf))) {}
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
(void) archive_read_next_header(a, &ae);
- while(0 != archive_read_data(a, buf, sizeof(buf))) {}
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
EPILOGUE();
}
@@ -1226,7 +1216,43 @@ DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary)
* errors during processing. */
(void) archive_read_next_header(a, &ae);
- while(0 != archive_read_data(a, buf, sizeof(buf))) {}
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
+
+ EPILOGUE();
+}
+
+DEFINE_TEST(test_read_format_rar5_different_solid_window_size)
+{
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_different_solid_window_size.rar");
+
+ /* Return codes of those calls are ignored, because this sample file
+ * is invalid. However, the unpacker shouldn't produce any SIGSEGV
+ * errors during processing. */
+
+ (void) archive_read_next_header(a, &ae);
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
+
+ (void) archive_read_next_header(a, &ae);
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
+
+ (void) archive_read_next_header(a, &ae);
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
+
+ EPILOGUE();
+}
+
+DEFINE_TEST(test_read_format_rar5_different_winsize_on_merge)
+{
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_different_winsize_on_merge.rar");
+
+ /* Return codes of those calls are ignored, because this sample file
+ * is invalid. However, the unpacker shouldn't produce any SIGSEGV
+ * errors during processing. */
+
+ (void) archive_read_next_header(a, &ae);
+ while(0 < archive_read_data(a, buf, sizeof(buf))) {}
EPILOGUE();
}
diff --git a/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu b/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu
new file mode 100644
index 000000000000..b131e6f00c8e
--- /dev/null
+++ b/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu
@@ -0,0 +1,73 @@
+begin 644 test_read_format_rar5_different_solid_window_size.rar
+M4F%R(1H'`0"-[P+2``'#M#P\7P$'`0"-[P+2``7#````1H68F`#___\`````
+M```0^OKZ^OJ%F)B8F)A)`)@"F-(%87)4`,.T/#Q?`0<!`(WO`M(`4F%R(1H'
+M`0"-[P+2``+'#PD`<@$A!QH:(](M``$:(](M``(:!P$`C>\"T@`"QP\`"7(A
+MFC$!$AHCTBT``B@A4F%2(1H'&.D````!`(WO`M(`!<-%````1A?'#P`)<B$:
+M!P$:T@7"F!=A_________P$$____,/__F!=A)F%R*%)8(W=T4F%R(1H'`0"-
+M[P+2``+'#PD`<@$A!QH:(](M``$:(](M``(:!P$`C>\"T@`"QP\`"7(AFC$!
+M$AHCTBT``B@A4F%2(1H'&.D````!`(WO`M(`!<-%````1A?'#P`)<B$:!P$:
+MT@7"F!=A_________P$$____,/__F!=A)B8(<@IE`.\*"7(`````````````
+M=O____________________\`!<-%````1A?'#_\P__\$(DT89%`(`0(`@$U3
+M0T8`````Y!]W__\;-A8T``````"!`$#U`@`!`&@````!]9^?```5`"T-````
+M`6QT(%P*"75I9%P*"75I9%P*"75I9%P*"75I9%P*"75I9%P*"7456BUL:#4M
+M#0````%L<0!SI/\````!]9^?```5`"T-`````6P56BUL:#4M#0````%L<0!S
+MI/\````!]9^?```5`"T-``#_``#J`"L-"E=!`````````````````````!$`
+M`!04%!04%!06`O__%*"@H*"@H*"@_PIW\M$"+@L*+@I&"@HV"BX*"BXH"F0*
+M+@H*+@HNYWJ""BX*"C?^___L+H`NCPHNMX*"@H*"@H*"@H*"@H*"@H*"@H*"
+M@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"
+M"@HV"BX*"BXH"F0*+@H*+@HNYWJ""BX*"C?^___L+H`N"BZW"F?_&_9<9```
+M@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"`/\G`)$`
+M@`#L`!OV7&0```%L%5HM;&@U+0T````!;'$`<Z3_`````71Y<&4];`HN"BX*
+M+@HN"BX*+FIJ:FIJ:@HN,#@T279R(&1E=FEC93US=B]S964];`HN"BX*+G0@
+M9'!Y93UL"BX*+@HN"BX*+@HN:FIJ:E)#)R\V,#@U+W-E="!\>7!E/6P*+@HN
+M"BYT('1Y<&4];`HN,"X*+@HN="!T>7!E/2X*+@HN"BYJ:FHP+W-E93UL"BX*
+M+@HN="!T>7!E+W-E="!T>7!E/6P*+@HN"BYT+G0@='G^6_]P9</#P\/#P\/#
+MP\/#P\/#P\/#P\/#P\/"P\/#P\/#+W-E="!D979I8V4]8G-D<V5T(&1E=FEC
+M93UB<V1O<RPM9"PN9"PN"BX*<R=D+2PL+F0L+@HN"B=S+"UD+"X*+@HN"BX*
+M+@HN"BL*70I="ET*70I="ET*70I="ET*70I="ET*70I="ET*70I="ET*70I=
+M"B%="ET*70I="ET*70I="ET*70I="ET*70I="@I="ET*70I="ET*70I="ET*
+M70I="ET*70I="ET*70I="ET*70I="ET*70H*70I="ET*70I="ET*70I="ET*
+M70I="ET*70I="ET*70I="ET*70I="ET*70I="ET*70I="ET*70I="ET*70I=
+M"ET*70I="ET*75T*70I="ET*70I="ET*9"PN"BX*+@HN"BX*"BX*+BYS9&7_
+M]P```````,/#P\/#P\/#P\/#P\/#P\/#P\/#P\/#P\,``"D(-```!0`!``$`
+M@A8!!0`````````````````!```(\/#P\/!A\/#P\/#P\.+P\/#P\/#P,O#P
+M\%!+`P1.`%IB#B@!`/P```#M@!4```###P\/#V?QZ@\/#P\/#P\/#P\/#P\/
+M#P\/#P\/#P\/#P\/#P\/#U37[OL```!02R&PHU:*0,/#)\+#S</#0\/#PP\`
+M#P\!]9^?```5`"T-`````6P56BUL:#4M#0````%L<0!SI/\````!]9^?```5
+M`"T-`````6P56BUL:#4M#0````%L<0!SI/\````!]9^?```5`"T-`````6P5
+M6BUL:#4M#0````%L<0!SI/\````!]9^?```5`"T-`````6P56BUL:#4M#0``
+M``%L<0!SI/\````!]9^?```%`"T-`````8Z.CHXICHZ.K0'H````````````
+M`````/]L%5HM;&@U+0T````!;'$`<Z3_`````?6?GP``%0`M#0````%L%5HM
+M;&@U+0T````!;'$`<Z3_`````?6?GP``%0`M#0````%L%5HM;&@U+0T`````
+M;'$`<Z3_`````?6?GP``%0`M#0````%L%5HM;&@U+=(``0!R(8WO`M(`M`%?
+MC>\"T@`"TGX!M,-'4CQ2:7`)20`&`````````(WO`M(``0!R(8WO`M(``0!R
+M(8WO`M(``0!R(8WO`M(`M`%?C>\"T@`"TGX!M,-'4CQ:!@!I`'`)20``````
+M`(WO`M(``0!R(8WO`M(``0!R(8WO`M(``0!R(8WO`M(`M`%?C>^NT@`"TGX!
+MM%)A<B$:!P$`C>\"T@`"PP<<@`<`_O__T?___^@@JP#_Q00``B$<`0(`#@``
+M`0``_@C2(`$>____"```_?__$`#_W5A04)#_!&R&;;%DS,RWL0!)`(/__P#_
+M`/\`^?__\&3/)#)(L0!)`#J#+O_______REH%PHHV#!="0"N)$%SF_J;$___
+M_YP#%9,I````_________Q/_____________________________________
+M_RC_____`P````````#_____*/]!04%!0=U891/_9?]0/2[_______\I:!<*
+M*-@P70D`KB1!<YOZFQ/___^<_^5L*0```/________\3________________
+M______________________\H____/0T.#0I5"E!!W5AE$_]E_U`]/0T.#0I5
+M"E#;V^+;V]O;V____________W________________________________W_
+ME/\56BUL:#4M#0````%L<0!SI/\````!]9^?```5`"T-`````6P56BUL:#4M
+M#0````%L<0!SI/\````!]9^?```5`"T-`````6P56BUL:#4M#0````%L<0!S
+MI/\````!]9^?```5`"T-`````6P56BUL:#4M#0````%L<0!SI/\````!]9^?
+M```5`"T-`````6P56BUL:#4M#0````%L<0!SI/\````!]9^?```5`"T-````
+M`6P56BUL:#4M#0````%L<0!SI/\````!]9^?```5`"T-`````6P56BUL:#4M
+M#0````%L<0!SI/\````!]9^?8C,*-`HN"EQ<7%Q<7%Q<7%Q<7%Q<7%Q<7%Q<
+M7`3_________`F@`!+_)_P\LL`#__V%R(1H'``1G=$Q24``0````(`$`````
+M```,J7\`+@TU'`#]_P`!````````!EQ<8C<*-`HN"EQ<7%Q<7%Q<7%Q<7%Q<
+M7%Q<7%Q<7`3__RTQ#0I#;U!+`P31!-'1!-$$*%+KZB$6____[```````````
+M-WJ\KR<<\9WSM=;L```````````V``````#___^"@H(!!0("`@("`@("`@("
+M`@(/#P\/#P\/#P\/#U0ZS<@`_\/_/\/#P\/#P\/#P\/#P\/#P\/#P\/#P\/#
+MP\/#P\/#P\/#P\/#P\/#P\/#P\/#P\/#P\/#P\/'P\/#PT```(F?GY_RGP&?
+MWY^?]4```(F?GY_RGP&?WY^?]4```(DO<V5T(&9L86=S/0HN"BX*+@HN"BX*
+M+@HN"BXN"BX*+@HN"BX*+@HN"BX*"BX*+@HN"BX*)@HN"BX*+@HN"BX*+@HN
+M"BX*+@HN"BX*+@HN"BX*+@HN"BX*+@HN"BX*+@`*+@HN"BY^+@HN"BX*+@HN
+M"BX*+@HN"@HN"BX*+@HN"BX*+@HN"BX*+@HA&@<`!&=T3%)0`!`````@4$L#
+M!#$`</^I?P`N#34<`/W_``$7%@I<7"Y<7%RT`5^-[P+2```$O\FTPT=2/%II
+9<`E)``8`````````C>\"T@``````````````
+`
+end
diff --git a/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu b/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu
new file mode 100644
index 000000000000..85391fa4e1f6
--- /dev/null
+++ b/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu
@@ -0,0 +1,16 @@
+begin 644 test_read_format_rar5_different_winsize_on_merge.rar.uu
+M4F%R(1H'`0"-[P+2``+''QP,!`H``"0`N)$#`0(H$"<"``X`/3Q/`0"V````
+MQ@$````V`/^%02`H^B7&,NX``"F&AK%M-50O<WY2!P$`C>\"T@`"_[6U,1"U
+MM;6UM[BU45)A<K6UM;6UM+6U```\______?______________P`&80"-[P+2
+MT@`#TA________\`M,-:!`8``(0A_^\"TE)A<J$?Y@<!`(WO`BCZ)<8R[@``
+M*8:&L6TU5"]S?E('`0"-[P+2``+_M0`````````DM3$0M;6UM;>XM5%287*U
+MM;6UM;2UM0``//_____W______________\`!F$`C>\"TM(``](?________
+M`+3#6@0&D0,!`B@0)P(`#@`]/$\!`+8```#&`0```#8`_X5!("CZ)<8R[@``
+M*8:&L6TU5"]S?E(`````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````<!`(WO````
+M`````````````````````````````````````````````````````$``````
+M`````````````````````````````````#$S-S4V-#<`_P0$!`0G!`0$!`0$
+"!`0`
+`
+end
diff --git a/libarchive/test/test_sparse_basic.c b/libarchive/test/test_sparse_basic.c
index f12b6af4862a..5ad591be830d 100644
--- a/libarchive/test/test_sparse_basic.c
+++ b/libarchive/test/test_sparse_basic.c
@@ -127,7 +127,7 @@ create_sparse_file(const char *path, const struct sparse *s)
assert(DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0,
NULL, 0, &dmy, NULL) != 0);
- size_t offsetSoFar = 0;
+ uint64_t offsetSoFar = 0;
while (s->type != END) {
if (s->type == HOLE) {
@@ -282,7 +282,7 @@ create_sparse_file(const char *path, const struct sparse *s)
{
char buff[1024];
int fd;
- size_t total_size = 0;
+ uint64_t total_size = 0;
const struct sparse *cur = s;
memset(buff, ' ', sizeof(buff));
@@ -555,6 +555,12 @@ DEFINE_TEST(test_sparse_basic)
{ HOLE, 1 }, { DATA, 10240 },
{ END, 0 }
};
+ const struct sparse sparse_file4[] = {
+ { DATA, 4096 }, { HOLE, 0xc0000000 },
+ /* This hole overflows the offset if stored in 32 bits. */
+ { DATA, 4096 }, { HOLE, 0x50000000 },
+ { END, 0 }
+ };
/*
* Test for the case that sparse data indicates just the whole file
@@ -596,6 +602,7 @@ DEFINE_TEST(test_sparse_basic)
verify_sparse_file(a, "file2", sparse_file2, 20);
/* Encoded non sparse; expect a data block but no sparse entries. */
verify_sparse_file(a, "file3", sparse_file3, 0);
+ verify_sparse_file(a, "file4", sparse_file4, 2);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
diff --git a/test_utils/test_main.c b/test_utils/test_main.c
index 1b9af9a9c37b..1b44edf171d9 100644
--- a/test_utils/test_main.c
+++ b/test_utils/test_main.c
@@ -1863,7 +1863,7 @@ is_symlink(const char *file, int line,
return (0);
if (contents == NULL)
return (1);
- linklen = readlink(pathname, buff, sizeof(buff));
+ linklen = readlink(pathname, buff, sizeof(buff) - 1);
if (linklen < 0) {
failure_start(file, line, "Can't read symlink %s", pathname);
failure_finish(NULL);