aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2026-04-13 13:22:49 +0000
committerMartin Matuska <mm@FreeBSD.org>2026-04-13 13:29:20 +0000
commitf2cd95a372000681bafe284df6ba857d5c2541c2 (patch)
tree750d581c1606b7a02f4a8cbdb2485219b7f44215
parent01333e8c4dd7b5e2bb90cc773332613cf085ccf4 (diff)
-rw-r--r--.cirrus.yml19
-rw-r--r--CMakeLists.txt1
-rw-r--r--Makefile.am17
-rw-r--r--NEWS4
-rw-r--r--README.md9
-rw-r--r--build/cmake/config.h.in6
-rw-r--r--build/version2
-rw-r--r--configure.ac4
-rw-r--r--contrib/android/Android.mk1
-rw-r--r--contrib/oss-fuzz/libarchive_linkify_fuzzer.cc13
-rw-r--r--contrib/untar.c4
-rw-r--r--cpio/CMakeLists.txt2
-rw-r--r--cpio/cmdline.c15
-rw-r--r--cpio/cpio.c123
-rw-r--r--cpio/cpio.h2
-rw-r--r--cpio/test/test_format_newc.c7
-rw-r--r--libarchive/archive.h4
-rw-r--r--libarchive/archive_acl.c6
-rw-r--r--libarchive/archive_check_magic.c4
-rw-r--r--libarchive/archive_cryptor_private.h4
-rw-r--r--libarchive/archive_entry.h2
-rw-r--r--libarchive/archive_hmac.c6
-rw-r--r--libarchive/archive_options.c4
-rw-r--r--libarchive/archive_pathmatch.c4
-rw-r--r--libarchive/archive_ppmd8.c22
-rw-r--r--libarchive/archive_ppmd8_private.h25
-rw-r--r--libarchive/archive_read.c12
-rw-r--r--libarchive/archive_read_append_filter.c4
-rw-r--r--libarchive/archive_read_disk_posix.c6
-rw-r--r--libarchive/archive_read_disk_windows.c6
-rw-r--r--libarchive/archive_read_open_filename.c7
-rw-r--r--libarchive/archive_read_support_filter_grzip.c2
-rw-r--r--libarchive/archive_read_support_filter_lz4.c4
-rw-r--r--libarchive/archive_read_support_filter_lzop.c2
-rw-r--r--libarchive/archive_read_support_filter_program.c2
-rw-r--r--libarchive/archive_read_support_format_7zip.c24
-rw-r--r--libarchive/archive_read_support_format_cab.c24
-rw-r--r--libarchive/archive_read_support_format_cpio.c4
-rw-r--r--libarchive/archive_read_support_format_iso9660.c26
-rw-r--r--libarchive/archive_read_support_format_lha.c11
-rw-r--r--libarchive/archive_read_support_format_mtree.c7
-rw-r--r--libarchive/archive_read_support_format_rar.c73
-rw-r--r--libarchive/archive_read_support_format_rar5.c45
-rw-r--r--libarchive/archive_read_support_format_tar.c6
-rw-r--r--libarchive/archive_read_support_format_xar.c14
-rw-r--r--libarchive/archive_read_support_format_zip.c22
-rw-r--r--libarchive/archive_string.c16
-rw-r--r--libarchive/archive_write.c2
-rw-r--r--libarchive/archive_write_add_filter_b64encode.c22
-rw-r--r--libarchive/archive_write_add_filter_bzip2.c7
-rw-r--r--libarchive/archive_write_add_filter_gzip.c12
-rw-r--r--libarchive/archive_write_add_filter_lrzip.c21
-rw-r--r--libarchive/archive_write_add_filter_lz4.c14
-rw-r--r--libarchive/archive_write_add_filter_lzop.c7
-rw-r--r--libarchive/archive_write_add_filter_uuencode.c22
-rw-r--r--libarchive/archive_write_add_filter_xz.c27
-rw-r--r--libarchive/archive_write_add_filter_zstd.c52
-rw-r--r--libarchive/archive_write_disk_posix.c30
-rw-r--r--libarchive/archive_write_disk_windows.c2
-rw-r--r--libarchive/archive_write_set_format_7zip.c9
-rw-r--r--libarchive/archive_write_set_format_cpio_binary.c4
-rw-r--r--libarchive/archive_write_set_format_cpio_newc.c2
-rw-r--r--libarchive/archive_write_set_format_cpio_odc.c2
-rw-r--r--libarchive/archive_write_set_format_gnutar.c34
-rw-r--r--libarchive/archive_write_set_format_iso9660.c18
-rw-r--r--libarchive/archive_write_set_format_mtree.c2
-rw-r--r--libarchive/archive_write_set_format_pax.c6
-rw-r--r--libarchive/archive_write_set_format_ustar.c27
-rw-r--r--libarchive/archive_write_set_format_v7tar.c27
-rw-r--r--libarchive/archive_write_set_format_xar.c6
-rw-r--r--libarchive/archive_write_set_format_zip.c49
-rw-r--r--libarchive/test/CMakeLists.txt6
-rw-r--r--libarchive/test/test_acl_text.c23
-rw-r--r--libarchive/test/test_archive_pathmatch.c18
-rw-r--r--libarchive/test/test_archive_string_conversion.c135
-rw-r--r--libarchive/test/test_gnutar_filename_encoding.c40
-rw-r--r--libarchive/test/test_read_format_7zip.c26
-rw-r--r--libarchive/test/test_read_format_7zip_malformed.c17
-rw-r--r--libarchive/test/test_read_format_7zip_malformed3.7z.uu24
-rw-r--r--libarchive/test/test_read_format_7zip_sfx_elf64trunc.elf.uu5
-rw-r--r--libarchive/test/test_read_format_cab_lzx_oob.c45
-rw-r--r--libarchive/test/test_read_format_cab_lzx_oob.cab.uu11
-rw-r--r--libarchive/test/test_read_format_cab_skip_malformed.c41
-rw-r--r--libarchive/test/test_read_format_cab_skip_malformed.cab.uu95
-rw-r--r--libarchive/test/test_read_format_iso_zisofs_overflow.c104
-rw-r--r--libarchive/test/test_read_format_iso_zisofs_overflow.iso.uu1096
-rw-r--r--libarchive/test/test_read_format_lha_oversize_header.c50
-rw-r--r--libarchive/test/test_read_format_lha_oversize_header.lzh.uu60
-rw-r--r--libarchive/test/test_read_format_rar5_loop_bug.c53
-rw-r--r--libarchive/test/test_read_format_rar5_loop_bug.rar.uu189
-rw-r--r--libarchive/test/test_read_set_format.c34
-rw-r--r--libarchive/test/test_ustar_filename_encoding.c40
-rw-r--r--libarchive/test/test_v7tar_filename_encoding.c67
-rw-r--r--libarchive/test/test_warn_missing_hardlink_target.c2
-rw-r--r--libarchive/test/test_write_disk.c29
-rw-r--r--libarchive/test/test_write_disk_perms.c11
-rw-r--r--libarchive/test/test_zip_filename_encoding.c40
-rw-r--r--libarchive_fe/lafe_getline.c (renamed from unzip/la_getline.c)11
-rw-r--r--libarchive_fe/lafe_getline.h (renamed from unzip/la_getline.h)15
-rw-r--r--tar/bsdtar.c20
-rw-r--r--tar/read.c2
-rw-r--r--tar/util.c8
-rw-r--r--tar/write.c16
-rw-r--r--test_utils/test_common.h4
-rw-r--r--test_utils/test_main.c85
-rw-r--r--unzip/CMakeLists.txt4
-rw-r--r--unzip/bsdunzip.c6
-rw-r--r--unzip/test/CMakeLists.txt1
108 files changed, 3063 insertions, 401 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 523d9cb61fac..3c99d430a348 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -5,26 +5,21 @@ env:
FreeBSD_task:
matrix:
- env:
- BS: autotools
- env:
- BS: cmake
- matrix:
- - name: 15.0-STABLE (UFS)
- freebsd_instance:
- image_family: freebsd-15-0-amd64-ufs-snap
- - name: 15.0-RELEASE (UFS)
+ - name: 15.0-RELEASE (UFS) cmake
freebsd_instance:
image_family: freebsd-15-0-amd64-ufs
+ env:
+ BS: cmake
- name: 15.0-RELEASE (ZFS)
freebsd_instance:
image_family: freebsd-15-0-amd64-zfs
+ env:
+ BS: autotools
- name: 14.3-RELEASE
freebsd_instance:
image_family: freebsd-14-3
- - name: 13.5-RELEASE
- freebsd_instance:
- image_family: freebsd-13-5
+ env:
+ BS: cmake
prepare_script:
- ./build/ci/cirrus_ci/ci.sh prepare
configure_script:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3ab6291332fb..4d9c5ccfe5b6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -747,6 +747,7 @@ LA_CHECK_INCLUDE_FILE("signal.h" HAVE_SIGNAL_H)
LA_CHECK_INCLUDE_FILE("spawn.h" HAVE_SPAWN_H)
LA_CHECK_INCLUDE_FILE("stdarg.h" HAVE_STDARG_H)
LA_CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H)
+LA_CHECK_INCLUDE_FILE("stdio.h" HAVE_STDIO_H)
LA_CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H)
LA_CHECK_INCLUDE_FILE("string.h" HAVE_STRING_H)
LA_CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
diff --git a/Makefile.am b/Makefile.am
index a3b04e75a04f..c34e8da922d2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -475,6 +475,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_ar.c \
libarchive/test/test_read_format_cab.c \
libarchive/test/test_read_format_cab_filename.c \
+ libarchive/test/test_read_format_cab_lzx_oob.c \
libarchive/test/test_read_format_cpio_afio.c \
libarchive/test/test_read_format_cpio_bin.c \
libarchive/test/test_read_format_cpio_bin_Z.c \
@@ -512,10 +513,12 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_isorr_new_bz2.c \
libarchive/test/test_read_format_isorr_rr_moved.c \
libarchive/test/test_read_format_isozisofs_bz2.c \
+ libarchive/test/test_read_format_iso_zisofs_overflow.c \
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_lha_oversize_header.c \
libarchive/test/test_read_format_mtree.c \
libarchive/test/test_read_format_mtree_crash747.c \
libarchive/test/test_read_format_pax_bz2.c \
@@ -528,6 +531,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_rar_invalid1.c \
libarchive/test/test_read_format_rar_overflow.c \
libarchive/test/test_read_format_rar5.c \
+ libarchive/test/test_read_format_rar5_loop_bug.c \
libarchive/test/test_read_format_raw.c \
libarchive/test/test_read_format_tar.c \
libarchive/test/test_read_format_tar_V_negative_size.c \
@@ -588,6 +592,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_tar_large.c \
libarchive/test/test_ustar_filenames.c \
libarchive/test/test_ustar_filename_encoding.c \
+ libarchive/test/test_v7tar_filename_encoding.c \
libarchive/test/test_warn_missing_hardlink_target.c \
libarchive/test/test_write_disk.c \
libarchive/test/test_write_disk_appledouble.c \
@@ -829,9 +834,11 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_7zip_lzma2_sparc.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_malformed3.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_sfx_elf.elf.uu \
+ libarchive/test/test_read_format_7zip_sfx_elf64trunc.elf.uu \
libarchive/test/test_read_format_7zip_sfx_modified_pe.exe.uu \
libarchive/test/test_read_format_7zip_sfx_pe.exe.uu \
libarchive/test/test_read_format_7zip_solid_zstd.7z.uu \
@@ -847,6 +854,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_cab_2.cab.uu \
libarchive/test/test_read_format_cab_3.cab.uu \
libarchive/test/test_read_format_cab_filename_cp932.cab.uu \
+ libarchive/test/test_read_format_cab_lzx_oob.cab.uu \
libarchive/test/test_read_format_cpio_bin_be.cpio.uu \
libarchive/test/test_read_format_cpio_bin_le.cpio.uu \
libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu \
@@ -883,6 +891,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu \
libarchive/test/test_read_format_iso_xorriso.iso.Z.uu \
libarchive/test/test_read_format_iso_zisofs.iso.Z.uu \
+ libarchive/test/test_read_format_iso_zisofs_overflow.iso.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 \
@@ -893,6 +902,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_lha_lh0.lzh.uu \
libarchive/test/test_read_format_lha_lh6.lzh.uu \
libarchive/test/test_read_format_lha_lh7.lzh.uu \
+ libarchive/test/test_read_format_lha_oversize_header.lzh.uu \
libarchive/test/test_read_format_lha_withjunk.lzh.uu \
libarchive/test/test_read_format_mtree.mtree.uu \
libarchive/test/test_read_format_mtree_nomagic.mtree.uu \
@@ -947,6 +957,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu \
libarchive/test/test_read_format_rar5_leftshift1.rar.uu \
libarchive/test/test_read_format_rar5_leftshift2.rar.uu \
+ libarchive/test/test_read_format_rar5_loop_bug.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part02.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part03.rar.uu \
@@ -1083,11 +1094,13 @@ libarchive_test_EXTRA_DIST=\
#
noinst_HEADERS+= \
libarchive_fe/lafe_err.h \
+ libarchive_fe/lafe_getline.h \
libarchive_fe/lafe_platform.h \
libarchive_fe/line_reader.h \
libarchive_fe/passphrase.h
libarchive_fe_la_SOURCES= \
libarchive_fe/lafe_err.c \
+ libarchive_fe/lafe_getline.c \
libarchive_fe/line_reader.c \
libarchive_fe/passphrase.c
@@ -1551,12 +1564,10 @@ bsdcat_test_EXTRA_DIST= \
noinst_HEADERS+= \
unzip/bsdunzip.h \
unzip/bsdunzip_platform.h \
- unzip/la_getline.h \
unzip/la_queue.h
bsdunzip_SOURCES= \
unzip/bsdunzip.c \
- unzip/cmdline.c \
- unzip/la_getline.c
+ unzip/cmdline.c
if INC_WINDOWS_FILES
noinst_HEADERS+=
diff --git a/NEWS b/NEWS
index be14de445b57..d5e9769771e2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Apr 13, 2026: libarchive 3.8.7 released
+
+Mar 10, 2026: libarchive 3.8.6 released
+
Jan 05, 2026: libarchive 3.8.5 released
Dec 01, 2025: libarchive 3.8.4 released
diff --git a/README.md b/README.md
index e9691f1b710b..3009e1b54d18 100644
--- a/README.md
+++ b/README.md
@@ -37,10 +37,13 @@ The top-level directory contains the following information files:
* **CMakeLists.txt** - input for "cmake" build tool, see INSTALL
* **configure** - configuration script, see INSTALL for details. If your copy of the source lacks a `configure` script, you can try to construct it by running the script in `build/autogen.sh` (or use `cmake`).
-The following files in the top-level directory are used by the 'configure' script:
+The following files in the top-level directory are related to the 'configure' script and are only needed by maintainers:
-* `Makefile.am`, `aclocal.m4`, `configure.ac` - used to build this distribution, only needed by maintainers
-* `Makefile.in`, `config.h.in` - templates used by configure script
+* `configure.ac` - used (by autoconf) to build the configure script and related files
+* `Makefile.am` - used (by automake) to generate Makefile.in
+* `aclocal.m4` - auto-generated file (created by aclocal) used to build the configure script
+* `Makefile.in` - auto-generated template (created by automake) used by the configure script to create Makefile
+* `config.h.in` - auto-generated template (created by autoheader) used by the configure script to create config.h
## Documentation
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index 06f66b4378c1..97ff59476720 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -642,6 +642,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `getea' function. */
#cmakedefine HAVE_GETEA 1
+/* Define to 1 if you have the `getegid' function. */
+#cmakedefine HAVE_GETEGID 1
+
/* Define to 1 if you have the `geteuid' function. */
#cmakedefine HAVE_GETEUID 1
@@ -1025,6 +1028,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
+/* Define to 1 if you have the <stdio.h> header file. */
+#cmakedefine HAVE_STDIO_H 1
+
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H 1
diff --git a/build/version b/build/version
index 3f78540c6288..99c36462af96 100644
--- a/build/version
+++ b/build/version
@@ -1 +1 @@
-3008005
+3008007
diff --git a/configure.ac b/configure.ac
index b60b886e62d5..84fe33fd8a9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release.
-m4_define([LIBARCHIVE_VERSION_S],[3.8.5])
-m4_define([LIBARCHIVE_VERSION_N],[3008005])
+m4_define([LIBARCHIVE_VERSION_S],[3.8.7])
+m4_define([LIBARCHIVE_VERSION_N],[3008007])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
diff --git a/contrib/android/Android.mk b/contrib/android/Android.mk
index 20e46a699643..1fdd2bf7cf35 100644
--- a/contrib/android/Android.mk
+++ b/contrib/android/Android.mk
@@ -159,6 +159,7 @@ libarchive_host_src_files :=
endif
libarchive_fe_src_files := libarchive_fe/lafe_err.c \
+ libarchive_fe/lafe_getline.c \
libarchive_fe/line_reader.c \
libarchive_fe/passphrase.c
diff --git a/contrib/oss-fuzz/libarchive_linkify_fuzzer.cc b/contrib/oss-fuzz/libarchive_linkify_fuzzer.cc
index 64c22dca959c..c8d05a2b934b 100644
--- a/contrib/oss-fuzz/libarchive_linkify_fuzzer.cc
+++ b/contrib/oss-fuzz/libarchive_linkify_fuzzer.cc
@@ -76,14 +76,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
// This is the main function we want to fuzz (zero coverage)
archive_entry_linkify(resolver, &entry, &spare);
- // entry and spare may be modified by linkify
- // We still need to free the original entries we allocated
+ // Update entries[i] to reflect ownership changes from linkify.
+ // If linkify cached the entry internally, entry is now NULL and the
+ // resolver owns the object. If linkify swapped it with a previously
+ // cached entry, entry points to that other object.
+ entries[i] = entry;
+
+ // Free any entry returned via spare (complete hardlink pair)
if (spare != NULL) {
archive_entry_free(spare);
}
}
- // Free remaining entries from the resolver
+ // Free remaining entries from the resolver (drain loop)
struct archive_entry *entry = NULL;
struct archive_entry *spare = NULL;
while (1) {
@@ -98,7 +103,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
}
}
- // Free all our created entries
+ // Free all our created entries that were NOT consumed by the resolver
for (int i = 0; i < num_entries; i++) {
if (entries[i] != NULL) {
archive_entry_free(entries[i]);
diff --git a/contrib/untar.c b/contrib/untar.c
index 6d5e88e2f097..0d862b8a8e0a 100644
--- a/contrib/untar.c
+++ b/contrib/untar.c
@@ -60,11 +60,11 @@ parseoct(const char *p, size_t n)
{
unsigned long i = 0;
- while ((*p < '0' || *p > '7') && n > 0) {
+ while (n > 0 && (*p < '0' || *p > '7')) {
++p;
--n;
}
- while (*p >= '0' && *p <= '7' && n > 0) {
+ while (n > 0 && *p >= '0' && *p <= '7') {
i *= 8;
i += *p - '0';
++p;
diff --git a/cpio/CMakeLists.txt b/cpio/CMakeLists.txt
index 7678ed658ae7..683f542d70f2 100644
--- a/cpio/CMakeLists.txt
+++ b/cpio/CMakeLists.txt
@@ -15,6 +15,8 @@ IF(ENABLE_CPIO)
cpio_platform.h
../libarchive_fe/lafe_err.c
../libarchive_fe/lafe_err.h
+ ../libarchive_fe/lafe_getline.c
+ ../libarchive_fe/lafe_getline.h
../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h
diff --git a/cpio/cmdline.c b/cpio/cmdline.c
index db06c03c011d..a3d029c65161 100644
--- a/cpio/cmdline.c
+++ b/cpio/cmdline.c
@@ -11,6 +11,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
@@ -347,9 +350,10 @@ owner_parse(const char *spec, struct cpio_owner *owner, const char **errmsg)
owner->gid = pwent->pw_gid;
} else {
char *end;
+ unsigned long val;
errno = 0;
- owner->uid = (int)strtoul(user, &end, 10);
- if (errno || *end != '\0') {
+ val = strtoul(user, &end, 10);
+ if (errno || *end != '\0' || val > (unsigned)INT_MAX) {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup user ``%s''", user);
errbuff[sizeof(errbuff) - 1] = '\0';
@@ -357,6 +361,7 @@ owner_parse(const char *spec, struct cpio_owner *owner, const char **errmsg)
*errmsg = errbuff;
return (-1);
}
+ owner->uid = (int)val;
}
free(user);
}
@@ -373,15 +378,17 @@ owner_parse(const char *spec, struct cpio_owner *owner, const char **errmsg)
}
} else {
char *end;
+ unsigned long val;
errno = 0;
- owner->gid = (int)strtoul(g, &end, 10);
- if (errno || *end != '\0') {
+ val = strtoul(g, &end, 10);
+ if (errno || *end != '\0' || val > (unsigned)INT_MAX) {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup group ``%s''", g);
errbuff[sizeof(errbuff) - 1] = '\0';
*errmsg = errbuff;
return (-1);
}
+ owner->gid = (int)val;
}
}
return (0);
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 77eefe809f37..6e6c2c3356c0 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -8,6 +8,8 @@
#include "cpio_platform.h"
+#include "lafe_getline.h"
+
#include <sys/types.h>
#include <archive.h>
#include <archive_entry.h>
@@ -33,6 +35,9 @@
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
@@ -83,7 +88,7 @@ struct name_cache {
static int extract_data(struct archive *, struct archive *);
const char * cpio_i64toa(int64_t);
-static const char *cpio_rename(const char *name);
+static void cpio_rename(struct archive_entry *);
static int entry_to_archive(struct cpio *, struct archive_entry *);
static int file_to_archive(struct cpio *, const char *);
static void free_cache(struct name_cache *cache);
@@ -110,19 +115,16 @@ static void passphrase_free(char *);
int
main(int argc, char *argv[])
{
- static char buff[16384];
struct cpio _cpio; /* Allocated on stack. */
struct cpio *cpio;
struct cpio_owner owner;
const char *errmsg;
char *tptr;
- int opt, t;
+ int opt;
+ long t;
cpio = &_cpio;
memset(cpio, 0, sizeof(*cpio));
- cpio->buff = buff;
- cpio->buff_size = sizeof(buff);
-
#if defined(HAVE_SIGACTION)
{
@@ -204,13 +206,13 @@ main(int argc, char *argv[])
case 'C': /* NetBSD/OpenBSD */
errno = 0;
tptr = NULL;
- t = (int)strtol(cpio->argument, &tptr, 10);
- if (errno || t <= 0 || *(cpio->argument) == '\0' ||
+ t = strtol(cpio->argument, &tptr, 10);
+ if (errno || t <= 0 || t > INT_MAX || *(cpio->argument) == '\0' ||
tptr == NULL || *tptr != '\0') {
lafe_errc(1, 0, "Invalid blocksize: %s",
cpio->argument);
}
- cpio->bytes_per_block = t;
+ cpio->bytes_per_block = (int)t;
break;
case 'c': /* POSIX 1997 */
cpio->format = "odc";
@@ -222,7 +224,7 @@ main(int argc, char *argv[])
if (archive_match_include_pattern_from_file(
cpio->matching, cpio->argument,
cpio->option_null) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(cpio->matching));
break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */
@@ -231,7 +233,7 @@ main(int argc, char *argv[])
case 'f': /* POSIX 1997 */
if (archive_match_exclude_pattern(cpio->matching,
cpio->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(cpio->matching));
break;
case OPTION_GRZIP:
@@ -247,7 +249,7 @@ main(int argc, char *argv[])
cpio->filename = cpio->argument;
break;
case 'i': /* POSIX 1997 */
- if (cpio->mode != '\0')
+ if (cpio->mode != '\0' && cpio->mode != opt)
lafe_errc(1, 0,
"Cannot use both -i and -%c", cpio->mode);
cpio->mode = opt;
@@ -289,13 +291,13 @@ main(int argc, char *argv[])
cpio->filename = cpio->argument;
break;
case 'o': /* POSIX 1997 */
- if (cpio->mode != '\0')
+ if (cpio->mode != '\0' && cpio->mode != opt)
lafe_errc(1, 0,
"Cannot use both -o and -%c", cpio->mode);
cpio->mode = opt;
break;
case 'p': /* POSIX 1997 */
- if (cpio->mode != '\0')
+ if (cpio->mode != '\0' && cpio->mode != opt)
lafe_errc(1, 0,
"Cannot use both -p and -%c", cpio->mode);
cpio->mode = opt;
@@ -316,17 +318,21 @@ main(int argc, char *argv[])
if (owner_parse(cpio->argument, &owner, &errmsg) != 0) {
if (!errmsg)
errmsg = "Error parsing owner";
- lafe_warnc(-1, "%s", errmsg);
+ lafe_warnc(0, "%s", errmsg);
usage();
}
if (owner.uid != -1)
cpio->uid_override = owner.uid;
- if (owner.uname != NULL)
+ if (owner.uname != NULL) {
+ free(cpio->uname_override);
cpio->uname_override = owner.uname;
+ }
if (owner.gid != -1)
cpio->gid_override = owner.gid;
- if (owner.gname != NULL)
+ if (owner.gname != NULL) {
+ free(cpio->gname_override);
cpio->gname_override = owner.gname;
+ }
break;
case 'r': /* POSIX 1997 */
cpio->option_rename = 1;
@@ -409,7 +415,7 @@ main(int argc, char *argv[])
while (*cpio->argv != NULL) {
if (archive_match_include_pattern(cpio->matching,
*cpio->argv) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(cpio->matching));
--cpio->argc;
++cpio->argv;
@@ -427,7 +433,7 @@ main(int argc, char *argv[])
break;
default:
lafe_errc(1, 0,
- "Must specify at least one of -i, -o, or -p");
+ "Must specify one of -i, -o, or -p");
}
archive_match_free(cpio->matching);
@@ -524,7 +530,7 @@ mode_out(struct cpio *cpio)
int r;
if (cpio->option_append)
- lafe_errc(1, 0, "Append mode not yet supported.");
+ lafe_errc(1, 0, "Append mode not yet supported");
cpio->archive_read_disk = archive_read_disk_new();
if (cpio->archive_read_disk == NULL)
@@ -638,7 +644,7 @@ mode_out(struct cpio *cpio)
int64_t blocks =
(archive_filter_bytes(cpio->archive, 0) + 511)
/ 512;
- fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
+ fprintf(stderr, "%lld %s\n", (long long)blocks,
blocks == 1 ? "block" : "blocks");
}
archive_write_free(cpio->archive);
@@ -696,7 +702,6 @@ remove_leading_slash(const char *p)
static int
file_to_archive(struct cpio *cpio, const char *srcpath)
{
- const char *destpath;
struct archive_entry *entry, *spare;
size_t len;
int r;
@@ -738,7 +743,6 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
* pass mode or the name that will go into the archive in
* output mode.
*/
- destpath = srcpath;
if (cpio->destdir) {
len = cpio->destdir_len + strlen(srcpath) + 8;
if (len >= cpio->pass_destpath_alloc) {
@@ -754,15 +758,17 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
}
strcpy(cpio->pass_destpath, cpio->destdir);
strcat(cpio->pass_destpath, remove_leading_slash(srcpath));
- destpath = cpio->pass_destpath;
+ archive_entry_set_pathname(entry, cpio->pass_destpath);
+ } else {
+ archive_entry_set_pathname(entry, srcpath);
}
if (cpio->option_rename)
- destpath = cpio_rename(destpath);
- if (destpath == NULL) {
+ cpio_rename(entry);
+
+ if (archive_entry_pathname(entry) == NULL) {
archive_entry_free(entry);
return (0);
}
- archive_entry_copy_pathname(entry, destpath);
/*
* If we're trying to preserve hardlinks, match them here.
@@ -791,7 +797,6 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
const char *destpath = archive_entry_pathname(entry);
const char *srcpath = archive_entry_sourcepath(entry);
int fd = -1;
- ssize_t bytes_read;
int r;
/* Print out the destination name to the user. */
@@ -869,21 +874,23 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
exit(1);
if (r >= ARCHIVE_WARN && archive_entry_size(entry) > 0 && fd >= 0) {
- bytes_read = read(fd, cpio->buff, (unsigned)cpio->buff_size);
+ static char buff[16384];
+ ssize_t bytes_read;
+
+ bytes_read = read(fd, buff, sizeof(buff));
while (bytes_read > 0) {
ssize_t bytes_write;
bytes_write = archive_write_data(cpio->archive,
- cpio->buff, bytes_read);
+ buff, bytes_read);
if (bytes_write < 0)
lafe_errc(1, archive_errno(cpio->archive),
"%s", archive_error_string(cpio->archive));
if (bytes_write < bytes_read) {
lafe_warnc(0,
"Truncated write; file may have "
- "grown while being archived.");
+ "grown while being archived");
}
- bytes_read = read(fd, cpio->buff,
- (unsigned)cpio->buff_size);
+ bytes_read = read(fd, buff, sizeof(buff));
}
}
@@ -997,11 +1004,9 @@ mode_in(struct cpio *cpio)
}
if (archive_match_path_excluded(cpio->matching, entry))
continue;
- if (cpio->option_rename) {
- destpath = cpio_rename(archive_entry_pathname(entry));
- archive_entry_set_pathname(entry, destpath);
- } else
- destpath = archive_entry_pathname(entry);
+ if (cpio->option_rename)
+ cpio_rename(entry);
+ destpath = archive_entry_pathname(entry);
if (destpath == NULL)
continue;
if (cpio->verbose)
@@ -1040,7 +1045,7 @@ mode_in(struct cpio *cpio)
if (!cpio->quiet) {
int64_t blocks = (archive_filter_bytes(a, 0) + 511)
/ 512;
- fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
+ fprintf(stderr, "%lld %s\n", (long long)blocks,
blocks == 1 ? "block" : "blocks");
}
archive_read_free(a);
@@ -1125,7 +1130,7 @@ mode_list(struct cpio *cpio)
if (!cpio->quiet) {
int64_t blocks = (archive_filter_bytes(a, 0) + 511)
/ 512;
- fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
+ fprintf(stderr, "%lld %s\n", (long long)blocks,
blocks == 1 ? "block" : "blocks");
}
archive_read_free(a);
@@ -1292,54 +1297,60 @@ mode_pass(struct cpio *cpio, const char *destdir)
* that an input of '.' means the name should be unchanged. GNU cpio
* treats '.' as a literal new name.
*/
-static const char *
-cpio_rename(const char *name)
+void
+cpio_rename(struct archive_entry *entry)
{
- static char buff[1024];
+ char *buff = NULL, *p, *ret = NULL;
FILE *t;
- char *p, *ret;
+ size_t n = 0;
+ ssize_t r;
#if defined(_WIN32) && !defined(__CYGWIN__)
FILE *to;
t = fopen("CONIN$", "r");
if (t == NULL)
- return (name);
+ return;
to = fopen("CONOUT$", "w");
if (to == NULL) {
fclose(t);
- return (name);
+ return;
}
- fprintf(to, "%s (Enter/./(new name))? ", name);
+ fprintf(to, "%s (Enter/./(new name))? ", archive_entry_pathname(entry));
fclose(to);
#else
t = fopen("/dev/tty", "r+");
if (t == NULL)
- return (name);
- fprintf(t, "%s (Enter/./(new name))? ", name);
+ return;
+ fprintf(t, "%s (Enter/./(new name))? ", archive_entry_pathname(entry));
fflush(t);
#endif
- p = fgets(buff, sizeof(buff), t);
+ r = getline(&buff, &n, t);
fclose(t);
- if (p == NULL)
+ if (r < 1)
/* End-of-file is a blank line. */
- return (NULL);
+ goto done;
+ p = buff;
while (*p == ' ' || *p == '\t')
++p;
if (*p == '\n' || *p == '\0')
/* Empty line. */
- return (NULL);
- if (*p == '.' && p[1] == '\n')
+ goto done;
+ if (*p == '.' && p[1] == '\n') {
/* Single period preserves original name. */
- return (name);
+ free(buff);
+ return;
+ }
ret = p;
/* Trim the final newline. */
while (*p != '\0' && *p != '\n')
++p;
/* Overwrite the final \n with a null character. */
*p = '\0';
- return (ret);
+done:
+ archive_entry_set_pathname(entry, ret);
+ free(buff);
}
static void
diff --git a/cpio/cpio.h b/cpio/cpio.h
index 9bc631b544fe..2621a4c3dda3 100644
--- a/cpio/cpio.h
+++ b/cpio/cpio.h
@@ -71,8 +71,6 @@ struct cpio {
/* Work data. */
struct archive *matching;
- char *buff;
- size_t buff_size;
char *ppbuff;
};
diff --git a/cpio/test/test_format_newc.c b/cpio/test/test_format_newc.c
index 33aa16d07a81..9d4e4e9fb674 100644
--- a/cpio/test/test_format_newc.c
+++ b/cpio/test/test_format_newc.c
@@ -6,6 +6,13 @@
*/
#include "test.h"
+#ifdef HAVE_GETEUID
+#define getuid() geteuid()
+#endif
+#ifdef HAVE_GETEGID
+#define getgid() getegid()
+#endif
+
/* Number of bytes needed to pad 'n' to multiple of 'block', assuming
* that 'block' is a power of two. This trick can be more easily
* remembered as -n & (block - 1), but many compilers quite reasonably
diff --git a/libarchive/archive.h b/libarchive/archive.h
index a9d34beb4f5a..41a5440cac75 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -34,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3008005
+#define ARCHIVE_VERSION_NUMBER 3008007
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.8.5"
+#define ARCHIVE_VERSION_ONLY_STRING "3.8.7"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c
index 362e3308f43f..ab601833def6 100644
--- a/libarchive/archive_acl.c
+++ b/libarchive/archive_acl.c
@@ -1256,8 +1256,12 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
tag = 0;
s = field[n].start;
- st = field[n].start + 1;
len = field[n].end - field[n].start;
+ if (len == 0) {
+ ret = ARCHIVE_WARN;
+ continue;
+ }
+ st = s + 1;
switch (*s) {
case L'u':
diff --git a/libarchive/archive_check_magic.c b/libarchive/archive_check_magic.c
index 6b8e0c5595f4..b6e1257949e1 100644
--- a/libarchive/archive_check_magic.c
+++ b/libarchive/archive_check_magic.c
@@ -148,14 +148,14 @@ __archive_check_magic(struct archive *a, unsigned int magic,
if (!handle_type) {
errmsg("PROGRAMMER ERROR: Function ");
errmsg(function);
- errmsg(" invoked with invalid archive handle.\n");
+ errmsg(" invoked with invalid archive handle\n");
diediedie();
}
if (a->magic != magic) {
archive_set_error(a, -1,
"PROGRAMMER ERROR: Function '%s' invoked"
- " on '%s' archive object, which is not supported.",
+ " on '%s' archive object, which is not supported",
function,
handle_type);
a->state = ARCHIVE_STATE_FATAL;
diff --git a/libarchive/archive_cryptor_private.h b/libarchive/archive_cryptor_private.h
index 272f2f84b9c9..1f9298ffdc46 100644
--- a/libarchive/archive_cryptor_private.h
+++ b/libarchive/archive_cryptor_private.h
@@ -109,6 +109,10 @@ typedef struct {
#include <nettle/version.h>
#define ARCHIVE_CRYPTOR_USE_NETTLE 1
+#ifndef AES_MAX_KEY_SIZE
+#define AES_MAX_KEY_SIZE AES256_KEY_SIZE
+#endif
+
typedef struct {
#if NETTLE_VERSION_MAJOR < 3
struct aes_ctx ctx;
diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h
index b43435692c27..7122a74ed007 100644
--- a/libarchive/archive_entry.h
+++ b/libarchive/archive_entry.h
@@ -28,7 +28,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3008005
+#define ARCHIVE_VERSION_NUMBER 3008007
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/libarchive/archive_hmac.c b/libarchive/archive_hmac.c
index 210cca70744d..458092f41b29 100644
--- a/libarchive/archive_hmac.c
+++ b/libarchive/archive_hmac.c
@@ -198,6 +198,7 @@ static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
}
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
+#include <nettle/version.h>
static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
@@ -216,7 +217,12 @@ __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
static void
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
{
+#if NETTLE_VERSION_MAJOR < 4
hmac_sha1_digest(ctx, (unsigned)*out_len, out);
+#else
+ hmac_sha1_digest(ctx, out);
+ *out_len = SHA1_DIGEST_SIZE;
+#endif
}
static void
diff --git a/libarchive/archive_options.c b/libarchive/archive_options.c
index 6e2c0d2a5971..66491bd4183b 100644
--- a/libarchive/archive_options.c
+++ b/libarchive/archive_options.c
@@ -90,7 +90,9 @@ _archive_set_either_option(struct archive *a, const char *m, const char *o, cons
if (r2 == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
- if (r2 == ARCHIVE_WARN - 1)
+ if (r1 == ARCHIVE_WARN - 1)
+ return r2;
+ if (r2 == ARCHIVE_WARN -1)
return r1;
return r1 > r2 ? r1 : r2;
}
diff --git a/libarchive/archive_pathmatch.c b/libarchive/archive_pathmatch.c
index 19e0889ffe55..db0d2b791adf 100644
--- a/libarchive/archive_pathmatch.c
+++ b/libarchive/archive_pathmatch.c
@@ -202,7 +202,7 @@ pm(const char *p, const char *s, int flags)
if (*p == '\0')
return (1);
while (*s) {
- if (archive_pathmatch(p, s, flags))
+ if (pm(p, s, flags))
return (1);
++s;
}
@@ -307,7 +307,7 @@ pm_w(const wchar_t *p, const wchar_t *s, int flags)
if (*p == L'\0')
return (1);
while (*s) {
- if (archive_pathmatch_w(p, s, flags))
+ if (pm_w(p, s, flags))
return (1);
++s;
}
diff --git a/libarchive/archive_ppmd8.c b/libarchive/archive_ppmd8.c
index 30196d64a9f5..04b1c0c3e165 100644
--- a/libarchive/archive_ppmd8.c
+++ b/libarchive/archive_ppmd8.c
@@ -61,7 +61,7 @@ typedef struct CPpmd8_Node_
#define EMPTY_NODE 0xFFFFFFFF
-void Ppmd8_Construct(CPpmd8 *p)
+static void Ppmd8_Construct(CPpmd8 *p)
{
unsigned i, k, m;
@@ -89,14 +89,14 @@ void Ppmd8_Construct(CPpmd8 *p)
}
}
-void Ppmd8_Free(CPpmd8 *p)
+static void Ppmd8_Free(CPpmd8 *p)
{
free(p->Base);
p->Size = 0;
p->Base = 0;
}
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size)
+static Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size)
{
if (p->Base == 0 || p->Size != size)
{
@@ -407,7 +407,7 @@ static void RestartModel(CPpmd8 *p)
}
}
-void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod)
+static void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod)
{
p->MaxOrder = maxOrder;
p->RestoreMethod = restoreMethod;
@@ -1042,7 +1042,7 @@ static void Rescale(CPpmd8 *p)
p->FoundState = STATS(p->MinContext);
}
-CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
+static CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
{
CPpmd_See *see;
if (p->MinContext->NumStats != 0xFF)
@@ -1078,7 +1078,7 @@ static void NextContext(CPpmd8 *p)
}
}
-void Ppmd8_Update1(CPpmd8 *p)
+static void Ppmd8_Update1(CPpmd8 *p)
{
CPpmd_State *s = p->FoundState;
s->Freq += 4;
@@ -1093,7 +1093,7 @@ void Ppmd8_Update1(CPpmd8 *p)
NextContext(p);
}
-void Ppmd8_Update1_0(CPpmd8 *p)
+static void Ppmd8_Update1_0(CPpmd8 *p)
{
p->PrevSuccess = (2 * p->FoundState->Freq >= p->MinContext->SummFreq);
p->RunLength += p->PrevSuccess;
@@ -1103,7 +1103,7 @@ void Ppmd8_Update1_0(CPpmd8 *p)
NextContext(p);
}
-void Ppmd8_UpdateBin(CPpmd8 *p)
+static void Ppmd8_UpdateBin(CPpmd8 *p)
{
p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 196));
p->PrevSuccess = 1;
@@ -1111,7 +1111,7 @@ void Ppmd8_UpdateBin(CPpmd8 *p)
NextContext(p);
}
-void Ppmd8_Update2(CPpmd8 *p)
+static void Ppmd8_Update2(CPpmd8 *p)
{
p->MinContext->SummFreq += 4;
if ((p->FoundState->Freq += 4) > MAX_FREQ)
@@ -1127,7 +1127,7 @@ This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
-Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
+static Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
{
unsigned i;
p->Low = 0;
@@ -1161,7 +1161,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
#define MASK(sym) ((signed char *)charMask)[sym]
-int Ppmd8_DecodeSymbol(CPpmd8 *p)
+static int Ppmd8_DecodeSymbol(CPpmd8 *p)
{
size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 0)
diff --git a/libarchive/archive_ppmd8_private.h b/libarchive/archive_ppmd8_private.h
index 454b75f41f25..f0493de04623 100644
--- a/libarchive/archive_ppmd8_private.h
+++ b/libarchive/archive_ppmd8_private.h
@@ -83,12 +83,6 @@ typedef struct
UInt16 BinSumm[25][64];
} CPpmd8;
-void Ppmd8_Construct(CPpmd8 *p);
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size);
-void Ppmd8_Free(CPpmd8 *p);
-void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
-#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
-
/* ---------- Internal Functions ---------- */
@@ -104,30 +98,11 @@ extern const Byte PPMD8_kExpEscape[16];
#define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
#endif
-void Ppmd8_Update1(CPpmd8 *p);
-void Ppmd8_Update1_0(CPpmd8 *p);
-void Ppmd8_Update2(CPpmd8 *p);
-void Ppmd8_UpdateBin(CPpmd8 *p);
-
#define Ppmd8_GetBinSumm(p) \
&p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
-CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
-
-
-/* ---------- Decode ---------- */
-
-Bool Ppmd8_RangeDec_Init(CPpmd8 *p);
-#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
-int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
-
-/* ---------- Encode ---------- */
-
-#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
-void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
-void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
typedef struct
{
diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
index c9b9d5981516..e5f89bdc8772 100644
--- a/libarchive/archive_read.c
+++ b/libarchive/archive_read.c
@@ -171,7 +171,7 @@ static int64_t
client_skip_proxy(struct archive_read_filter *self, int64_t request)
{
if (request < 0)
- __archive_errx(1, "Negative skip requested.");
+ __archive_errx(1, "Negative skip requested");
if (request == 0)
return 0;
@@ -379,7 +379,7 @@ archive_read_set_callback_data2(struct archive *_a, void *client_data,
if (a->client.dataset == NULL)
{
archive_set_error(&a->archive, ENOMEM,
- "No memory.");
+ "No memory");
return ARCHIVE_FATAL;
}
a->client.nodes = 1;
@@ -388,7 +388,7 @@ archive_read_set_callback_data2(struct archive *_a, void *client_data,
if (iindex > a->client.nodes - 1)
{
archive_set_error(&a->archive, EINVAL,
- "Invalid index specified.");
+ "Invalid index specified");
return ARCHIVE_FATAL;
}
a->client.dataset[iindex].data = client_data;
@@ -409,14 +409,14 @@ archive_read_add_callback_data(struct archive *_a, void *client_data,
"archive_read_add_callback_data");
if (iindex > a->client.nodes) {
archive_set_error(&a->archive, EINVAL,
- "Invalid index specified.");
+ "Invalid index specified");
return ARCHIVE_FATAL;
}
p = realloc(a->client.dataset, sizeof(*a->client.dataset)
* (++(a->client.nodes)));
if (p == NULL) {
archive_set_error(&a->archive, ENOMEM,
- "No memory.");
+ "No memory");
return ARCHIVE_FATAL;
}
a->client.dataset = (struct archive_read_data_node *)p;
@@ -625,7 +625,7 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
r1 = archive_read_data_skip(&a->archive);
if (r1 == ARCHIVE_EOF)
archive_set_error(&a->archive, EIO,
- "Premature end-of-file.");
+ "Premature end-of-file");
if (r1 == ARCHIVE_EOF || r1 == ARCHIVE_FATAL) {
a->archive.state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
diff --git a/libarchive/archive_read_append_filter.c b/libarchive/archive_read_append_filter.c
index cd88df119906..d578b06fe714 100644
--- a/libarchive/archive_read_append_filter.c
+++ b/libarchive/archive_read_append_filter.c
@@ -104,6 +104,10 @@ archive_read_append_filter(struct archive *_a, int code)
strcpy(str, "lrzip");
r1 = archive_read_support_filter_lrzip(_a);
break;
+ case ARCHIVE_FILTER_GRZIP:
+ strcpy(str, "grzip");
+ r1 = archive_read_support_filter_grzip(_a);
+ break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Invalid filter code specified");
diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
index 94fa8fef963f..a7176bdd939d 100644
--- a/libarchive/archive_read_disk_posix.c
+++ b/libarchive/archive_read_disk_posix.c
@@ -921,7 +921,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
r = archive_match_path_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
+ "%s", archive_error_string(a->matching));
return (r);
}
if (r) {
@@ -1035,7 +1035,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
r = archive_match_time_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
+ "%s", archive_error_string(a->matching));
return (r);
}
if (r) {
@@ -1061,7 +1061,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
r = archive_match_owner_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
+ "%s", archive_error_string(a->matching));
return (r);
}
if (r) {
diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c
index 117ca505fadd..0e890497a443 100644
--- a/libarchive/archive_read_disk_windows.c
+++ b/libarchive/archive_read_disk_windows.c
@@ -947,7 +947,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
r = archive_match_path_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
+ "%s", archive_error_string(a->matching));
return (r);
}
if (r) {
@@ -1019,7 +1019,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
r = archive_match_time_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
+ "%s", archive_error_string(a->matching));
return (r);
}
if (r) {
@@ -1045,7 +1045,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
r = archive_match_owner_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
+ "%s", archive_error_string(a->matching));
return (r);
}
if (r) {
diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c
index a910eefcbfd2..9ec1e6c0e808 100644
--- a/libarchive/archive_read_open_filename.c
+++ b/libarchive/archive_read_open_filename.c
@@ -122,13 +122,14 @@ archive_read_open_filenames(struct archive *a, const char **filenames,
archive_clear_error(a);
do
{
+ size_t len;
if (filename == NULL)
filename = "";
- mine = calloc(1,
- sizeof(*mine) + strlen(filename));
+ len = strlen(filename);
+ mine = calloc(1, sizeof(*mine) + len);
if (mine == NULL)
goto no_memory;
- strcpy(mine->filename.m, filename);
+ memcpy(mine->filename.m, filename, len + 1);
mine->block_size = block_size;
mine->fd = -1;
mine->buffer = NULL;
diff --git a/libarchive/archive_read_support_filter_grzip.c b/libarchive/archive_read_support_filter_grzip.c
index 15b6757cb90c..8ec5d1f855cb 100644
--- a/libarchive/archive_read_support_filter_grzip.c
+++ b/libarchive/archive_read_support_filter_grzip.c
@@ -62,7 +62,7 @@ archive_read_support_filter_grzip(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- if (__archive_read_register_bidder(a, NULL, NULL,
+ if (__archive_read_register_bidder(a, NULL, "grzip",
&grzip_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
diff --git a/libarchive/archive_read_support_filter_lz4.c b/libarchive/archive_read_support_filter_lz4.c
index 144572ef2362..acd7f5157997 100644
--- a/libarchive/archive_read_support_filter_lz4.c
+++ b/libarchive/archive_read_support_filter_lz4.c
@@ -363,7 +363,7 @@ lz4_filter_read(struct archive_read_filter *self, const void **p)
case READ_LEGACY_STREAM:
/* Reading a lz4 stream already failed. */
archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Invalid sequence.");
+ ARCHIVE_ERRNO_MISC, "Invalid sequence");
return (ARCHIVE_FATAL);
case READ_DEFAULT_BLOCK:
ret = lz4_filter_read_default_stream(self, p);
@@ -377,7 +377,7 @@ lz4_filter_read(struct archive_read_filter *self, const void **p)
break;
default:
archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Program error.");
+ ARCHIVE_ERRNO_MISC, "Program error");
return (ARCHIVE_FATAL);
}
diff --git a/libarchive/archive_read_support_filter_lzop.c b/libarchive/archive_read_support_filter_lzop.c
index b0c4bb13e8b3..12ed78c578cd 100644
--- a/libarchive/archive_read_support_filter_lzop.c
+++ b/libarchive/archive_read_support_filter_lzop.c
@@ -110,7 +110,7 @@ archive_read_support_filter_lzop(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- if (__archive_read_register_bidder(a, NULL, NULL,
+ if (__archive_read_register_bidder(a, NULL, "lzop",
&lzop_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
diff --git a/libarchive/archive_read_support_filter_program.c b/libarchive/archive_read_support_filter_program.c
index 2c8e45302d8e..9f187f852df3 100644
--- a/libarchive/archive_read_support_filter_program.c
+++ b/libarchive/archive_read_support_filter_program.c
@@ -149,6 +149,8 @@ archive_read_support_filter_program_signature(struct archive *_a,
if (signature != NULL && signature_len > 0) {
state->signature_len = signature_len;
state->signature = malloc(signature_len);
+ if (state->signature == NULL)
+ goto memerr;
memcpy(state->signature, signature, signature_len);
}
diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
index 330d5515dd50..8926ac50a1ed 100644
--- a/libarchive/archive_read_support_format_7zip.c
+++ b/libarchive/archive_read_support_format_7zip.c
@@ -34,6 +34,9 @@
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_BZLIB_H
#include <bzlib.h>
#endif
@@ -80,7 +83,7 @@
/*
* ELF format
*/
-#define ELF_HDR_MIN_LEN 0x3f
+#define ELF_HDR_MIN_LEN 0x40 /* sizeof(Elf64_Ehdr) */
#define ELF_HDR_EI_CLASS_OFFSET 0x04
#define ELF_HDR_EI_DATA_OFFSET 0x05
@@ -855,13 +858,18 @@ find_elf_data_sec(struct archive_read *a)
while (e_shnum > 0) {
name_offset = (*dec32)(h + sec_tbl_offset);
if (name_offset == data_sym_offset) {
+ uint64_t sel_offset;
+
if (format_64) {
- min_addr = (*dec64)(
+ sel_offset = (*dec64)(
h + sec_tbl_offset + 0x18);
} else {
- min_addr = (*dec32)(
+ sel_offset = (*dec32)(
h + sec_tbl_offset + 0x10);
}
+ if (sel_offset > SSIZE_MAX)
+ break;
+ min_addr = (ssize_t)sel_offset;
break;
}
sec_tbl_offset += e_shentsize;
@@ -967,7 +975,7 @@ archive_read_format_7zip_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Pathname cannot be converted "
- "from %s to current locale.",
+ "from %s to current locale",
archive_string_conversion_charset_name(zip->sconv));
ret = ARCHIVE_WARN;
}
@@ -1573,7 +1581,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
-15 /* Don't check for zlib header */);
if (r != Z_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't initialize zlib stream.");
+ "Couldn't initialize zlib stream");
return (ARCHIVE_FAILED);
}
zip->stream_valid = 1;
@@ -1715,7 +1723,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
if (bytes < 0) {
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,
- "BCJ2 conversion Failed");
+ "BCJ2 conversion failed");
return (ARCHIVE_FAILED);
}
zip->main_stream_bytes_remaining -=
@@ -1769,7 +1777,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
default:
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,
- "Decompression failed(%d)",
+ "Decompression failed (%d)",
r);
return (ARCHIVE_FAILED);
}
@@ -1971,7 +1979,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
bytes = Bcj2_Decode(zip, bcj2_next_out, bcj2_avail_out);
if (bytes < 0) {
archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC, "BCJ2 conversion Failed");
+ ARCHIVE_ERRNO_MISC, "BCJ2 conversion failed");
return (ARCHIVE_FAILED);
}
zip->main_stream_bytes_remaining -=
diff --git a/libarchive/archive_read_support_format_cab.c b/libarchive/archive_read_support_format_cab.c
index 63755ef9e579..bf8ac6b1ca77 100644
--- a/libarchive/archive_read_support_format_cab.c
+++ b/libarchive/archive_read_support_format_cab.c
@@ -383,8 +383,10 @@ archive_read_support_format_cab(struct archive *_a)
NULL,
NULL);
- if (r != ARCHIVE_OK)
+ if (r != ARCHIVE_OK) {
+ archive_wstring_free(&cab->ws);
free(cab);
+ }
return (ARCHIVE_OK);
}
@@ -978,7 +980,7 @@ archive_read_format_cab_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Pathname cannot be converted "
- "from %s to current locale.",
+ "from %s to current locale",
archive_string_conversion_charset_name(sconv));
err = ARCHIVE_WARN;
}
@@ -1024,7 +1026,7 @@ archive_read_format_cab_read_data(struct archive_read *a,
*offset = 0;
archive_clear_error(&a->archive);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Cannot restore this file split in multivolume.");
+ "Cannot restore this file split in multivolume");
return (ARCHIVE_FAILED);
default:
break;
@@ -1173,6 +1175,9 @@ cab_checksum_finish(struct archive_read *a)
l = 4;
if (cab->cfheader.flags & RESERVE_PRESENT)
l += cab->cfheader.cfdata;
+ if (cfdata->memimage == NULL) {
+ return (ARCHIVE_FAILED);
+ }
cfdata->sum_calculated = cab_checksum_cfdata(
cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
if (cfdata->sum_calculated != cfdata->sum) {
@@ -1360,7 +1365,7 @@ cab_read_ahead_cfdata(struct archive_read *a, ssize_t *avail)
return (cab_read_ahead_cfdata_lzx(a, avail));
default: /* Unsupported compression. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported CAB compression : %s",
+ "Unsupported CAB compression: %s",
cab->entry_cffolder->compname);
*avail = ARCHIVE_FAILED;
return (NULL);
@@ -1447,7 +1452,7 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
-15 /* Don't check for zlib header */);
if (r != Z_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize deflate decompression.");
+ "Can't initialize deflate decompression");
*avail = ARCHIVE_FATAL;
return (NULL);
}
@@ -1667,7 +1672,7 @@ cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
cab->entry_cffolder->compdata);
if (r != ARCHIVE_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize LZX decompression.");
+ "Can't initialize LZX decompression");
*avail = ARCHIVE_FATAL;
return (NULL);
}
@@ -1685,6 +1690,13 @@ cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
cab->uncompressed_buffer + cab->xstrm.total_out;
cab->xstrm.avail_out =
cfdata->uncompressed_size - cab->xstrm.total_out;
+
+ if ((size_t)cfdata->uncompressed_size > cab->uncompressed_buffer_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid CFDATA uncompressed size");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
d = __archive_read_ahead(a, 1, &bytes_avail);
if (d == NULL) {
diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
index 526096b39f75..43169f61806d 100644
--- a/libarchive/archive_read_support_format_cpio.c
+++ b/libarchive/archive_read_support_format_cpio.c
@@ -397,7 +397,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname can't be converted from %s to current locale.",
+ "Pathname can't be converted from %s to current locale",
archive_string_conversion_charset_name(sconv));
r = ARCHIVE_WARN;
}
@@ -426,7 +426,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Linkname can't be converted from %s to "
- "current locale.",
+ "current locale",
archive_string_conversion_charset_name(sconv));
r = ARCHIVE_WARN;
}
diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index 1635228d5071..c69fcd272bcd 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -1322,7 +1322,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Pathname cannot be converted "
- "from %s to current locale.",
+ "from %s to current locale",
archive_string_conversion_charset_name(
iso9660->sconv_utf16be));
@@ -1400,7 +1400,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Linkname cannot be converted "
- "from %s to current locale.",
+ "from %s to current locale",
archive_string_conversion_charset_name(
iso9660->sconv_utf16be));
rd_r = ARCHIVE_WARN;
@@ -1663,7 +1663,7 @@ zisofs_read_data(struct archive_read *a,
r = inflateInit(&zisofs->stream);
if (r != Z_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize zisofs decompression.");
+ "Can't initialize zisofs decompression");
return (ARCHIVE_FATAL);
}
zisofs->stream_valid = 1;
@@ -1728,7 +1728,7 @@ zisofs_read_data(struct archive_read *a,
(void)size;/* UNUSED */
(void)offset;/* UNUSED */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "zisofs is not supported on this platform.");
+ "zisofs is not supported on this platform");
return (ARCHIVE_FAILED);
}
@@ -2756,11 +2756,19 @@ parse_rockridge_ZF1(struct file_info *file, const unsigned char *data,
{
if (data[0] == 0x70 && data[1] == 0x7a && data_length == 12) {
- /* paged zlib */
- file->pz = 1;
- file->pz_log2_bs = data[3];
- file->pz_uncompressed_size = archive_le32dec(&data[4]);
- }
+ /* paged zlib */
+ file->pz = 1;
+ file->pz_log2_bs = data[3];
+ if (file->pz_log2_bs < 15 || file->pz_log2_bs > 17) {
+ /* TODO: Return an error here instead of silently
+ * disabling zisofs. That requires propagating an
+ * error return through parse_rockridge() and its
+ * callers. */
+ file->pz = 0;
+ return;
+ }
+ file->pz_uncompressed_size = archive_le32dec(&data[4]);
+ }
}
static void
diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c
index cf6a147abda6..ff6dbb8df1cd 100644
--- a/libarchive/archive_read_support_format_lha.c
+++ b/libarchive/archive_read_support_format_lha.c
@@ -613,7 +613,7 @@ archive_read_format_lha_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Pathname cannot be converted "
- "from %s to Unicode.",
+ "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))
@@ -634,7 +634,7 @@ archive_read_format_lha_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Pathname cannot be converted "
- "from %s to Unicode.",
+ "from %s to Unicode",
archive_string_conversion_charset_name(lha->sconv_fname));
err = ARCHIVE_FATAL;
}
@@ -1101,6 +1101,13 @@ lha_read_file_header_3(struct archive_read *a, struct lha *lha)
header_crc = lha_crc16(0, p, H3_FIXED_SIZE);
__archive_read_consume(a, H3_FIXED_SIZE);
+ /* Reject rediculously large header */
+ if (lha->header_size > 65536) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "LHa header size too large");
+ return (ARCHIVE_FATAL);
+ }
+
/* Read extended headers */
err = lha_read_file_extended_header(a, lha, &header_crc, 4,
lha->header_size - H3_FIXED_SIZE, &extdsize);
diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
index 10c07b05d965..4a5a49ca8136 100644
--- a/libarchive/archive_read_support_format_mtree.c
+++ b/libarchive/archive_read_support_format_mtree.c
@@ -300,7 +300,12 @@ cleanup(struct archive_read *a)
struct mtree_entry *p, *q;
mtree = (struct mtree *)(a->format->data);
-
+
+ /* Close any dangling file descriptor before freeing */
+ if (mtree->fd >= 0) {
+ close(mtree->fd);
+ mtree->fd = -1;
+ }
p = mtree->entries;
while (p != NULL) {
q = p->next;
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
index 9b401c00ba34..0ed2540cd0a8 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -955,7 +955,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to read next header.");
+ "Failed to read next header");
return (ARCHIVE_FATAL);
}
p = h;
@@ -1005,7 +1005,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
archive_entry_set_is_data_encrypted(entry, 1);
rar->has_encrypted_entries = 1;
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "RAR encryption support unavailable.");
+ "RAR encryption support unavailable");
return (ARCHIVE_FATAL);
}
@@ -1141,7 +1141,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported compression method for RAR file.");
+ "Unsupported compression method for RAR file");
ret = ARCHIVE_FATAL;
break;
}
@@ -1432,14 +1432,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
else
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "RAR solid archive support unavailable.");
+ "RAR solid archive support unavailable");
return (ARCHIVE_FATAL);
}
if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to read full header content.");
+ "Failed to read full header content");
return (ARCHIVE_FATAL);
}
@@ -1471,7 +1471,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
archive_entry_set_is_data_encrypted(entry, 1);
rar->has_encrypted_entries = 1;
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "RAR encryption support unavailable.");
+ "RAR encryption support unavailable");
/* Since it is only the data part itself that is encrypted we can at least
extract information about the currently processed entry and don't need
to return ARCHIVE_FATAL here. */
@@ -1503,7 +1503,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
if (rar->packed_size < 0 || rar->unp_size < 0)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid sizes specified.");
+ "Invalid sizes specified");
return (ARCHIVE_FATAL);
}
@@ -1516,19 +1516,19 @@ read_header(struct archive_read *a, struct archive_entry *entry,
size_t distance = p - (const char *)h;
if (rar->packed_size > INT64_MAX - header_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Extended header size too large.");
+ "Extended header size too large");
return (ARCHIVE_FATAL);
}
header_size += rar->packed_size;
if ((uintmax_t)header_size > SIZE_MAX) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unable to read extended header data.");
+ "Unable to read extended header data");
return (ARCHIVE_FATAL);
}
/* Make sure we have the extended data. */
if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to read extended header data.");
+ "Failed to read extended header data");
return (ARCHIVE_FATAL);
}
p = h;
@@ -1547,7 +1547,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
newptr = realloc(rar->filename, newsize);
if (newptr == NULL) {
archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory.");
+ "Couldn't allocate memory");
return (ARCHIVE_FATAL);
}
rar->filename = newptr;
@@ -1701,7 +1701,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
newsize = sizeof(*rar->dbo) * (rar->nodes + 1);
if ((newdbo = realloc(rar->dbo, newsize)) == NULL)
{
- archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
+ archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory");
return (ARCHIVE_FATAL);
}
rar->dbo = newdbo;
@@ -1715,7 +1715,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
if (rar->packed_size > INT64_MAX - a->filter->position)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unable to store offsets.");
+ "Unable to store offsets");
return (ARCHIVE_FATAL);
}
rar->dbo[rar->cursor].start_offset = a->filter->position;
@@ -1734,7 +1734,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
newsize = filename_size + 1;
if ((newptr = realloc(rar->filename_save, newsize)) == NULL)
{
- archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
+ archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory");
return (ARCHIVE_FATAL);
}
rar->filename_save = newptr;
@@ -1745,7 +1745,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
free(rar->dbo);
if ((rar->dbo = calloc(1, sizeof(*rar->dbo))) == NULL)
{
- archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
+ archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory");
return (ARCHIVE_FATAL);
}
rar->dbo[0].header_size = header_size;
@@ -1776,7 +1776,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
__archive_read_consume(a, header_size - 7);
if (rar->packed_size > INT64_MAX - a->filter->position) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unable to store offsets.");
+ "Unable to store offsets");
return (ARCHIVE_FATAL);
}
rar->dbo[0].start_offset = a->filter->position;
@@ -1848,7 +1848,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted from %s to current locale.",
+ "Pathname cannot be converted from %s to current locale",
archive_string_conversion_charset_name(fn_sconv));
ret = (ARCHIVE_WARN);
}
@@ -1979,13 +1979,13 @@ read_symlink_stored(struct archive_read *a, struct archive_entry *entry,
if ((uintmax_t)rar->packed_size > SIZE_MAX)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unable to read link.");
+ "Unable to read link");
return (ARCHIVE_FATAL);
}
if ((h = rar_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to read link.");
+ "Failed to read link");
return (ARCHIVE_FATAL);
}
p = h;
@@ -2000,7 +2000,7 @@ read_symlink_stored(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "link cannot be converted from %s to current locale.",
+ "link cannot be converted from %s to current locale",
archive_string_conversion_charset_name(sconv));
ret = (ARCHIVE_WARN);
}
@@ -2201,7 +2201,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
case 3:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Parsing filters is unsupported.");
+ "Parsing filters is unsupported");
return (ARCHIVE_FAILED);
case 4:
@@ -2473,7 +2473,7 @@ parse_codes(struct archive_read *a)
free(precode.tree);
free(precode.table);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Internal error extracting RAR file.");
+ "Internal error extracting RAR file");
return (ARCHIVE_FATAL);
}
@@ -2548,7 +2548,8 @@ parse_codes(struct archive_read *a)
return (r);
}
- if (!rar->dictionary_size || !rar->lzss.window)
+ if (!rar->dictionary_size || !rar->lzss.window ||
+ (unsigned int)(rar->lzss.mask + 1) < rar->dictionary_size)
{
/* Seems as though dictionary sizes are not used. Even so, minimize
* memory usage as much as possible.
@@ -2562,13 +2563,13 @@ parse_codes(struct archive_read *a)
new_size = rar_fls((unsigned int)rar->unp_size) << 1;
if (new_size == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Zero window size is invalid.");
+ "Zero window size is invalid");
return (ARCHIVE_FATAL);
}
new_window = realloc(rar->lzss.window, new_size);
if (new_window == NULL) {
archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for uncompressed data.");
+ "Unable to allocate memory for uncompressed data");
return (ARCHIVE_FATAL);
}
rar->lzss.window = (unsigned char *)new_window;
@@ -2686,7 +2687,7 @@ create_code(struct archive_read *a, struct huffman_code *code,
code->numallocatedentries = 0;
if (new_node(code) < 0) {
archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
+ "Unable to allocate memory for node data");
return (ARCHIVE_FATAL);
}
code->numentries = 1;
@@ -2769,12 +2770,12 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
if ((repeatnode = new_node(code)) < 0) {
archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
+ "Unable to allocate memory for node data");
return (ARCHIVE_FATAL);
}
if ((nextnode = new_node(code)) < 0) {
archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
+ "Unable to allocate memory for node data");
return (ARCHIVE_FATAL);
}
@@ -2794,7 +2795,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
{
if (new_node(code) < 0) {
archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
+ "Unable to allocate memory for node data");
return (ARCHIVE_FATAL);
}
code->tree[lastnode].branches[bit] = code->numentries++;
@@ -2863,13 +2864,13 @@ make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
if (!code->tree)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Huffman tree was not created.");
+ "Huffman tree was not created");
return (ARCHIVE_FATAL);
}
if (node < 0 || node >= code->numentries)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid location to Huffman tree specified.");
+ "Invalid location to Huffman tree specified");
return (ARCHIVE_FATAL);
}
@@ -3149,6 +3150,11 @@ copy_from_lzss_window(struct archive_read *a, uint8_t *buffer,
windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
firstpart = lzss_size(&rar->lzss) - windowoffs;
+ if (length > lzss_size(&rar->lzss)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file data");
+ return (ARCHIVE_FATAL);
+ }
if (firstpart < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad RAR file data");
@@ -3180,7 +3186,7 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
{
archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for uncompressed data.");
+ "Unable to allocate memory for uncompressed data");
return (ARCHIVE_FATAL);
}
}
@@ -3315,7 +3321,8 @@ parse_filter(struct archive_read *a, const uint8_t *bytes, uint16_t length, uint
else
blocklength = prog ? prog->oldfilterlength : 0;
- if (blocklength > rar->dictionary_size)
+ if (blocklength > rar->dictionary_size ||
+ blocklength > (uint32_t)(rar->lzss.mask + 1))
return 0;
registers[3] = PROGRAM_SYSTEM_GLOBAL_ADDRESS;
diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c
index 17e501e02e9f..63dd97b3008a 100644
--- a/libarchive/archive_read_support_format_rar5.c
+++ b/libarchive/archive_read_support_format_rar5.c
@@ -375,6 +375,7 @@ static int rar5_read_data_skip(struct archive_read *a);
static int push_data_ready(struct archive_read* a, struct rar5* rar,
const uint8_t* buf, size_t size, int64_t offset);
static void clear_data_ready_stack(struct rar5* rar);
+static void rar5_deinit(struct rar5* rar);
/* CDE_xxx = Circular Double Ended (Queue) return values. */
enum CDE_RETURN_VALUES {
@@ -429,8 +430,7 @@ static int cdeque_front(struct cdeque* d, void** value) {
return CDE_OUT_OF_BOUNDS;
}
-/* Pushes a new element into the end of this circular deque object. If current
- * size will exceed capacity, the oldest element will be overwritten. */
+/* Pushes a new element into the end of this circular deque object. */
static int cdeque_push_back(struct cdeque* d, void* item) {
if(d == NULL)
return CDE_PARAM;
@@ -554,7 +554,11 @@ static struct filter_info* add_new_filter(struct rar5* rar) {
return NULL;
}
- cdeque_push_back(&rar->cstate.filters, cdeque_filter(f));
+ if (CDE_OK != cdeque_push_back(&rar->cstate.filters, cdeque_filter(f))) {
+ free(f);
+ return NULL;
+ }
+
return f;
}
@@ -671,7 +675,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
rar->cstate.filtered_buf = malloc(flt->block_length);
if(!rar->cstate.filtered_buf) {
archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for filter data.");
+ "Can't allocate memory for filter data");
return ARCHIVE_FATAL;
}
@@ -1847,7 +1851,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
rar->cstate.window_buf == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Declared solid file, but no window buffer "
- "initialized yet.");
+ "initialized yet");
return ARCHIVE_FATAL;
}
@@ -1857,7 +1861,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
(rar->file.dir == 0 && window_size == 0))
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Declared dictionary size is not supported.");
+ "Declared dictionary size is not supported");
return ARCHIVE_FATAL;
}
@@ -1869,7 +1873,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
{
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. ");
+ "the window size used in previous solid file");
return ARCHIVE_FATAL;
}
}
@@ -1895,7 +1899,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
if(!new_window_buf) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Not enough memory when trying to realloc the window "
- "buffer.");
+ "buffer");
return ARCHIVE_FATAL;
}
@@ -3040,7 +3044,9 @@ static int parse_filter(struct archive_read* ar, const uint8_t* p) {
if(block_length < 4 ||
block_length > 0x400000 ||
filter_type > FILTER_ARM ||
- !is_valid_filter_block_start(rar, block_start))
+ !is_valid_filter_block_start(rar, block_start) ||
+ (rar->cstate.window_size > 0 &&
+ (ssize_t)block_length > rar->cstate.window_size >> 1))
{
archive_set_error(&ar->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid filter encountered");
@@ -3051,7 +3057,7 @@ static int parse_filter(struct archive_read* ar, const uint8_t* p) {
filt = add_new_filter(rar);
if(filt == NULL) {
archive_set_error(&ar->archive, ENOMEM,
- "Can't allocate memory for a filter descriptor.");
+ "Can't allocate memory for a filter descriptor");
return ARCHIVE_FATAL;
}
@@ -3500,7 +3506,7 @@ static int merge_block(struct archive_read* a, ssize_t block_size,
rar->vol.push_buf = malloc(block_size + 8);
if(!rar->vol.push_buf) {
archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for a merge block buffer.");
+ "Can't allocate memory for a merge block buffer");
return ARCHIVE_FATAL;
}
@@ -3533,7 +3539,7 @@ static int merge_block(struct archive_read* a, ssize_t block_size,
if(partial_offset + cur_block_size > block_size) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_PROGRAMMER,
- "Consumed too much data when merging blocks.");
+ "Consumed too much data when merging blocks");
return ARCHIVE_FATAL;
}
@@ -3802,7 +3808,7 @@ static int push_data_ready(struct archive_read* a, struct rar5* rar,
* as an internal error. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Error: premature end of data_ready stack");
+ "Premature end of data_ready stack");
return ARCHIVE_FATAL;
}
@@ -4328,7 +4334,7 @@ static int rar5_cleanup(struct archive_read *a) {
free(rar->vol.push_buf);
free_filters(rar);
- cdeque_free(&rar->cstate.filters);
+ rar5_deinit(rar);
free(rar);
a->format->data = NULL;
@@ -4353,6 +4359,7 @@ static int rar5_has_encrypted_entries(struct archive_read *_a) {
return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
}
+/* Must match deallocations in rar5_deinit */
static int rar5_init(struct rar5* rar) {
memset(rar, 0, sizeof(struct rar5));
@@ -4368,6 +4375,11 @@ static int rar5_init(struct rar5* rar) {
return ARCHIVE_OK;
}
+/* Must match allocations in rar5_init */
+static void rar5_deinit(struct rar5* rar) {
+ cdeque_free(&rar->cstate.filters);
+}
+
int archive_read_support_format_rar5(struct archive *_a) {
struct archive_read* ar;
int ret;
@@ -4404,8 +4416,9 @@ int archive_read_support_format_rar5(struct archive *_a) {
rar5_has_encrypted_entries);
if(ret != ARCHIVE_OK) {
- (void) rar5_cleanup(ar);
+ rar5_deinit(rar);
+ free(rar);
}
- return ret;
+ return ARCHIVE_OK;
}
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index 98f7d699570a..2979492767ed 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -1202,7 +1202,7 @@ set_conversion_failed_error(struct archive_read *a,
return (ARCHIVE_FATAL);
}
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "%s can't be converted from %s to current locale.",
+ "%s can't be converted from %s to current locale",
name, archive_string_conversion_charset_name(sconv));
return (ARCHIVE_WARN);
}
@@ -2255,12 +2255,12 @@ pax_attribute_SCHILY_acl(struct archive_read *a, struct tar *tar,
if (r != ARCHIVE_OK) {
if (r == ARCHIVE_FATAL) {
archive_set_error(&a->archive, ENOMEM,
- "%s %s", "Can't allocate memory for ",
+ "%s %s", "Can't allocate memory for",
errstr);
return (r);
}
archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC, "%s %s", "Parse error: ", errstr);
+ ARCHIVE_ERRNO_MISC, "%s %s", "Parse error:", errstr);
}
return (r);
}
diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c
index 36b5ab3ae04c..874501fc0782 100644
--- a/libarchive/archive_read_support_format_xar.c
+++ b/libarchive/archive_read_support_format_xar.c
@@ -733,7 +733,7 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
}
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Gname cannot be converted from %s to current locale.",
+ "Gname cannot be converted from %s to current locale",
archive_string_conversion_charset_name(xar->sconv));
r = ARCHIVE_WARN;
}
@@ -748,7 +748,7 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
}
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Uname cannot be converted from %s to current locale.",
+ "Uname cannot be converted from %s to current locale",
archive_string_conversion_charset_name(xar->sconv));
r = ARCHIVE_WARN;
}
@@ -762,7 +762,7 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
}
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted from %s to current locale.",
+ "Pathname cannot be converted from %s to current locale",
archive_string_conversion_charset_name(xar->sconv));
r = ARCHIVE_WARN;
}
@@ -778,7 +778,7 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
}
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Linkname cannot be converted from %s to current locale.",
+ "Linkname cannot be converted from %s to current locale",
archive_string_conversion_charset_name(xar->sconv));
r = ARCHIVE_WARN;
}
@@ -1008,7 +1008,7 @@ move_reading_point(struct archive_read *a, uint64_t offset)
if (pos == ARCHIVE_FAILED) {
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,
- "Cannot seek.");
+ "Cannot seek");
return (ARCHIVE_FAILED);
}
xar->offset = pos;
@@ -1476,7 +1476,7 @@ decompression_init(struct archive_read *a, enum enctype encoding)
r = inflateInit(&(xar->stream));
if (r != Z_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't initialize zlib stream.");
+ "Couldn't initialize zlib stream");
return (ARCHIVE_FATAL);
}
xar->stream_valid = 1;
@@ -1691,7 +1691,7 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
default:
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,
- "%s decompression failed(%d)",
+ "%s decompression failed (%d)",
(xar->entry_encoding == XZ)?"xz":"lzma",
r);
return (ARCHIVE_FATAL);
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
index 0c86ce935e26..00796b288a48 100644
--- a/libarchive/archive_read_support_format_zip.c
+++ b/libarchive/archive_read_support_format_zip.c
@@ -1008,7 +1008,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Pathname cannot be converted "
- "from %s to current locale.",
+ "from %s to current locale",
archive_string_conversion_charset_name(sconv));
ret = ARCHIVE_WARN;
}
@@ -1256,7 +1256,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Symlink cannot be converted "
- "from %s to current locale.",
+ "from %s to current locale",
archive_string_conversion_charset_name(
sconv));
ret = ARCHIVE_WARN;
@@ -1726,7 +1726,7 @@ zipx_xz_init(struct archive_read *a, struct zip *zip)
r = lzma_stream_decoder(&zip->zipx_lzma_stream, UINT64_MAX, 0);
if (r != LZMA_OK) {
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "xz initialization failed(%d)",
+ "xz initialization failed (%d)",
r);
return (ARCHIVE_FAILED);
@@ -1778,7 +1778,7 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
r = lzma_alone_decoder(&zip->zipx_lzma_stream, UINT64_MAX);
if (r != LZMA_OK) {
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "lzma initialization failed(%d)", r);
+ "lzma initialization failed (%d)", r);
return (ARCHIVE_FAILED);
}
@@ -1921,7 +1921,7 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
switch(lz_ret) {
case LZMA_DATA_ERROR:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "xz data error (error %d)", (int) lz_ret);
+ "xz data error (%d)", (int) lz_ret);
return (ARCHIVE_FATAL);
case LZMA_NO_CHECK:
@@ -1930,7 +1930,7 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "xz unknown error %d", (int) lz_ret);
+ "xz unknown error (%d)", (int) lz_ret);
return (ARCHIVE_FATAL);
case LZMA_STREAM_END:
@@ -2018,7 +2018,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
switch(lz_ret) {
case LZMA_DATA_ERROR:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "lzma data error (error %d)", (int) lz_ret);
+ "lzma data error (%d)", (int) lz_ret);
return (ARCHIVE_FATAL);
/* This case is optional in lzma alone format. It can happen,
@@ -2041,7 +2041,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "lzma unknown error %d", (int) lz_ret);
+ "lzma unknown error (%d)", (int) lz_ret);
return (ARCHIVE_FATAL);
}
@@ -2261,7 +2261,7 @@ zipx_bzip2_init(struct archive_read *a, struct zip *zip)
r = BZ2_bzDecompressInit(&zip->bzstream, 0, 1);
if(r != BZ_OK) {
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "bzip2 initialization failed(%d)",
+ "bzip2 initialization failed (%d)",
r);
return ARCHIVE_FAILED;
@@ -2527,7 +2527,7 @@ zip_deflate_init(struct archive_read *a, struct zip *zip)
-15 /* Don't check for zlib header */);
if (r != Z_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize ZIP decompression.");
+ "Can't initialize ZIP decompression");
return (ARCHIVE_FATAL);
}
/* Stream structure has been set up. */
@@ -3193,7 +3193,7 @@ archive_read_format_zip_read_data(struct archive_read *a,
!= (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZIP uncompressed data is wrong size "
- "(read %jd, expected %jd)\n",
+ "(read %jd, expected %jd)",
(intmax_t)zip->entry_uncompressed_bytes_read,
(intmax_t)zip->entry->uncompressed_size);
return (ARCHIVE_FAILED);
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
index a776dc85c688..c6ae8968d54f 100644
--- a/libarchive/archive_string.c
+++ b/libarchive/archive_string.c
@@ -772,7 +772,7 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as,
int r;
defchar_used = 0;
- if (to_cp == CP_UTF8 || sc == NULL)
+ if (to_cp == CP_UTF8)
dp = NULL;
else
dp = &defchar_used;
@@ -1713,7 +1713,7 @@ get_sconv_object(struct archive *a, const char *fc, const char *tc, int flag)
if (a != NULL) {
#if HAVE_ICONV
archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "iconv_open failed : Cannot handle ``%s''",
+ "iconv_open failed: Cannot handle ``%s''",
(flag & SCONV_TO_CHARSET)?tc:fc);
#else
archive_set_error(a, ARCHIVE_ERRNO_MISC,
@@ -1873,6 +1873,9 @@ archive_string_conversion_free(struct archive *a)
const char *
archive_string_conversion_charset_name(struct archive_string_conv *sc)
{
+ if (sc == NULL) {
+ return "current locale";
+ }
if (sc->flag & SCONV_TO_CHARSET)
return (sc->to_charset);
else
@@ -4123,7 +4126,12 @@ archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
* character-set. */
if ((aes->aes_set & AES_SET_MBS) == 0) {
const char *pm; /* unused */
- archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
+ if (archive_mstring_get_mbs(a, aes, &pm) != 0) {
+ /* We have another form, but failed to convert it to
+ * the native locale. Transitively, we've failed to
+ * convert it to the specified character set. */
+ ret = -1;
+ }
}
/* If we already have an MBS form, use it to be translated to
* specified character-set. */
@@ -4141,6 +4149,8 @@ archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
if (length != NULL)
*length = aes->aes_mbs_in_locale.length;
} else {
+ /* Either we have no string in any form,
+ * or conversion failed and set 'ret != 0'. */
*p = NULL;
if (length != NULL)
*length = 0;
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
index e1ce5d57288d..14dc7339ec5a 100644
--- a/libarchive/archive_write.c
+++ b/libarchive/archive_write.c
@@ -742,7 +742,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
if (a->format_write_header == NULL) {
archive_set_error(&(a->archive), -1,
- "Format must be set before you can write to an archive.");
+ "Format must be set before you can write to an archive");
a->archive.state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
diff --git a/libarchive/archive_write_add_filter_b64encode.c b/libarchive/archive_write_add_filter_b64encode.c
index dbedf9d305c3..d2c4742d2ef6 100644
--- a/libarchive/archive_write_add_filter_b64encode.c
+++ b/libarchive/archive_write_add_filter_b64encode.c
@@ -28,6 +28,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -116,12 +119,20 @@ archive_filter_b64encode_options(struct archive_write_filter *f, const char *key
struct private_b64encode *state = (struct private_b64encode *)f->data;
if (strcmp(key, "mode") == 0) {
+ int64_t val;
+
if (value == NULL) {
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
"mode option requires octal digits");
return (ARCHIVE_FAILED);
}
- state->mode = (int)atol8(value, strlen(value)) & 0777;
+ val = atol8(value, strlen(value));
+ if (val < 0 || val > INT_MAX) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "invalid mode option");
+ return (ARCHIVE_FAILED);
+ }
+ state->mode = (int)val & 0777;
return (ARCHIVE_OK);
} else if (strcmp(key, "name") == 0) {
if (value == NULL) {
@@ -286,14 +297,19 @@ atol8(const char *p, size_t char_cnt)
{
int64_t l;
int digit;
-
+
+ if (char_cnt == 0)
+ return (-1);
+
l = 0;
while (char_cnt-- > 0) {
if (*p >= '0' && *p <= '7')
digit = *p - '0';
else
- break;
+ return (-1);
p++;
+ if (l > (INT64_MAX >> 3))
+ return (-1);
l <<= 3;
l |= digit;
}
diff --git a/libarchive/archive_write_add_filter_bzip2.c b/libarchive/archive_write_add_filter_bzip2.c
index 2434528d5133..94b342d41b74 100644
--- a/libarchive/archive_write_add_filter_bzip2.c
+++ b/libarchive/archive_write_add_filter_bzip2.c
@@ -127,8 +127,11 @@ archive_compressor_bzip2_options(struct archive_write_filter *f,
if (strcmp(key, "compression-level") == 0) {
if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
+ value[1] != '\0') {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level invalid");
+ return (ARCHIVE_FAILED);
+ }
data->compression_level = value[0] - '0';
/* Make '0' be a synonym for '1'. */
/* This way, bzip2 compressor supports the same 0..9
diff --git a/libarchive/archive_write_add_filter_gzip.c b/libarchive/archive_write_add_filter_gzip.c
index b09e669b753d..0a2f22408bad 100644
--- a/libarchive/archive_write_add_filter_gzip.c
+++ b/libarchive/archive_write_add_filter_gzip.c
@@ -160,8 +160,11 @@ archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
if (strcmp(key, "compression-level") == 0) {
if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
+ value[1] != '\0') {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level invalid");
+ return (ARCHIVE_FAILED);
+ }
data->compression_level = value[0] - '0';
return (ARCHIVE_OK);
}
@@ -172,8 +175,11 @@ archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
if (strcmp(key, "original-filename") == 0) {
free((void*)data->original_filename);
data->original_filename = NULL;
- if (value)
+ if (value) {
data->original_filename = strdup(value);
+ if (data->original_filename == NULL)
+ return (ARCHIVE_WARN);
+ }
return (ARCHIVE_OK);
}
diff --git a/libarchive/archive_write_add_filter_lrzip.c b/libarchive/archive_write_add_filter_lrzip.c
index fe974c93d5d0..cda34dc738d3 100644
--- a/libarchive/archive_write_add_filter_lrzip.c
+++ b/libarchive/archive_write_add_filter_lrzip.c
@@ -97,8 +97,11 @@ archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
struct write_lrzip *data = (struct write_lrzip *)f->data;
if (strcmp(key, "compression") == 0) {
- if (value == NULL)
- return (ARCHIVE_WARN);
+ if (value == NULL) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression option requires an argument");
+ return (ARCHIVE_FAILED);
+ }
else if (strcmp(value, "bzip2") == 0)
data->compression = bzip2;
else if (strcmp(value, "gzip") == 0)
@@ -109,13 +112,19 @@ archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
data->compression = none;
else if (strcmp(value, "zpaq") == 0)
data->compression = zpaq;
- else
- return (ARCHIVE_WARN);
+ else {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression invalid");
+ return (ARCHIVE_FAILED);
+ }
return (ARCHIVE_OK);
} else if (strcmp(key, "compression-level") == 0) {
if (value == NULL || !(value[0] >= '1' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
+ value[1] != '\0') {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level invalid");
+ return (ARCHIVE_FAILED);
+ }
data->compression_level = value[0] - '0';
return (ARCHIVE_OK);
}
diff --git a/libarchive/archive_write_add_filter_lz4.c b/libarchive/archive_write_add_filter_lz4.c
index 24061a169521..efc408e2a3f8 100644
--- a/libarchive/archive_write_add_filter_lz4.c
+++ b/libarchive/archive_write_add_filter_lz4.c
@@ -160,8 +160,11 @@ archive_filter_lz4_options(struct archive_write_filter *f,
if (strcmp(key, "compression-level") == 0) {
int val;
if (value == NULL || !((val = value[0] - '0') >= 1 && val <= 9) ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
+ value[1] != '\0') {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level invalid");
+ return (ARCHIVE_FAILED);
+ }
#ifndef HAVE_LZ4HC_H
if(val >= 3)
@@ -184,8 +187,11 @@ archive_filter_lz4_options(struct archive_write_filter *f,
}
if (strcmp(key, "block-size") == 0) {
if (value == NULL || !(value[0] >= '4' && value[0] <= '7') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
+ value[1] != '\0') {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "block-size invalid");
+ return (ARCHIVE_FAILED);
+ }
data->block_maximum_size = value[0] - '0';
return (ARCHIVE_OK);
}
diff --git a/libarchive/archive_write_add_filter_lzop.c b/libarchive/archive_write_add_filter_lzop.c
index 8580e58844af..42d62db63a13 100644
--- a/libarchive/archive_write_add_filter_lzop.c
+++ b/libarchive/archive_write_add_filter_lzop.c
@@ -211,8 +211,11 @@ archive_write_lzop_options(struct archive_write_filter *f, const char *key,
if (strcmp(key, "compression-level") == 0) {
if (value == NULL || !(value[0] >= '1' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
+ value[1] != '\0') {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level invalid");
+ return (ARCHIVE_FAILED);
+ }
data->compression_level = value[0] - '0';
return (ARCHIVE_OK);
}
diff --git a/libarchive/archive_write_add_filter_uuencode.c b/libarchive/archive_write_add_filter_uuencode.c
index 99c7a2cb7a7e..d25236fa9b26 100644
--- a/libarchive/archive_write_add_filter_uuencode.c
+++ b/libarchive/archive_write_add_filter_uuencode.c
@@ -28,6 +28,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -105,12 +108,20 @@ archive_filter_uuencode_options(struct archive_write_filter *f, const char *key,
struct private_uuencode *state = (struct private_uuencode *)f->data;
if (strcmp(key, "mode") == 0) {
+ int64_t val;
+
if (value == NULL) {
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
"mode option requires octal digits");
return (ARCHIVE_FAILED);
}
- state->mode = (int)atol8(value, strlen(value)) & 0777;
+ val = atol8(value, strlen(value));
+ if (val < 0 || val > INT_MAX) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "invalid mode option");
+ return (ARCHIVE_FAILED);
+ }
+ state->mode = (int)val & 0777;
return (ARCHIVE_OK);
} else if (strcmp(key, "name") == 0) {
if (value == NULL) {
@@ -277,14 +288,19 @@ atol8(const char *p, size_t char_cnt)
{
int64_t l;
int digit;
-
+
+ if (char_cnt == 0)
+ return (-1);
+
l = 0;
while (char_cnt-- > 0) {
if (*p >= '0' && *p <= '7')
digit = *p - '0';
else
- break;
+ return (-1);
p++;
+ if (l > (INT64_MAX >> 3))
+ return (-1);
l <<= 3;
l |= digit;
}
diff --git a/libarchive/archive_write_add_filter_xz.c b/libarchive/archive_write_add_filter_xz.c
index 098f0c95570b..56cf02070754 100644
--- a/libarchive/archive_write_add_filter_xz.c
+++ b/libarchive/archive_write_add_filter_xz.c
@@ -29,6 +29,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -376,23 +379,33 @@ archive_compressor_xz_options(struct archive_write_filter *f,
if (strcmp(key, "compression-level") == 0) {
if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
+ value[1] != '\0') {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level invalid");
+ return (ARCHIVE_FAILED);
+ }
data->compression_level = value[0] - '0';
if (data->compression_level > 9)
data->compression_level = 9;
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
char *endptr;
+ unsigned long val;
- if (value == NULL)
- return (ARCHIVE_WARN);
+ if (value == NULL) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "threads option requires an argument");
+ return (ARCHIVE_FAILED);
+ }
errno = 0;
- data->threads = (int)strtoul(value, &endptr, 10);
- if (errno != 0 || *endptr != '\0') {
+ val = strtoul(value, &endptr, 10);
+ if (errno != 0 || *endptr != '\0' || val > (unsigned)INT_MAX) {
data->threads = 1;
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "threads invalid");
+ return (ARCHIVE_FAILED);
}
+ data->threads = (int)val;
if (data->threads == 0) {
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
data->threads = lzma_cputhreads();
diff --git a/libarchive/archive_write_add_filter_zstd.c b/libarchive/archive_write_add_filter_zstd.c
index d4752c247157..7149abb2b8a8 100644
--- a/libarchive/archive_write_add_filter_zstd.c
+++ b/libarchive/archive_write_add_filter_zstd.c
@@ -245,7 +245,9 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
if (strcmp(key, "compression-level") == 0) {
intmax_t level;
if (string_to_number(value, &level) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level invalid");
+ return (ARCHIVE_FAILED);
}
/* If we don't have the library, hard-code the max level */
int minimum = CLEVEL_MIN;
@@ -263,14 +265,18 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
}
#endif
if (level < minimum || level > maximum) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "compression-level out of range");
+ return (ARCHIVE_FAILED);
}
data->compression_level = (int)level;
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
intmax_t threads;
if (string_to_number(value, &threads) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "threads invalid");
+ return (ARCHIVE_FAILED);
}
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
@@ -286,7 +292,9 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
}
#endif
if (threads < 0 || threads > INT_MAX) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "threads out of rnage");
+ return (ARCHIVE_FAILED);
}
data->threads = (int)threads;
return (ARCHIVE_OK);
@@ -296,26 +304,34 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
return (ARCHIVE_OK);
} else if (strcmp(key, "min-frame-in") == 0) {
if (string_to_size(value, &data->min_frame_in) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "min-frame-in invalid");
+ return (ARCHIVE_FAILED);
}
return (ARCHIVE_OK);
} else if (strcmp(key, "min-frame-out") == 0 ||
strcmp(key, "min-frame-size") == 0) {
if (string_to_size(value, &data->min_frame_out) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "min-frame-out invalid");
+ return (ARCHIVE_FAILED);
}
return (ARCHIVE_OK);
} else if (strcmp(key, "max-frame-in") == 0 ||
strcmp(key, "max-frame-size") == 0) {
if (string_to_size(value, &data->max_frame_in) != ARCHIVE_OK ||
data->max_frame_in < 1024) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "max-frame-size invalid");
+ return (ARCHIVE_FAILED);
}
return (ARCHIVE_OK);
} else if (strcmp(key, "max-frame-out") == 0) {
if (string_to_size(value, &data->max_frame_out) != ARCHIVE_OK ||
data->max_frame_out < 1024) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "max-frame-out invalid");
+ return (ARCHIVE_FAILED);
}
return (ARCHIVE_OK);
#endif
@@ -323,22 +339,30 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
else if (strcmp(key, "long") == 0) {
intmax_t long_distance;
if (string_to_number(value, &long_distance) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "long invalid");
+ return (ARCHIVE_FAILED);
}
#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream && ZSTD_VERSION_NUMBER >= MINVER_LONG
ZSTD_bounds bounds = ZSTD_cParam_getBounds(ZSTD_c_windowLog);
if (ZSTD_isError(bounds.error)) {
int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
- if (((int)long_distance) < 10 || (int)long_distance > max_distance)
- return (ARCHIVE_WARN);
+ if (((int)long_distance) < 10 || (int)long_distance > max_distance) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "long out of range");
+ return (ARCHIVE_FAILED);
+ }
} else {
- if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound)
- return (ARCHIVE_WARN);
+ if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "long out of range");
+ return (ARCHIVE_FAILED);
+ }
}
#else
int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
if (((int)long_distance) < 10 || (int)long_distance > max_distance)
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
#endif
data->long_distance = (int)long_distance;
return (ARCHIVE_OK);
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
index d1f043d24437..7b90fc25fa54 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -1975,7 +1975,7 @@ archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id)
return (a->lookup_gid)(a->lookup_gid_data, name, id);
return (id);
}
-
+
int64_t
archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id)
{
@@ -2119,7 +2119,7 @@ restore_entry(struct archive_write_disk *a)
if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) {
archive_set_error(&a->archive, en,
- "Hard-link target '%s' does not exist.",
+ "Hard-link target '%s' does not exist",
archive_entry_hardlink(a->entry));
return (ARCHIVE_FAILED);
}
@@ -2406,7 +2406,7 @@ create_filesystem_object(struct archive_write_disk *a)
*/
mode = final_mode & 0777 & ~a->user_umask;
- /*
+ /*
* Always create writable such that [f]setxattr() works if we're not
* root.
*/
@@ -3024,7 +3024,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
/*
* We are not the last element and we want to
* follow symlinks if they are a directory.
- *
+ *
* This is needed to extract hardlinks over
* symlinks.
*/
@@ -3435,7 +3435,7 @@ create_dir(struct archive_write_disk *a, char *path)
le = new_fixup(a, path);
if (le == NULL)
return (ARCHIVE_FATAL);
- le->fixup |=TODO_MODE_BASE;
+ le->fixup |= TODO_MODE_BASE;
le->mode = mode_final;
}
return (ARCHIVE_OK);
@@ -3447,8 +3447,17 @@ create_dir(struct archive_write_disk *a, char *path)
* don't add it to the fixup list here, as it's already been
* added.
*/
- if (la_stat(path, &st) == 0 && S_ISDIR(st.st_mode))
- return (ARCHIVE_OK);
+ if (errno == EEXIST) {
+ if (la_stat(path, &st) == 0) {
+ if (S_ISDIR(st.st_mode))
+ return (ARCHIVE_OK);
+ /* path exists but is not a directory */
+ errno = ENOTDIR;
+ } else {
+ /* restore original errno */
+ errno = EEXIST;
+ }
+ }
archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
path);
@@ -4010,7 +4019,7 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
#elif defined(HAVE_CHFLAGS)
if (S_ISLNK(a->st.st_mode)) {
archive_set_error(&a->archive, errno,
- "Can't set file flags on symlink.");
+ "Can't set file flags on symlink");
return (ARCHIVE_WARN);
}
if (chflags(name, a->st.st_flags) == 0)
@@ -4569,7 +4578,7 @@ set_xattrs(struct archive_write_disk *a)
} else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot restore extended "
- "attributes on this file system.");
+ "attributes on this file system");
}
archive_string_free(&errlist);
@@ -4671,7 +4680,7 @@ set_xattrs(struct archive_write_disk *a)
} else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot restore extended "
- "attributes on this file system.");
+ "attributes on this file system");
}
archive_string_free(&errlist);
@@ -4767,4 +4776,3 @@ static void close_file_descriptor(struct archive_write_disk* a)
#endif /* !_WIN32 || __CYGWIN__ */
-
diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
index d4f6f1820e96..8a970de1ad04 100644
--- a/libarchive/archive_write_disk_windows.c
+++ b/libarchive/archive_write_disk_windows.c
@@ -1516,7 +1516,7 @@ restore_entry(struct archive_write_disk *a)
if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) {
archive_set_error(&a->archive, en,
- "Hard-link target '%s' does not exist.",
+ "Hard-link target '%s' does not exist",
archive_entry_hardlink(a->entry));
return (ARCHIVE_FAILED);
}
diff --git a/libarchive/archive_write_set_format_7zip.c b/libarchive/archive_write_set_format_7zip.c
index ebdb16e9022a..1bbd24d632e7 100644
--- a/libarchive/archive_write_set_format_7zip.c
+++ b/libarchive/archive_write_set_format_7zip.c
@@ -28,6 +28,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -333,6 +336,7 @@ string_to_number(const char *string, intmax_t *numberp)
if (string == NULL || *string == '\0')
return (ARCHIVE_WARN);
+ errno = 0;
*numberp = strtoimax(string, &end, 10);
if (end == string || *end != '\0' || errno == EOVERFLOW) {
*numberp = 0;
@@ -487,8 +491,9 @@ _7z_options(struct archive_write *a, const char *key, const char *value)
}
char *end = NULL;
+ errno = 0;
long lvl = strtol(value, &end, 10);
- if (end == NULL || *end != '\0') {
+ if (errno != 0 || end == NULL || *end != '\0') {
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
"parsing compression-level option value failed `%s'", value);
return (ARCHIVE_FAILED);
@@ -525,7 +530,7 @@ _7z_options(struct archive_write *a, const char *key, const char *value)
if (string_to_number(value, &threads) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
- if (threads < 0) {
+ if (threads < 0 || threads > INT_MAX) {
return (ARCHIVE_WARN);
}
if (threads == 0) {
diff --git a/libarchive/archive_write_set_format_cpio_binary.c b/libarchive/archive_write_set_format_cpio_binary.c
index aefb2ca6f514..4777e75f2912 100644
--- a/libarchive/archive_write_set_format_cpio_binary.c
+++ b/libarchive/archive_write_set_format_cpio_binary.c
@@ -506,12 +506,12 @@ write_header(struct archive_write *a, struct archive_entry *entry)
if ((a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) &&
(archive_entry_size(entry) > 256*256*256-1)) {
archive_set_error(&a->archive, ERANGE,
- "File is too large for PWB binary cpio format.");
+ "File is too large for PWB binary cpio format");
ret_final = ARCHIVE_FAILED;
goto exit_write_header;
} else if (archive_entry_size(entry) > INT32_MAX) {
archive_set_error(&a->archive, ERANGE,
- "File is too large for binary cpio format.");
+ "File is too large for binary cpio format");
ret_final = ARCHIVE_FAILED;
goto exit_write_header;
}
diff --git a/libarchive/archive_write_set_format_cpio_newc.c b/libarchive/archive_write_set_format_cpio_newc.c
index 254d5a9901c3..d72434d8ae88 100644
--- a/libarchive/archive_write_set_format_cpio_newc.c
+++ b/libarchive/archive_write_set_format_cpio_newc.c
@@ -322,7 +322,7 @@ write_header(struct archive_write *a, struct archive_entry *entry)
h + c_filesize_offset, c_filesize_size);
if (ret) {
archive_set_error(&a->archive, ERANGE,
- "File is too large for this format.");
+ "File is too large for this format");
ret_final = ARCHIVE_FAILED;
goto exit_write_header;
}
diff --git a/libarchive/archive_write_set_format_cpio_odc.c b/libarchive/archive_write_set_format_cpio_odc.c
index c72c6b2796bf..ffac716b8e75 100644
--- a/libarchive/archive_write_set_format_cpio_odc.c
+++ b/libarchive/archive_write_set_format_cpio_odc.c
@@ -380,7 +380,7 @@ write_header(struct archive_write *a, struct archive_entry *entry)
h + c_filesize_offset, c_filesize_size);
if (ret) {
archive_set_error(&a->archive, ERANGE,
- "File is too large for cpio format.");
+ "File is too large for cpio format");
ret_final = ARCHIVE_FAILED;
goto exit_write_header;
}
diff --git a/libarchive/archive_write_set_format_gnutar.c b/libarchive/archive_write_set_format_gnutar.c
index 14ef4cd2444d..b67007a631c0 100644
--- a/libarchive/archive_write_set_format_gnutar.c
+++ b/libarchive/archive_write_set_format_gnutar.c
@@ -293,6 +293,17 @@ archive_write_gnutar_header(struct archive_write *a,
} else
sconv = gnutar->opt_sconv;
+ /* Sanity check. */
+ if (archive_entry_pathname(entry) == NULL
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ && archive_entry_pathname_w(entry) == NULL
+#endif
+ ) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't record entry in tar file without pathname");
+ return ARCHIVE_FAILED;
+ }
+
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
@@ -385,17 +396,30 @@ archive_write_gnutar_header(struct archive_write *a,
r = archive_entry_pathname_l(entry, &(gnutar->pathname),
&(gnutar->pathname_length), sconv);
if (r != 0) {
+ const char* p_mbs;
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for pathname");
ret = ARCHIVE_FATAL;
goto exit_write_header;
}
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- archive_entry_pathname(entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
+ p_mbs = archive_entry_pathname(entry);
+ if (p_mbs) {
+ /* We have a wrongly-encoded MBS pathname.
+ * Warn and use it. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s", p_mbs,
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ } else {
+ /* We have no MBS pathname. Fail. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname to %s",
+ archive_string_conversion_charset_name(sconv));
+ return ARCHIVE_FAILED;
+ }
}
r = archive_entry_uname_l(entry, &(gnutar->uname),
&(gnutar->uname_length), sconv);
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
index c275c1ec92b9..359a2737365f 100644
--- a/libarchive/archive_write_set_format_iso9660.c
+++ b/libarchive/archive_write_set_format_iso9660.c
@@ -1381,7 +1381,7 @@ iso9660_options(struct archive_write *a, const char *key, const char *value)
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Option ``%s'' "
- "is not supported on this platform.", key);
+ "is not supported on this platform", key);
return (ARCHIVE_FATAL);
#endif
}
@@ -1503,7 +1503,7 @@ iso9660_options(struct archive_write *a, const char *key, const char *value)
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"``zisofs'' "
- "is not supported on this platform.");
+ "is not supported on this platform");
return (ARCHIVE_FATAL);
#endif
}
@@ -1539,7 +1539,7 @@ iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
if (archive_entry_filetype(entry) == AE_IFLNK
&& iso9660->opt.rr == OPT_RR_DISABLED) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignore symlink file.");
+ "Ignore symlink file");
iso9660->cur_file = NULL;
return (ARCHIVE_WARN);
}
@@ -1549,7 +1549,7 @@ iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Ignore over %lld bytes file. "
- "This file too large.",
+ "This file too large",
MULTI_EXTENT_SIZE);
iso9660->cur_file = NULL;
return (ARCHIVE_WARN);
@@ -2103,7 +2103,7 @@ iso9660_close(struct archive_write *a)
if (iso9660->directories_too_deep != NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: Directories too deep.",
+ "%s: Directories too deep",
archive_entry_pathname(
iso9660->directories_too_deep->file->entry));
return (ARCHIVE_WARN);
@@ -3799,7 +3799,7 @@ set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc,
isoent = isoent_find_entry(vdd->rootent, ids);
if (isoent == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Not Found %s `%s'.",
+ "Not Found %s `%s'",
label, ids);
return (ARCHIVE_FATAL);
}
@@ -7080,7 +7080,7 @@ isoent_make_path_table(struct archive_write *a)
* See also ISO9660 Standard 9.4.
*/
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Too many directories(%d) over 65535.", dir_number);
+ "Too many directories(%d) over 65535", dir_number);
return (ARCHIVE_FATAL);
}
@@ -7203,7 +7203,7 @@ isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Boot image file(``%s'') size is too big "
- "for fd type.",
+ "for fd type",
iso9660->el_torito.boot_filename.s);
return (ARCHIVE_FATAL);
}
@@ -7964,7 +7964,7 @@ zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs,
r = inflateInit(&zisofs->stream);
if (r != Z_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize zisofs decompression.");
+ "Can't initialize zisofs decompression");
return (ARCHIVE_FATAL);
}
zisofs->stream_valid = 1;
diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c
index 8131574c8da2..a4ffec8954d9 100644
--- a/libarchive/archive_write_set_format_mtree.c
+++ b/libarchive/archive_write_set_format_mtree.c
@@ -2262,7 +2262,7 @@ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Found duplicate entries for `%s' with "
- "differing file types.",
+ "differing file types",
np->pathname.s);
return (ARCHIVE_FAILED);
}
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
index 66e6d75196ec..f3589d6859e3 100644
--- a/libarchive/archive_write_set_format_pax.c
+++ b/libarchive/archive_write_set_format_pax.c
@@ -1062,7 +1062,7 @@ archive_write_pax_header(struct archive_write *a,
}
/* If numeric GID is too large, add 'gid' to pax extended attrs. */
- if ((unsigned int)archive_entry_gid(entry_main) >= (1 << 18)) {
+ if (archive_entry_gid(entry_main) >= (1 << 18)) {
add_pax_attr_int(&(pax->pax_header), "gid",
archive_entry_gid(entry_main));
need_extension = 1;
@@ -1078,7 +1078,7 @@ archive_write_pax_header(struct archive_write *a,
}
/* If numeric UID is too large, add 'uid' to pax extended attrs. */
- if ((unsigned int)archive_entry_uid(entry_main) >= (1 << 18)) {
+ if (archive_entry_uid(entry_main) >= (1 << 18)) {
add_pax_attr_int(&(pax->pax_header), "uid",
archive_entry_uid(entry_main));
need_extension = 1;
@@ -1471,7 +1471,7 @@ archive_write_pax_header(struct archive_write *a,
if (r < ARCHIVE_WARN) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"archive_write_pax_header: "
- "'x' header failed?! This can't happen.\n");
+ "'x' header failed?! This can't happen");
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
diff --git a/libarchive/archive_write_set_format_ustar.c b/libarchive/archive_write_set_format_ustar.c
index 4084eb455968..97724c1588b3 100644
--- a/libarchive/archive_write_set_format_ustar.c
+++ b/libarchive/archive_write_set_format_ustar.c
@@ -254,11 +254,11 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
sconv = ustar->opt_sconv;
/* Sanity check. */
+ if (archive_entry_pathname(entry) == NULL
#if defined(_WIN32) && !defined(__CYGWIN__)
- if (archive_entry_pathname_w(entry) == NULL) {
-#else
- if (archive_entry_pathname(entry) == NULL) {
+ && archive_entry_pathname_w(entry) == NULL
#endif
+ ) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't record entry in tar file without pathname");
return (ARCHIVE_FAILED);
@@ -409,15 +409,28 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
*/
r = archive_entry_pathname_l(entry, &pp, &copy_length, sconv);
if (r != 0) {
+ const char* p_mbs;
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,
- "Can't translate pathname '%s' to %s",
- pp, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
+ p_mbs = archive_entry_pathname(entry);
+ if (p_mbs) {
+ /* We have a wrongly-encoded MBS pathname.
+ * Warn and use it. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s", p_mbs,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ } else {
+ /* We have no MBS pathname. Fail. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname to %s",
+ archive_string_conversion_charset_name(sconv));
+ return ARCHIVE_FAILED;
+ }
}
if (copy_length <= USTAR_name_size)
memcpy(h + USTAR_name_offset, pp, copy_length);
diff --git a/libarchive/archive_write_set_format_v7tar.c b/libarchive/archive_write_set_format_v7tar.c
index 2598fc076c0c..37ba73a1320a 100644
--- a/libarchive/archive_write_set_format_v7tar.c
+++ b/libarchive/archive_write_set_format_v7tar.c
@@ -232,7 +232,11 @@ archive_write_v7tar_header(struct archive_write *a, struct archive_entry *entry)
sconv = v7tar->opt_sconv;
/* Sanity check. */
- if (archive_entry_pathname(entry) == NULL) {
+ if (archive_entry_pathname(entry) == NULL
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ && archive_entry_pathname_w(entry) == NULL
+#endif
+ ) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't record entry in tar file without pathname");
return (ARCHIVE_FAILED);
@@ -382,15 +386,28 @@ format_header_v7tar(struct archive_write *a, char h[512],
*/
r = archive_entry_pathname_l(entry, &pp, &copy_length, sconv);
if (r != 0) {
+ const char* p_mbs;
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,
- "Can't translate pathname '%s' to %s",
- pp, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
+ p_mbs = archive_entry_pathname(entry);
+ if (p_mbs) {
+ /* We have a wrongly-encoded MBS pathname.
+ * Warn and use it. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s", p_mbs,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ } else {
+ /* We have no MBS pathname. Fail. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname to %s",
+ archive_string_conversion_charset_name(sconv));
+ return ARCHIVE_FAILED;
+ }
}
if (strict && copy_length < V7TAR_name_size)
memcpy(h + V7TAR_name_offset, pp, copy_length);
diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c
index ec3219057e4e..6ecccdef6499 100644
--- a/libarchive/archive_write_set_format_xar.c
+++ b/libarchive/archive_write_set_format_xar.c
@@ -526,12 +526,13 @@ xar_options(struct archive_write *a, const char *key, const char *value)
}
if (strcmp(key, "threads") == 0) {
char *endptr;
+ unsigned long val;
if (value == NULL)
return (ARCHIVE_FAILED);
errno = 0;
- xar->opt_threads = (int)strtoul(value, &endptr, 10);
- if (errno != 0 || *endptr != '\0') {
+ val = strtoul(value, &endptr, 10);
+ if (errno != 0 || *endptr != '\0' || val > (unsigned)INT_MAX) {
xar->opt_threads = 1;
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,
@@ -539,6 +540,7 @@ xar_options(struct archive_write *a, const char *key, const char *value)
value);
return (ARCHIVE_FAILED);
}
+ xar->opt_threads = (int)val;
if (xar->opt_threads == 0) {
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
xar->opt_threads = lzma_cputhreads();
diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c
index 19121b519148..81d3db0db038 100644
--- a/libarchive/archive_write_set_format_zip.c
+++ b/libarchive/archive_write_set_format_zip.c
@@ -398,16 +398,17 @@ archive_write_zip_options(struct archive_write *a, const char *key,
return (ret);
} else if (strcmp(key, "compression-level") == 0) {
char *endptr;
+ unsigned long v;
if (val == NULL)
return (ARCHIVE_WARN);
errno = 0;
- zip->compression_level = (short)strtoul(val, &endptr, 10);
- if (errno != 0 || *endptr != '\0' || zip->compression_level < 0 ||
- zip->compression_level > 9) {
+ v = strtoul(val, &endptr, 10);
+ if (errno != 0 || *endptr != '\0' || v > 9) {
zip->compression_level = 6; // set to default
return (ARCHIVE_WARN);
}
+ zip->compression_level = (short)v;
if (zip->compression_level == 0) {
zip->requested_compression = COMPRESSION_STORE;
@@ -435,17 +436,19 @@ archive_write_zip_options(struct archive_write *a, const char *key,
}
} else if (strcmp(key, "threads") == 0) {
char *endptr;
+ unsigned long v;
if (val == NULL)
return (ARCHIVE_FAILED);
errno = 0;
- zip->threads = (short)strtoul(val, &endptr, 10);
- if (errno != 0 || *endptr != '\0') {
+ v = strtoul(val, &endptr, 10);
+ if (errno != 0 || *endptr != '\0' || v > SHRT_MAX) {
zip->threads = 1;
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
"Illegal value `%s'", val);
return (ARCHIVE_FAILED);
}
+ zip->threads = (short)v;
if (zip->threads == 0) {
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
zip->threads = lzma_cputhreads();
@@ -802,6 +805,17 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
int version_needed = 10;
#define MIN_VERSION_NEEDED(x) do { if (version_needed < x) { version_needed = x; } } while (0)
+ /* Sanity check. */
+ if (archive_entry_pathname(entry) == NULL
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ && archive_entry_pathname_w(entry) == NULL
+#endif
+ ) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't record entry in zip file without pathname");
+ return ARCHIVE_FAILED;
+ }
+
/* Ignore types of entries that we don't support. */
type = archive_entry_filetype(entry);
if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
@@ -882,22 +896,33 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
return (ARCHIVE_FATAL);
}
- if (sconv != NULL) {
+ {
const char *p;
size_t len;
if (archive_entry_pathname_l(zip->entry, &p, &len, sconv) != 0) {
+ const char* p_mbs;
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,
- "Can't translate Pathname '%s' to %s",
- archive_entry_pathname(zip->entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
+ p_mbs = archive_entry_pathname(zip->entry);
+ if (p_mbs) {
+ /* We have a wrongly-encoded MBS pathname. Warn and use it. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s", p_mbs,
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ } else {
+ /* We have no MBS pathname. Fail. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname to %s",
+ archive_string_conversion_charset_name(sconv));
+ return ARCHIVE_FAILED;
+ }
}
if (len > 0)
archive_entry_set_pathname(zip->entry, p);
diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
index 02521c2bc1ad..5734cbed5ed8 100644
--- a/libarchive/test/CMakeLists.txt
+++ b/libarchive/test/CMakeLists.txt
@@ -114,6 +114,8 @@ IF(ENABLE_TEST)
test_read_format_ar.c
test_read_format_cab.c
test_read_format_cab_filename.c
+ test_read_format_cab_lzx_oob.c
+ test_read_format_cab_skip_malformed.c
test_read_format_cpio_afio.c
test_read_format_cpio_bin.c
test_read_format_cpio_bin_Z.c
@@ -151,10 +153,12 @@ IF(ENABLE_TEST)
test_read_format_isorr_new_bz2.c
test_read_format_isorr_rr_moved.c
test_read_format_isozisofs_bz2.c
+ test_read_format_iso_zisofs_overflow.c
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_lha_oversize_header.c
test_read_format_mtree.c
test_read_format_mtree_crash747.c
test_read_format_pax_bz2.c
@@ -167,6 +171,7 @@ IF(ENABLE_TEST)
test_read_format_rar_filter.c
test_read_format_rar_overflow.c
test_read_format_rar5.c
+ test_read_format_rar5_loop_bug.c
test_read_format_raw.c
test_read_format_tar.c
test_read_format_tar_V_negative_size.c
@@ -227,6 +232,7 @@ IF(ENABLE_TEST)
test_tar_large.c
test_ustar_filename_encoding.c
test_ustar_filenames.c
+ test_v7tar_filename_encoding.c
test_warn_missing_hardlink_target.c
test_write_disk.c
test_write_disk_appledouble.c
diff --git a/libarchive/test/test_acl_text.c b/libarchive/test/test_acl_text.c
index c2904649a3ba..7e80686e84eb 100644
--- a/libarchive/test/test_acl_text.c
+++ b/libarchive/test/test_acl_text.c
@@ -404,6 +404,29 @@ DEFINE_TEST(test_acl_from_text)
archive_entry_acl_clear(ae);
free(ws);
+
+ /*
+ * 6. Malformed "default" prefix with no tag field should return
+ * ARCHIVE_WARN, not crash (GitHub issue #2744).
+ * When the ACL text is just "d" or "default" with type DEFAULT,
+ * the parser recognises the default prefix but field[1] is NULL,
+ * which previously caused a NULL-pointer dereference.
+ */
+ archive_entry_acl_clear(ae);
+ assertEqualInt(ARCHIVE_WARN,
+ archive_entry_acl_from_text(ae, "d",
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
+ assertEqualInt(ARCHIVE_WARN,
+ archive_entry_acl_from_text_w(ae, L"d",
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
+ archive_entry_acl_clear(ae);
+ assertEqualInt(ARCHIVE_WARN,
+ archive_entry_acl_from_text(ae, "default",
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
+ assertEqualInt(ARCHIVE_WARN,
+ archive_entry_acl_from_text_w(ae, L"default",
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
+
archive_entry_free(ae);
}
diff --git a/libarchive/test/test_archive_pathmatch.c b/libarchive/test/test_archive_pathmatch.c
index 3696d38fcf19..3b212aca9d94 100644
--- a/libarchive/test/test_archive_pathmatch.c
+++ b/libarchive/test/test_archive_pathmatch.c
@@ -285,4 +285,22 @@ DEFINE_TEST(test_archive_pathmatch)
archive_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
archive_pathmatch("b/c/d$", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+
+ /* Anchor characters within pattern not special. */
+ assertEqualInt(0,
+ archive_pathmatch("*^*", "a/b/c", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+ assertEqualInt(1,
+ archive_pathmatch("*^*", "a^b", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+ assertEqualInt(0,
+ archive_pathmatch("*$*", "a/b/c", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+ assertEqualInt(1,
+ archive_pathmatch("*$*", "a$b", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+ assertEqualInt(0,
+ archive_pathmatch("a*/^b/c", "a/b/c", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+ assertEqualInt(1,
+ archive_pathmatch("a*/^b/c", "a/^b/c", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+ assertEqualInt(0,
+ archive_pathmatch("a*/b$/c", "a/b/c", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+ assertEqualInt(1,
+ archive_pathmatch("a*/b$/c", "a/b$/c", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
}
diff --git a/libarchive/test/test_archive_string_conversion.c b/libarchive/test/test_archive_string_conversion.c
index 055bddc75068..ecc39dffea7f 100644
--- a/libarchive/test/test_archive_string_conversion.c
+++ b/libarchive/test/test_archive_string_conversion.c
@@ -883,6 +883,141 @@ DEFINE_TEST(test_archive_string_conversion)
test_archive_string_set_get();
}
+static void
+test_archive_string_conversion_fail_charset(void)
+{
+ /* Conversion error message construction may use the charset name. */
+ assertEqualString("current locale",
+ archive_string_conversion_charset_name(NULL));
+}
+
+static void
+test_archive_string_conversion_fail_utf16_mbs(struct archive *a,
+ struct archive_string_conv *sconv)
+{
+ static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
+ int r;
+ const char* p;
+ size_t len;
+
+ /* WCS to MBS should fail. */
+ {
+ struct archive_string str;
+ archive_string_init(&str);
+ r = archive_string_append_from_wcs(
+ &str, wcs_string, sizeof(wcs_string) / sizeof(*wcs_string) - 1);
+ assertEqualInt(-1, r);
+ archive_string_free(&str);
+ }
+ {
+ struct archive_mstring mstr;
+ memset(&mstr, 0, sizeof(mstr));
+ assertEqualInt(ARCHIVE_OK,
+ archive_mstring_copy_wcs(&mstr, wcs_string));
+ r = archive_mstring_get_mbs_l(a, &mstr, &p, &len, NULL);
+ assertEqualInt(-1, r);
+ assertEqualInt(0, mstr.aes_set & AES_SET_MBS);
+ archive_mstring_clean(&mstr);
+ }
+ if (sconv) {
+ struct archive_mstring mstr;
+ memset(&mstr, 0, sizeof(mstr));
+ assertEqualInt(ARCHIVE_OK,
+ archive_mstring_copy_wcs(&mstr, wcs_string));
+ r = archive_mstring_get_mbs_l(a, &mstr, &p, &len, sconv);
+ assertEqualInt(-1, r);
+ assertEqualInt(0, mstr.aes_set & AES_SET_MBS);
+ archive_mstring_clean(&mstr);
+ }
+}
+
+static void
+test_archive_string_conversion_fail_utf8_mbs(struct archive *a,
+ struct archive_string_conv *sconv)
+{
+ static const char utf8_string[] = "\xD0\xBF\xD1\x80\xD0\xB8";
+ int r;
+ const char* p;
+ size_t len;
+
+ /* UTF-8 to MBS should fail. */
+ {
+ struct archive_mstring mstr;
+ memset(&mstr, 0, sizeof(mstr));
+ assertEqualInt(6,
+ archive_mstring_copy_utf8(&mstr, utf8_string));
+ r = archive_mstring_get_mbs_l(a, &mstr, &p, &len, NULL);
+ assertEqualInt(-1, r);
+ assertEqualInt(0, mstr.aes_set & AES_SET_MBS);
+ archive_mstring_clean(&mstr);
+ }
+ if (sconv) {
+ struct archive_mstring mstr;
+ memset(&mstr, 0, sizeof(mstr));
+ assertEqualInt(6,
+ archive_mstring_copy_utf8(&mstr, utf8_string));
+ r = archive_mstring_get_mbs_l(a, &mstr, &p, &len, sconv);
+ assertEqualInt(-1, r);
+ assertEqualInt(0, mstr.aes_set & AES_SET_MBS);
+ archive_mstring_clean(&mstr);
+ }
+}
+
+DEFINE_TEST(test_archive_string_conversion_fail_c)
+{
+ struct archive *a;
+
+ /* Test the C locale by not calling setlocale. */
+
+ test_archive_string_conversion_fail_charset();
+
+ assert((a = archive_write_new()) != NULL);
+
+ test_archive_string_conversion_fail_utf16_mbs(a, NULL);
+ test_archive_string_conversion_fail_utf8_mbs(a, NULL);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+}
+
+DEFINE_TEST(test_archive_string_conversion_fail_latin1)
+{
+ struct archive *a;
+ struct archive_string_conv *sconv;
+
+ /* Test a Latin-1 locale. */
+ if (
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Windows allows ".<code-page>" to change encoding. */
+ setlocale(LC_ALL, ".1252") == NULL
+#else
+ setlocale(LC_ALL, "en_US.ISO8859-1") == NULL
+#endif
+ ) {
+ skipping("No Latin-1 locale found on this system.");
+ return;
+ }
+
+ test_archive_string_conversion_fail_charset();
+
+ assert((a = archive_write_new()) != NULL);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "CP1252", 0)));
+ assertEqualString("CP1252",
+ archive_string_conversion_charset_name(sconv));
+#else
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "ISO8859-1", 0)));
+ assertEqualString("ISO8859-1",
+ archive_string_conversion_charset_name(sconv));
+#endif
+ test_archive_string_conversion_fail_utf16_mbs(a, sconv);
+ test_archive_string_conversion_fail_utf8_mbs(a, sconv);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+}
+
DEFINE_TEST(test_archive_string_conversion_utf16_utf8)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
diff --git a/libarchive/test/test_gnutar_filename_encoding.c b/libarchive/test/test_gnutar_filename_encoding.c
index 476ec2149fdf..830b3884f829 100644
--- a/libarchive/test/test_gnutar_filename_encoding.c
+++ b/libarchive/test/test_gnutar_filename_encoding.c
@@ -491,3 +491,43 @@ DEFINE_TEST(test_gnutar_filename_encoding_UTF16_win)
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
#endif
}
+
+DEFINE_TEST(test_gnutar_filename_encoding_fail_UTF16_win)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ skipping("This test is meant to verify unicode string handling"
+ " on Windows with UTF-16 names");
+ return;
+#else
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ /* Test the C locale by not calling setlocale. */
+
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP437") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from UTF-16 to CP437.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set the filename using a UTF-16 string */
+ archive_entry_copy_pathname_w(entry, L"\u8868.txt");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, entry));
+ /* The pathname cannot even be represented in the current locale
+ for inclusion in the error message. */
+ assertEqualString("Can't translate pathname to CP437",
+ archive_error_string(a));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+#endif
+}
diff --git a/libarchive/test/test_read_format_7zip.c b/libarchive/test/test_read_format_7zip.c
index 3236fee2c9d3..6d71f80d12ed 100644
--- a/libarchive/test/test_read_format_7zip.c
+++ b/libarchive/test/test_read_format_7zip.c
@@ -1383,6 +1383,32 @@ DEFINE_TEST(test_read_format_7zip_sfx_elf)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
+/*
+ * A truncated ELF 64-bit MSB file.
+ */
+DEFINE_TEST(test_read_format_7zip_sfx_elf64trunc)
+{
+ const char *reffile = "test_read_format_7zip_sfx_elf64trunc.elf";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+
+ extract_reference_file(reffile);
+ assertEqualIntA(a, ARCHIVE_FATAL,
+ archive_read_open_filename(a, reffile, 10240));
+
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
+ assertEqualInt(0, archive_file_count(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
DEFINE_TEST(test_read_format_7zip_extract_second)
{
struct archive *a;
diff --git a/libarchive/test/test_read_format_7zip_malformed.c b/libarchive/test/test_read_format_7zip_malformed.c
index f2120879fa8c..bd3452c00aad 100644
--- a/libarchive/test/test_read_format_7zip_malformed.c
+++ b/libarchive/test/test_read_format_7zip_malformed.c
@@ -59,8 +59,25 @@ test_malformed2(void)
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
+
+static void
+test_malformed3(void)
+{
+ const char *refname = "test_read_format_7zip_malformed3.7z";
+ struct archive *a;
+
+ 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_FATAL, archive_read_open_filename(a, refname, 10240));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
DEFINE_TEST(test_read_format_7zip_malformed)
{
test_malformed1();
test_malformed2();
+ test_malformed3();
}
diff --git a/libarchive/test/test_read_format_7zip_malformed3.7z.uu b/libarchive/test/test_read_format_7zip_malformed3.7z.uu
new file mode 100644
index 000000000000..4e814980a6da
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_malformed3.7z.uu
@@ -0,0 +1,24 @@
+begin 644 test_read_format_7zip_malformed3.7z
+M?T5,1@("`64N9&5B=0``+ZZNRO_______P```/\Q```````````"````````
+M```L0"!S+F)S,``1<P!```H``FMK__](:VMK:VNAH:$!`*&AH:&A)S$```!C
+M;VUP>FEP503_8G-S90``````#0H-_P```'X```````````(`````````````
+M`*D``````"\`````____^@````$````````#`/__________<RYD96)U```O
+MKJ[*________````_S$```````````(``````````"Q`(',N8G,P`!%S`$``
+M(``":VNAH2<Q```````#Z'K__P5%145%____________`/__________;VUP
+M>FEP503_8G-S90``````#0H-_P```'X```````````(``````````````*D`
+M`````"\`````____^@````$````````#_P```/______<RYD96)U```OKJ[*
+M________````_S$```````````(``````````"Q`(',N8G,P`!%S`$"0`P`"
+M:VLR:TAK:VMK:Z&AH0$`H:&AH:$G,@```&-O;7!Z:7!5!/]28W-E```````-
+M"@W_````?@```````````@``````````````J0``````+P`````0___Z````
+M`0````````,`__________\PXT$N9&%T80#^E)3+E)24_P3_____________
+M____(________^+______P5%145%____________`/__________________
+M_____________________^?_________145%0``#`/Z4E,N4P<'!P<'!E```
+M`/_R`````'5U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U
+M=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=0`````"````
+M```````L0"!S+F4```````T*#?\```!^```````````"``````````````"I
+M```````O`````/___^0````!`````````P#__W5U=75U=75U=75U=75U=75U
+M=0`````"```````````L0"!S+F)S,?P1<P!```,`"&MK,FM(:VMK145%145%
+,P45%145%1?____\$
+`
+end
+
diff --git a/libarchive/test/test_read_format_7zip_sfx_elf64trunc.elf.uu b/libarchive/test/test_read_format_7zip_sfx_elf64trunc.elf.uu
new file mode 100644
index 000000000000..512da918218b
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_sfx_elf64trunc.elf.uu
@@ -0,0 +1,5 @@
+begin 664 test_read_format_7zip_sfx_elf64trunc.elf
+M?T5,1@("````````````````````````````````````````````````````
+2```````````````````H``$`
+`
+end
diff --git a/libarchive/test/test_read_format_cab_lzx_oob.c b/libarchive/test/test_read_format_cab_lzx_oob.c
new file mode 100644
index 000000000000..a4c15d62f789
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_lzx_oob.c
@@ -0,0 +1,45 @@
+#include "test.h"
+
+/*
+ * Regression test for Heap Out-of-Bounds Write in CAB LZX decoder.
+ * This ensures that a malformed CFDATA uncompressed size does not
+ * bypass physical buffer limits and cause memory corruption during skips.
+ */
+DEFINE_TEST(test_read_format_cab_lzx_oob)
+{
+ const char *refname = "test_read_format_cab_lzx_oob.cab";
+ struct archive *a;
+ struct archive_entry *ae;
+ const void *buff;
+ size_t size;
+ int64_t offset;
+
+ /* * The test framework will automatically find 'test_read_format_cab_lzx_oob.cab.uu',
+ * decode it, and place the binary '.cab' in the temporary test directory.
+ */
+ extract_reference_file(refname);
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_cab(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+
+ /* If it fails to open, there's a problem with the test setup/file */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+
+ /* Read the header of the malformed entry */
+ if (ARCHIVE_OK == archive_read_next_header(a, &ae)) {
+ /* * We attempt to read a block to initialize the LZX state machine.
+ * We do not assert the result because the file is intentionally malformed.
+ * Regardless of success or failure, we force a skip to test state handling
+ * and trigger the vulnerability.
+ */
+ archive_read_data_block(a, &buff, &size, &offset);
+ archive_read_data_skip(a);
+ /* * Optional: We could assert that the error string contains our patch message,
+ * but simply surviving without a segfault/ASAN violation is the primary goal
+ * for fuzzing regression tests.
+ */
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+} \ No newline at end of file
diff --git a/libarchive/test/test_read_format_cab_lzx_oob.cab.uu b/libarchive/test/test_read_format_cab_lzx_oob.cab.uu
new file mode 100644
index 000000000000..2f453ef27116
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_lzx_oob.cab.uu
@@ -0,0 +1,11 @@
+begin 664 test_read_format_cab_lzx_oob.cab
+M35-#1@````!!``"2DI*2DI(````````2Y``!``$``,2PW@``'P$```$`0Q`!
+M`3O2T@D)"0D)"0D)``````````````"RLK*RLK*RLK*RLK*RLK*RLK(*,```
+M````````````````LK*2X____[:RL@``````````LK*R"C``````````````
+M`````+*RDN/___^VLK(```````````"R'YV)3``````````````0$!`0$!`0
+M$!`0$!D0$!`0$!`0$!`0$!`0$!`0$!#___\/$!`0`````````$`0$`!`,#<P
+M-S`R````,#82SWXO+R\`_P``````````````````````````````````````
+M``````#U\DH*-S`R````,#82SWXO+R\`_P``````````````````````````
+.````````````````````
+`
+end
diff --git a/libarchive/test/test_read_format_cab_skip_malformed.c b/libarchive/test/test_read_format_cab_skip_malformed.c
new file mode 100644
index 000000000000..05cc80b79c93
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_skip_malformed.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+DEFINE_TEST(test_read_format_cab_skip_malformed)
+{
+ /* Reference to the malformed CAB file */
+ const char *refname = "test_read_format_cab_skip_malformed.cab";
+ struct archive *a;
+ struct archive_entry *ae;
+ void *buffer;
+ size_t buffersize;
+
+ /* Extract the reference file into the test sandbox */
+ extract_reference_file(refname);
+
+ /* Read the entire file into memory */
+ buffer = slurpfile(&buffersize, "%s", refname);
+ assert(buffer != NULL);
+
+ /* Initialize the archive reader */
+ 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));
+
+ /* Read from memory (a prerequisite for triggering this specific bug) */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buffer, buffersize));
+
+ /* Simulate the parsing flow to trigger the implicit skip routine */
+ while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
+ const void *buff;
+ size_t size_read;
+ int64_t offset;
+ while (archive_read_data_block(a, &buff, &size_read, &offset) == ARCHIVE_OK) {
+ /* Consume data. This will fail quickly due to the malformed payload. */
+ }
+ }
+
+ /* Clean up. If the patch is effective, the program reaches here safely. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ free(buffer);
+} \ No newline at end of file
diff --git a/libarchive/test/test_read_format_cab_skip_malformed.cab.uu b/libarchive/test/test_read_format_cab_skip_malformed.cab.uu
new file mode 100644
index 000000000000..7ec83433546d
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_skip_malformed.cab.uu
@@ -0,0 +1,95 @@
+begin 664 test_read_format_cab_skip_malformed.cab
+M35-#1@````!!``"2DI*2DI(````````2Y``!``$``,2PW@``'P$``-(!```!
+M.]+2"0D)"0D)"0D)"0D)"0D)"0FRLK*R"0D)"0D)"0D)"0D)LK*RLK*RLK(`
+M``````````````````"RLK*RLK*RLK*RLK*RLK*RLK(*,```````````````
+M````LK*RX____[:RL@```````````````#`W,"]`````"G!P`````&UDL@HP
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````%!+`P0````!#`P,#`P,#`P,#`P,#```````````````__\```3_
+M``!(___H````````````````````````````````````````____________
+M____________________________________________________````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M@```````````````@`````$`````````````````````````````````````
+M````````````````````````````````````````````#`H,#````'H,#`P`
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````#__P``!/\``$C__^@```````````#_________________________
+M______________________________________\`````````````````````
+M`"\O+R\O+R\O+R\O+R\O+R\O+R\O+R\G+PHQ-C4P+U):22\P-S!,4EI)"@HO
+M=6YS970@<F$@("T@("!/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T\@(2`@("`@
+M+2`@("`@("`@(",@("`@("`@("L@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`K('A,4EI)"@H*("`@("`@(```````````````````````````````````
+M```````````````````````````````````````````````````,]@P,#`H*
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````#__P``!/\``$C__^@`````
+M`%``````````````````````````````````________________________
+M________________________________________````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````@```````
+M````````@`````$`````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````#__P``!/\``$C__^@`
+M``````````#_________________________________________________
+M______________\`````````````````````````````````````````````
+M`````````````````````%!+`P0````!#`P,#`P,#`P,#`P,#```#`H,#```
+M`'H,````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````,#`SV``````````````````````P,
+M#`H*`/__```$_P``2/__Z````````````%#_________________________
+M______________________________________\`````````````````````
+M````````````````````````````````````````````+R\P23@*"DQ:3#`P
+M"DQ26DD*"DQ:+PH*,#`W,"\O,#<P+R\O+R\O+S!).`H*3%I,,"\P-S!,4EI)
+M"@I,6B\O"F)E9VEN-F%E<RUB-"`Q(%TP-#`P5T%20R\O25HX"DQ,,`I,4EI)
+M"@I,6B\O-S`W"DQ:3#`O,#<P3%):20H*3%HO+PIB96=I;BUB87-E-C0@-B`P
+M-#`P5T%20R\O25HX"DQ,,`I,4EI)"@I,6B\O-S`W,#<O+R]:4B\O+R\O"C!@
+M-S`W,#$*#8V-C8V-C8V-C8V-C8V-C8V-C5!+`P10"@`*"C`P-S`O+S`W,"\O
+M+R\O+R\P23@*"DQ:3#`O,#<P3%):20H*3%HO+PIB96=I;BUB87-E-C0@,2`P
+M-#`P5T%20R\O25HX"DQ,"DQ:3#`O,#<P3%):20H*3%HO+PIB96=I;BUB87-E
+M-C0@,2`P-#`P5T%20R\O25HV"DQ,,`I,4EI)"@I,6B\*"C`P-S`O+S`W,"\O
+M+R\O+R\P23@*"DQ:3#`O,#<P3%):20H*3%HO+PIB90``V/\M`?\-__\-_RO_
+M_?____\F__\+____B?\*)PH``')R<G)R<G)R<G+_____________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________<G)R<G)R
+M<G)R<G)R<G)R<G)R<G)R<G)R<G)R<G)R<G)R<G)R<G)R<G)R<G)R<G)``!0`
+M`````````````````$#_____"`1W2"__0`#D$P`G_D3________NXEQ<7%QR
+M7#`P-S=<,#)<7%Q<7%Q<?%Q<7%Q<<EPP,#<W7#`R7%Q<7%Q<7%Q<,#)<7%Q<
+M7%Q<7')<,#`W-UPP,EQ<7%Q<7"L*=75,6B\O"F)E9VEN+6)A<V4V-"`V(#`T
+M,#!705)#+R])6C@*3"`Q(#`T,#!705)#+R])6C@*3$P*3%I,,"\P-S!,4EI)
+M"@I,6B\O"F)E9VEN+6)A<V4V-"`Q(#`T,#!705)#+R])6C@*3$PP"DQ26DD*
+M"DQ:+PH*,#`W,"\O,#<P+R\O+R\O+S!).`H*3%I,,"\P-S!,4EI)"@I,6B\O
+M"F)E9VEN+6)A<V4V-"`Q,S`T,#!705)#+R])6C@*3$PP"DQ26DD*"DQ:+R\W
+M,#<*3%I,,"\P-S!,4EI)"@I,6B\O"F)E9VEN+6)A<V4V-"`V(#`T,#!705)#
+M+R])6C@*3$PP"DQ26DD*"DQ:+R\W,#<P-R\O+UI2+R\O+R\O+R\O-S`W"DQ:
+M3#`O04Y325\P-S!,4EI)"@I,6B\O"F)E9VEN+6)A<V4V-"`V(#`T,#!705)#
+M+R])6CP*3$PP"DQ26DD*"DQ:+R\W,#<P-R\O+UI2+R\O+R\O+R\O+R\O+R\O
+M+R\O+R\O+R\O+R\P23@*"DQ:3"\O+R\O+R\P23@*"DQ:3#`O,#<P3%):20H*
+M3%HO+PIB96=I;BUB87-E-C0@,2`P-#`P5T%20R\O25HX"DQ,,`I,4EI)"@I,
+M6B\O-S`W"DQ:3#`O,#<P3%):20H*3%HO+PIB96=I;BUB87-/-C0@-B`P-#`P
+M5T%20R\O25HX"DQ,,`I,4EI)"@I,6B\O-S`W,#<O+R]:4B\O+R\O+R\O+S<P
+M-PI,6DPP+S`W,$Q26DD*"DQ:+R\*8F5G:6XM8F%S938T(#8@,#0P,%=!4D,O
+M,#<P3%):20H*3%HO+PIB96=I;BUB87-E-C0@,2!=,#0P,%=!4D,O+TE:.`I,
+M3#`*3%):20H*3%HO+S<P-PI,6DPP+S`W,$Q26DD*"DQ:+R\*8F5G:6XM8F%S
+M938T(#8@,#0P,%=!4D,O+TE:.`I,3#`*3%):20H*,!^+#@``````````````
+M```````+``````#'<?\```````````L``````,=Q_____U):20```````!`D
+M````````3%HO+S<P-S`W+R\O6E(O+R]Z+R\*,&`W,#<P,0H-"@U=2@T*#0HN
+M+@H*#0!$`````%Q<7%QA7%Q<55Q<05PR*5Q<7%Q<7%Q<7%PP7%Q!7#(I7%Q<
+M7%Q<7%Q<7#!<7$%<,BE<7%Q<85Q<7%5<7$%<,BE<7%Q<7%Q<7%Q<,%Q<7%Q<
+M7%Q<7%Q57%Q!7#(I7`D)"0D)"0D)"0D)"0D)"0D)"0D)"@````!%1@"']@``
+!````
+`
+end
diff --git a/libarchive/test/test_read_format_iso_zisofs_overflow.c b/libarchive/test/test_read_format_iso_zisofs_overflow.c
new file mode 100644
index 000000000000..bad52b154acd
--- /dev/null
+++ b/libarchive/test/test_read_format_iso_zisofs_overflow.c
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2025
+ * 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"
+
+/*
+ * Verify that a crafted ISO9660 image with an invalid zisofs block-size
+ * exponent (pz_log2_bs) is handled gracefully.
+ *
+ * The ZF extension in the Rock Ridge entry stores pz_log2_bs as a raw
+ * byte from the image. The zisofs spec only permits values 15-17.
+ * Values outside that range can cause:
+ * - Undefined behavior via oversized bit shifts (any platform)
+ * - Integer overflow in block pointer allocation on 32-bit platforms,
+ * leading to a heap buffer overflow write
+ *
+ * The test image has pz_log2_bs=2 (out of spec) combined with
+ * pz_uncompressed_size=0xFFFFFFF9. On 32-bit, (ceil+1)*4 overflows
+ * size_t to 0, malloc(0) returns a tiny buffer, and the code attempts
+ * to write ~4GB into it. On 64-bit the allocation is huge and safely
+ * fails.
+ *
+ * We verify the fix by checking archive_entry_size() after reading the
+ * header. When pz_log2_bs validation rejects the bad value (pz=0),
+ * the entry keeps its raw on-disk size (small). Without the fix,
+ * the reader sets the entry size to pz_uncompressed_size (0xFFFFFFF9).
+ *
+ * We intentionally do NOT call archive_read_data() here. Without the
+ * fix, the data-read path triggers a heap buffer overflow on 32-bit
+ * that silently corrupts the process heap, causing later tests to
+ * crash rather than this one.
+ */
+DEFINE_TEST(test_read_format_iso_zisofs_overflow)
+{
+ const char reffile[] = "test_read_format_iso_zisofs_overflow.iso";
+ struct archive *a;
+ struct archive_entry *ae;
+ int r = ARCHIVE_OK;
+ int found_regular_file = 0;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, reffile, 10240));
+
+ while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK ||
+ r == ARCHIVE_WARN) {
+ /*
+ * With the fix, pz_log2_bs=2 is rejected and pz is set
+ * to 0, so the entry keeps its small raw size from the
+ * ISO directory record. Without the fix, zisofs sets
+ * the entry size to pz_uncompressed_size (0xFFFFFFF9).
+ *
+ * We intentionally do NOT call archive_read_data().
+ * Without the fix, the data-read path triggers a heap
+ * buffer overflow on 32-bit that silently corrupts the
+ * process heap, causing later tests to crash rather
+ * than this one.
+ */
+ if (archive_entry_filetype(ae) == AE_IFREG) {
+ la_int64_t sz = archive_entry_size(ae);
+ failure("entry \"%s\" has size %jd"
+ "; expected < 1 MiB"
+ " (if size is 4294966265 = 0xFFFFFFF9, the"
+ " pz_log2_bs validation is missing)",
+ archive_entry_pathname(ae), (intmax_t)sz);
+ assert(sz < 1024 * 1024);
+ found_regular_file = 1;
+ }
+ }
+
+ /* Iteration must have completed normally. */
+ assertEqualInt(ARCHIVE_EOF, r);
+
+ /* The PoC image contains a regular file; if we never saw one,
+ * something is wrong with the test image. */
+ assert(found_regular_file);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
diff --git a/libarchive/test/test_read_format_iso_zisofs_overflow.iso.uu b/libarchive/test/test_read_format_iso_zisofs_overflow.iso.uu
new file mode 100644
index 000000000000..5e7dcc3750ac
--- /dev/null
+++ b/libarchive/test/test_read_format_iso_zisofs_overflow.iso.uu
@@ -0,0 +1,1096 @@
+begin 664 test_read_format_iso_zisofs_overflow.iso
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````!0T0P,#$!````````````````````````````````````````
+M````4$]#7U=2251%`````````````````````````````````````````!@`
+M```````8```````````````````````````````````````````!```!`0``
+M`0`("``*````````"A(`````````````$@`````B`!,````````3``@`````
+M"`!Z`1D,`````@```0```0$`````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````$`````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````/]#1#`P,0$`````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````0`3`````0``````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````!5`!,````````3``@`
+M````"`!Z`1D,`````@```0```0$`4U`'`;[O`%!8+`'M00````!![0(`````
+M```"``````````````````````$````````!(@`3````````$P`(``````@`
+M>@$9#`````(```$```$!`7T`%````````!00"``````($'H!&0P````````!
+M```!#D]615)&3$]7+D))3CLQ`%I&$`%P>@0"^?O__P````!.31$!`$]615)&
+M3$]7+D))3E!8+`&D@0````"!I`$````````!``````````````````````(`
+M```````"````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````#?D4Y;)V]8'^?O__P0"``!!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!
+M0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"
+M0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#
+M1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$04)#1$%"0T1!0D-$
+M04)#1```````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+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_format_lha_oversize_header.c b/libarchive/test/test_read_format_lha_oversize_header.c
new file mode 100644
index 000000000000..fbdbd671df7c
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_oversize_header.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2026 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_read_format_lha_oversize_header)
+{
+ const char *refname = "test_read_format_lha_oversize_header.lzh";
+ extract_reference_file(refname);
+ struct archive_entry *ae;
+ struct archive *a;
+
+ 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));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+
+ /* First 18 entries in the test file are well-formed */
+ for (int i = 0; i < 18; i++) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ }
+
+ /* 19th has an oversized header */
+ assertEqualInt(ARCHIVE_FATAL, archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
diff --git a/libarchive/test/test_read_format_lha_oversize_header.lzh.uu b/libarchive/test/test_read_format_lha_oversize_header.lzh.uu
new file mode 100644
index 000000000000..e562e440a777
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_oversize_header.lzh.uu
@@ -0,0 +1,60 @@
+begin 644 test_read_format_lha_oversize_header.lzh
+M)L`M;&AD+0```````````$@B[!``!&1I<EP``%4`@5$!`.A!Z0/I`R?X+6QH
+M9"T```````````!((NP0``5D:7(R7```50"!40$`[4'I`^D#.'PM;&AD+0``
+M`````````4@C[!``%F1I<C)<<WEM;&EN:S%\+BY<9FEL93$``%4``J,"`.VA
+MZ0/I`SA^+6QH9"T```````````%((^P0`!9D:7(R7'-Y;6QI;FLR?"XN7&9I
+M;&4R``!5``*C`@#MH>D#Z0,GO2UL:#4M(@```#P`````2"+L(``%9FEL93&D
+MYU4`@5$!`*2!Z0/I`P`80FYIQ>/Z`=-:'>9%#"P%J!\CH0"/GE$,.W6FMSD%
+M*_4G02UL:#4M(@```$X`````2"+L(``%9FEL93+5%54`@5$!`+:!Z0/I`P`8
+M0FYIQV/Z`=.:'.9%#"P%J-\+H0"/'E$,.W6FMSD%*_T9?RUL:&0M&@``````
+M````2"+L(`$```!5!P`"9&ER_P4`4.A!!P!1Z0/I`P<`5(%1`0```!F!+6QH
+M9"T;``````````!((NP@`0```%4(``)D:7(R_P4`4.U!!P!1Z0/I`P<`5(%1
+M`0```!YQ+6QH9"TG``````````%((^P@`05F:6QE,0``510``F1I<C+_<WEM
+M;&EN:S%\+B[_!0!0[:$'`%'I`^D#!P!4`J,"````'G(M;&AD+2<`````````
+M`4@C["`!!69I;&4R``!5%``"9&ER,O]S>6UL:6YK,GPN+O\%`%#MH0<`4>D#
+MZ0,'`%0"HP(````>!BUL:#4M-0```#P`````2"+L(`$%9FEL93&DYU4%`%"D
+M@0<`4>D#Z0,'`%2!40$`````&$)N:<7C^@'36AWF10PL!:@?(Z$`CYY1##MU
+MIK<Y!2OU'G@M;&@U+34```!.`````$@B["`!!69I;&4RU155!0!0MH$'`%'I
+M`^D#!P!4@5$!`````!A";FG'8_H!TYH<YD4,+`6HWPNA`(\>40P[=::W.04K
+M_34`+6QH9"T``````````(%1`0`@`@``504```7>`P`!!P`"9&ER_P4`4.A!
+M!P!1Z0/I`P``-@`M;&AD+0``````````@5$!`"`"``!5!0``")D#``$(``)D
+M:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD+0```````````J,"`"`"``!5!0``
+MM*D(``%F:6QE,10``F1I<C+_<WEM;&EN:S%\+B[_!0!0[:$'`%'I`^D#``!'
+M`"UL:&0M```````````"HP(`(`(``%4%``"'[0@``69I;&4R%``"9&ER,O]S
+M>6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,``#,`+6QH-2TB````/````(%1`0`@
+M`J3G504``/T!"``!9FEL93$%`%"D@0<`4>D#Z0,````80FYIQ>/Z`=-:'>9%
+M#"P%J!\CH0"/GE$,.W6FMSD%*_4S`"UL:#4M(@```$X```"!40$`(`+5%54%
+M```OQ@@``69I;&4R!0!0MH$'`%'I`^D#````&$)N:<=C^@'3FASF10PL!:C?
+M"Z$`CQY1##MUIK<Y!2O]!``M;&AD+0``````````@5$!`"`#``!-?/[___\`
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````$:D`P``!0````$)`````F1I
+M<O\'````0!``&0```/_M00`````````````,%?Y,1!K^3!T```!!S-]1M/Z5
+MRP&`UD``J+*=`0!Z#]`!ELL!"``````NKP<`````!``M;&AD+0``````````
+M@5$!`"`#``!-?0````D```!&I`,```4````!"@````)D:7(R_P<```!`$``9
+M````_^U!`````````````"$:_DQ$&OY,'0```$%*@6Z[`9;+`8#60`"HLIT!
+M`'H/T`&6RP$(`````'T7!P`````$`"UL:#4M)````#P```"!40$`(`.DYTUQ
+M````"0```$:D`P``"@````%F:6QE,1D```#_I($`````````````QQ3^3",:
+M_DP=````031"HHK^E<L!@-9``*BRG0'^<J2\`9;+`0@`````"O$'```````9
+M0FV1J+1V@'IK0ZGID/-H#J@6.H0"'V^-&353:F^XA-UZ@`0`+6QH-2TD````
+M3@```(%1`0`@`]4537$````)````1J0#```*`````69I;&4R&0```/^D@0``
+M```````````A&OY,(QK^3!T```!!_D5SNP&6RP&`UD``J+*=`5C5IKP!ELL!
+M"`````!!W@<``````!E";9&H[':`>G-#B>F0\V@.J,8:A`(>;XT9-5-J;[B$
+MW7Z`-0`M;&AD+0``````````@5$!`"`"``!5!40:_DP=````0<S?4;3^E<L!
+M@-9``*BRG0$`>@_0`9;+`0@`````+J\'``````0`+6QH9"T``````````(%1
+M`0`@`P``37T````)````1J0#```%`````0H````"9&ER,O\'````0!``&0``
+M`/_M00`````````````A&OY,1!K^3!T```!!2H%NNP&6RP&`UD``J+*=`0!Z
+M#]`!ELL!"`````!]%P<`````!``M;&@U+20````\````@5$!`"`#I.=-<0``
+M``D```!&I`,```H````!9FEL93$9````_Z2!`````````````,<4_DPC&OY,
+M'0```$$T0J**_I7+`8#60`"HLIT!_G*DO`&6RP$(``````KQ!P``````&4)M
+MD:BT=H!Z:T.IZ9!1Z0/I`P```FUK=XVV['"Z\`>$(6[`2-EZ5P&P^!J*0MPV
+M*IM]&^L37/)<Y+,0WC;RYN647;X'R_\P`E;2>[SD(6GCE`4$+,RA<%QVYXC%
+M'H1Q`I@_B\H/L@(+W3`0@5CY6X%Q%WW+@7<`8(F7=77U]%5YG?`;3N&I:_6Y
+MWA$,3F@?:)>FZ!<!"?.:#C/:',\PG@>:WRP0:TH8%&:/A#VMNUUD[D?+:#XK
+M%3NMR(PSF4;V"^\X0/E3JMRQ46+7\I]S@7ZJNTX[ROSD+=\7\.O#I:W._S>P
+M-B(W4`=N<T/$OT+5];U>*!<4AM0Y4$L'"(=02P,$\$*.O%TM;&@U+0``KPLX
+M+4``2@````````"``````/________\`````````V0````"A````````````
+M````````````+6QH-RT```!8$,P.0&OJER*:CF[S6/=2*T4J8HB@[:HP^'7*
+MK?(\7:Y+-"U'*^OXT210`,J%*>9(T9[(@N(DJ+A)A```3`]%Z8U.^3!F0_G-
+17YFUYB_%6DWMSZ8'\Z-^CR@`
+`
+end
diff --git a/libarchive/test/test_read_format_rar5_loop_bug.c b/libarchive/test/test_read_format_rar5_loop_bug.c
new file mode 100644
index 000000000000..77dd78cccc48
--- /dev/null
+++ b/libarchive/test/test_read_format_rar5_loop_bug.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2026 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_read_format_rar5_loop_bug)
+{
+ const char *reffile = "test_read_format_rar5_loop_bug.rar";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *buf;
+ size_t size;
+ la_int64_t offset;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, reffile, 10240));
+
+ // This has just one entry
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+ // Read blocks until the end of the entry
+ while (ARCHIVE_OK == archive_read_data_block(a, &buf, &size, &offset)) {
+ }
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_free(a));
+}
diff --git a/libarchive/test/test_read_format_rar5_loop_bug.rar.uu b/libarchive/test/test_read_format_rar5_loop_bug.rar.uu
new file mode 100644
index 000000000000..3e470043fb70
--- /dev/null
+++ b/libarchive/test/test_read_format_rar5_loop_bug.rar.uu
@@ -0,0 +1,189 @@
+begin 644 test_read_format_rar5_loop_bug.rar
+M4F%R(1H'`0#%&C,R`P$``)T-9%L.`@+P0`"`@`P`@`,``6'(WFP@`?\7_U/^
+M8@!.`B`H````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+5```````````````````Y^;*!`@4`
+`
+end
diff --git a/libarchive/test/test_read_set_format.c b/libarchive/test/test_read_set_format.c
index 615dd8ae8022..2ea39045201f 100644
--- a/libarchive/test/test_read_set_format.c
+++ b/libarchive/test/test_read_set_format.c
@@ -177,6 +177,40 @@ DEFINE_TEST(test_read_append_wrong_filter)
assertEqualInt(ARCHIVE_OK,archive_read_free(a));
}
+DEFINE_TEST(test_read_append_lzop_filter)
+{
+ struct archive *a;
+ int r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
+ r = archive_read_append_filter(a, ARCHIVE_FILTER_LZOP);
+ if (archive_liblzo2_version() != NULL) {
+ assertEqualIntA(a, ARCHIVE_OK, r);
+ } else if (canLzop()) {
+ // We're using an external program
+ assertEqualIntA(a, ARCHIVE_WARN, r);
+ }
+
+ archive_read_free(a);
+}
+
+DEFINE_TEST(test_read_append_grzip_filter)
+{
+ struct archive *a;
+ int r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
+ r = archive_read_append_filter(a, ARCHIVE_FILTER_GRZIP);
+ // Grzip currently always uses an external program.
+ if (canGrzip()) {
+ assertEqualIntA(a, ARCHIVE_WARN, r);
+ }
+
+ archive_read_free(a);
+}
+
DEFINE_TEST(test_read_append_filter_program)
{
struct archive_entry *ae;
diff --git a/libarchive/test/test_ustar_filename_encoding.c b/libarchive/test/test_ustar_filename_encoding.c
index 1242bd1d3cd2..440d1b99276e 100644
--- a/libarchive/test/test_ustar_filename_encoding.c
+++ b/libarchive/test/test_ustar_filename_encoding.c
@@ -492,3 +492,43 @@ DEFINE_TEST(test_ustar_filename_encoding_UTF16_win)
assertEqualMem(buff + 157, "\xE8\xA1\xA8.txt", 7);
#endif
}
+
+DEFINE_TEST(test_ustar_filename_encoding_fail_UTF16_win)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ skipping("This test is meant to verify unicode string handling"
+ " on Windows with UTF-16 names");
+ return;
+#else
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ /* Test the C locale by not calling setlocale. */
+
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP437") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from UTF-16 to CP437.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set the filename using a UTF-16 string */
+ archive_entry_copy_pathname_w(entry, L"\u8868.txt");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, entry));
+ /* The pathname cannot even be represented in the current locale
+ for inclusion in the error message. */
+ assertEqualString("Can't translate pathname to CP437",
+ archive_error_string(a));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+#endif
+}
diff --git a/libarchive/test/test_v7tar_filename_encoding.c b/libarchive/test/test_v7tar_filename_encoding.c
new file mode 100644
index 000000000000..96594b12180e
--- /dev/null
+++ b/libarchive/test/test_v7tar_filename_encoding.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2003-2025 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+#include <locale.h>
+
+DEFINE_TEST(test_v7tar_filename_encoding_fail_UTF16_win)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ skipping("This test is meant to verify unicode string handling"
+ " on Windows with UTF-16 names");
+ return;
+#else
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ /* Test the C locale by not calling setlocale. */
+
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_v7tar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP437") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from UTF-16 to CP437.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set the filename using a UTF-16 string */
+ archive_entry_copy_pathname_w(entry, L"\u8868.txt");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, entry));
+ /* The pathname cannot even be represented in the current locale
+ for inclusion in the error message. */
+ assertEqualString("Can't translate pathname to CP437",
+ archive_error_string(a));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+#endif
+}
diff --git a/libarchive/test/test_warn_missing_hardlink_target.c b/libarchive/test/test_warn_missing_hardlink_target.c
index d7fa5eb6c0fc..b3e5b95f06d4 100644
--- a/libarchive/test/test_warn_missing_hardlink_target.c
+++ b/libarchive/test/test_warn_missing_hardlink_target.c
@@ -37,7 +37,7 @@ DEFINE_TEST(test_warn_missing_hardlink_target)
assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
assertEqualInt(ENOENT, archive_errno(a));
- assertEqualString("Hard-link target 'hardlink-target' does not exist.",
+ assertEqualString("Hard-link target 'hardlink-target' does not exist",
archive_error_string(a));
archive_entry_free(ae);
diff --git a/libarchive/test/test_write_disk.c b/libarchive/test/test_write_disk.c
index fa0743f949f6..1e503cdb178a 100644
--- a/libarchive/test/test_write_disk.c
+++ b/libarchive/test/test_write_disk.c
@@ -233,6 +233,22 @@ static void create_reg_file_win(struct archive_entry *ae, const char *msg)
assertEqualInt(st.st_size, sizeof(data));
free(fname);
}
+#else
+static void create_fail(struct archive_entry *ae, int experr,
+ const char *msg)
+{
+ struct archive *ad;
+ struct stat st;
+
+ /* Write the entry to disk. */
+ assert((ad = archive_write_disk_new()) != NULL);
+ failure("%s", msg);
+ assertEqualIntA(ad, ARCHIVE_FAILED, archive_write_header(ad, ae));
+ assertEqualIntA(ad, experr, archive_errno(ad));
+ assertEqualInt(0, archive_write_free(ad));
+ assertEqualInt(-1, stat(archive_entry_pathname(ae), &st));
+ assertEqualInt(ENOENT, errno);
+}
#endif /* _WIN32 && !__CYGWIN__ */
DEFINE_TEST(test_write_disk)
@@ -344,5 +360,18 @@ DEFINE_TEST(test_write_disk)
" with unusable characters in its file name");
archive_entry_free(ae);
free(fullpath);
+#else /* !_WIN32 || __CYGWIN__ */
+ /* A directory with a /../ in the middle */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "a/b/../b/file");
+ archive_entry_set_mode(ae, S_IFREG | 0644);
+ /* First attempt should fail with EACCES */
+ assertEqualInt(0, mkdir("a", 0111));
+ create_fail(ae, EACCES,
+ "Test failing to create parent directory with /../");
+ /* Now let it succeed */
+ assertEqualInt(0, chmod("a", 0755));
+ create(ae, "Test creating parent directory with /../");
+ archive_entry_free(ae);
#endif /* _WIN32 && !__CYGWIN__ */
}
diff --git a/libarchive/test/test_write_disk_perms.c b/libarchive/test/test_write_disk_perms.c
index 72b55179d86e..4f246e9bc2f0 100644
--- a/libarchive/test/test_write_disk_perms.c
+++ b/libarchive/test/test_write_disk_perms.c
@@ -26,6 +26,13 @@
#if !defined(_WIN32) || defined(__CYGWIN__)
+#ifdef HAVE_GETEUID
+#define getuid() geteuid()
+#endif
+#ifdef HAVE_GETEGID
+#define getgid() getegid()
+#endif
+
#define UMASK 022
static long _default_gid = -1;
@@ -142,7 +149,7 @@ DEFINE_TEST(test_write_disk_perms)
* and we're on a system where group ownership is inherited.
* (Because we're not allowed to SGID files with defaultgid().)
*/
- assertEqualInt(0, chown(".", getuid(), getgid()));
+ assertChown(".", getuid(), getgid());
/* Create an archive_write_disk object. */
assert((a = archive_write_disk_new()) != NULL);
@@ -208,7 +215,7 @@ DEFINE_TEST(test_write_disk_perms)
if (getuid() == 0) {
original_uid = getuid() + 1;
try_to_change_uid = getuid();
- assertEqualInt(0, chown("dir_owner", original_uid, getgid()));
+ assertChown("dir_owner", original_uid, getgid());
} else {
original_uid = getuid();
try_to_change_uid = getuid() + 1;
diff --git a/libarchive/test/test_zip_filename_encoding.c b/libarchive/test/test_zip_filename_encoding.c
index b6786f2c3b18..1cb394547066 100644
--- a/libarchive/test/test_zip_filename_encoding.c
+++ b/libarchive/test/test_zip_filename_encoding.c
@@ -622,3 +622,43 @@ DEFINE_TEST(test_zip_filename_encoding_UTF16_win)
/* NOTE: ZIP does not support hardlinks */
#endif
}
+
+DEFINE_TEST(test_zip_filename_encoding_fail_UTF16_win)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ skipping("This test is meant to verify unicode string handling"
+ " on Windows with UTF-16 names");
+ return;
+#else
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ /* Test the C locale by not calling setlocale. */
+
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=CP437") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from UTF-16 to CP437.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set the filename using a UTF-16 string */
+ archive_entry_copy_pathname_w(entry, L"\u8868.txt");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, entry));
+ /* The pathname cannot even be represented in the current locale
+ for inclusion in the error message. */
+ assertEqualString("Can't translate pathname to CP437",
+ archive_error_string(a));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+#endif
+}
diff --git a/unzip/la_getline.c b/libarchive_fe/lafe_getline.c
index 40ab35cde842..ebd9f1a894a7 100644
--- a/unzip/la_getline.c
+++ b/libarchive_fe/lafe_getline.c
@@ -7,12 +7,15 @@
* All rights reserved.
*/
-#include "bsdunzip_platform.h"
+#include "lafe_platform.h"
#ifndef HAVE_GETLINE
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
@@ -26,8 +29,10 @@
#include <string.h>
#endif
+#include "lafe_getline.h"
+
static ssize_t
-la_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
+lafe_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
{
char *ptr, *eptr;
@@ -72,6 +77,6 @@ la_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
ssize_t
getline(char **buf, size_t *bufsiz, FILE *fp)
{
- return la_getdelim(buf, bufsiz, '\n', fp);
+ return lafe_getdelim(buf, bufsiz, '\n', fp);
}
#endif
diff --git a/unzip/la_getline.h b/libarchive_fe/lafe_getline.h
index d7588731943d..b10641ffd1eb 100644
--- a/unzip/la_getline.h
+++ b/libarchive_fe/lafe_getline.h
@@ -5,12 +5,19 @@
* All rights reserved.
*/
-#ifndef LA_GETLINE_H_INCLUDED
-#define LA_GETLINE_H_INCLUDED
+#ifndef LAFE_GETLINE_H_INCLUDED
+#define LAFE_GETLINE_H_INCLUDED
+
+#include "lafe_platform.h"
-#include <stdio.h>
#ifndef HAVE_GETLINE
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
ssize_t getline(char **buf, size_t *bufsiz, FILE *fp);
#endif
-#endif /* !LA_GETLINE_H_INCLUDED */
+#endif /* !LAFE_GETLINE_H_INCLUDED */
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index 92e86fd6bd94..fbc0627a83b9 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -525,28 +525,28 @@ main(int argc, char **argv)
if (archive_match_include_date(bsdtar->matching,
ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_NEWER_CTIME_THAN:
if (archive_match_include_file_time(bsdtar->matching,
ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_NEWER_MTIME: /* GNU tar */
if (archive_match_include_date(bsdtar->matching,
ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_NEWER_MTIME_THAN:
if (archive_match_include_file_time(bsdtar->matching,
ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_NODUMP: /* star */
@@ -618,28 +618,28 @@ main(int argc, char **argv)
if (archive_match_include_date(bsdtar->matching,
ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_OLDER_CTIME_THAN:
if (archive_match_include_file_time(bsdtar->matching,
ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_OLDER_MTIME:
if (archive_match_include_date(bsdtar->matching,
ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_OLDER_MTIME_THAN:
if (archive_match_include_file_time(bsdtar->matching,
ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER,
bsdtar->argument) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case OPTION_ONE_FILE_SYSTEM: /* GNU tar */
@@ -819,7 +819,7 @@ main(int argc, char **argv)
if (archive_match_exclude_pattern_from_file(
bsdtar->matching, bsdtar->argument, 0)
!= ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
break;
case 'x': /* SUSv2 */
@@ -1026,7 +1026,7 @@ main(int argc, char **argv)
if (bsdtar->return_value != 0)
lafe_warnc(0,
- "Error exit delayed from previous errors.");
+ "Error exit delayed from previous errors");
return (bsdtar->return_value);
}
diff --git a/tar/read.c b/tar/read.c
index 7cbcfb19ff0a..4acbf6b2a9dc 100644
--- a/tar/read.c
+++ b/tar/read.c
@@ -255,7 +255,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
break;
p = archive_entry_pathname(entry);
if (p == NULL || p[0] == '\0') {
- lafe_warnc(0, "Archive entry has empty or unreadable filename ... skipping.");
+ lafe_warnc(0, "Archive entry has empty or unreadable filename ... skipping");
bsdtar->return_value = 1;
continue;
}
diff --git a/tar/util.c b/tar/util.c
index 6e41e49de133..6b21e8aeff2b 100644
--- a/tar/util.c
+++ b/tar/util.c
@@ -715,8 +715,8 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
/* Use uname if it's present, else uid. */
p = archive_entry_uname(entry);
if ((p == NULL) || (*p == '\0')) {
- snprintf(tmp, sizeof(tmp), "%lu ",
- (unsigned long)archive_entry_uid(entry));
+ snprintf(tmp, sizeof(tmp), "%lld ",
+ (long long)archive_entry_uid(entry));
p = tmp;
}
w = strlen(p);
@@ -730,8 +730,8 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
fprintf(out, "%s", p);
w = strlen(p);
} else {
- snprintf(tmp, sizeof(tmp), "%lu",
- (unsigned long)archive_entry_gid(entry));
+ snprintf(tmp, sizeof(tmp), "%lld",
+ (long long)archive_entry_gid(entry));
w = strlen(tmp);
fprintf(out, "%s", tmp);
}
diff --git a/tar/write.c b/tar/write.c
index b39a397707ba..abff3831bcda 100644
--- a/tar/write.c
+++ b/tar/write.c
@@ -301,7 +301,7 @@ tar_mode_r(struct bsdtar *bsdtar)
archive_read_free(a);
close(bsdtar->fd);
lafe_errc(1, 0,
- "Cannot append to compressed archive.");
+ "Cannot append to compressed archive");
}
/* Keep going until we hit end-of-archive */
format = archive_format(a);
@@ -329,7 +329,7 @@ tar_mode_r(struct bsdtar *bsdtar)
if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK)
&& format != ARCHIVE_FORMAT_EMPTY) {
lafe_errc(1, 0,
- "Format %s is incompatible with the archive %s.",
+ "Format %s is incompatible with the archive %s",
cset_get_format(bsdtar->cset), bsdtar->filename);
}
} else {
@@ -394,12 +394,12 @@ tar_mode_u(struct bsdtar *bsdtar)
archive_read_free(a);
close(bsdtar->fd);
lafe_errc(1, 0,
- "Cannot append to compressed archive.");
+ "Cannot append to compressed archive");
}
if (archive_match_exclude_entry(bsdtar->matching,
ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
ARCHIVE_MATCH_EQUAL, entry) != ARCHIVE_OK)
- lafe_errc(1, 0, "Error : %s",
+ lafe_errc(1, 0, "%s",
archive_error_string(bsdtar->matching));
/* Record the last format determination we see */
format = archive_format(a);
@@ -786,7 +786,7 @@ copy_file_data_block(struct bsdtar *bsdtar, struct archive *a,
* continue. */
lafe_warnc(0,
"%s: Truncated write; file may "
- "have grown while being archived.",
+ "have grown while being archived",
archive_entry_pathname(entry));
return (0);
}
@@ -805,7 +805,7 @@ copy_file_data_block(struct bsdtar *bsdtar, struct archive *a,
/* Write was truncated; warn but continue. */
lafe_warnc(0,
"%s: Truncated write; file may have grown "
- "while being archived.",
+ "while being archived",
archive_entry_pathname(entry));
return (0);
}
@@ -1052,14 +1052,14 @@ test_for_append(struct bsdtar *bsdtar)
if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
lafe_errc(1, 0, "no files or directories specified");
if (bsdtar->filename == NULL)
- lafe_errc(1, 0, "Cannot append to stdout.");
+ lafe_errc(1, 0, "Cannot append to stdout");
if (stat(bsdtar->filename, &s) != 0)
return;
if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode))
lafe_errc(1, 0,
- "Cannot append to %s: not a regular file.",
+ "Cannot append to %s: not a regular file",
bsdtar->filename);
/* Is this an appropriate check here on Windows? */
diff --git a/test_utils/test_common.h b/test_utils/test_common.h
index a9df300e3be8..2f19597dee6b 100644
--- a/test_utils/test_common.h
+++ b/test_utils/test_common.h
@@ -163,6 +163,9 @@
/* change file/directory permissions and errors if it fails */
#define assertChmod(pathname, mode) \
assertion_chmod(__FILE__, __LINE__, pathname, mode)
+/* change file/directory ownership and errors if it fails */
+#define assertChown(pathname, user, group) \
+ assertion_chown(__FILE__, __LINE__, pathname, user, group)
/* Assert two files have the same file flags */
#define assertEqualFflags(patha, pathb) \
assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0)
@@ -279,6 +282,7 @@ void failure(const char *fmt, ...) __LA_PRINTFLIKE(1, 2);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_chmod(const char *, int, const char *, int);
+int assertion_chown(const char *, int, const char *, int, int);
int assertion_compare_fflags(const char *, int, const char *, const char *,
int);
int assertion_empty_file(const char *, int, const char *);
diff --git a/test_utils/test_main.c b/test_utils/test_main.c
index dbd3fcf60e9a..1f641bbe8db7 100644
--- a/test_utils/test_main.c
+++ b/test_utils/test_main.c
@@ -96,6 +96,12 @@ extern char **environ;
# define USE_POSIX_SPAWN 1
# endif
#endif
+#if !defined(_WIN32)
+# if HAVE_PWD_H && HAVE_GETEUID && HAVE_GETEGID
+# include <pwd.h>
+# define RUN_TEST_UNPRIV 1
+# endif
+#endif
#ifndef nitems
#define nitems(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -179,6 +185,14 @@ const char *testprogfile;
const char *testprog;
#endif
+#ifdef RUN_TEST_UNPRIV
+/* Unprivileged user to run as */
+const char *tuser = "nobody";
+/* Original and test credentials */
+uid_t ouid, tuid;
+uid_t ogid, tgid;
+#endif
+
#if defined(_WIN32) && !defined(__CYGWIN__)
static void *GetFunctionKernel32(const char *);
static int my_CreateSymbolicLinkA(const char *, const char *, int);
@@ -632,6 +646,22 @@ assertion_chmod(const char *file, int line, const char *pathname, int mode)
}
+/* change file/directory ownership and errors if it fails */
+int
+assertion_chown(const char *file, int line, const char *pathname, int user,
+ int group)
+{
+ assertion_count(file, line);
+#ifdef HAVE_CHOWN
+ if (chown(pathname, (uid_t)user, (gid_t)group) == 0)
+ return (1);
+#endif
+ failure_start(file, line, "chown(\"%s\", %d, %d)", pathname,
+ user, group);
+ failure_finish(NULL);
+ return (0);
+}
+
/* Verify two integers are equal. */
int
assertion_equal_int(const char *file, int line,
@@ -3610,8 +3640,11 @@ test_run(int i, const char *tmpdir)
exit(1);
}
testworkdir = workdir;
- if (!assertMakeDir(testworkdir, 0755)
- || !assertChdir(testworkdir)) {
+ if (!assertMakeDir(testworkdir, 0755) ||
+#ifdef RUN_TEST_UNPRIV
+ (tuser != NULL && !assertChown(testworkdir, tuid, tgid)) ||
+#endif
+ !assertChdir(testworkdir)) {
fprintf(stderr,
"ERROR: Can't chdir to work dir %s\n", testworkdir);
exit(1);
@@ -3620,10 +3653,28 @@ test_run(int i, const char *tmpdir)
set_c_locale();
/* Record the umask before we run the test. */
umask(oldumask = umask(0));
+#ifdef RUN_TEST_UNPRIV
+ /*
+ * Temporarily drop privileges.
+ */
+ if (tuser != NULL) {
+ (void)setegid(tuid);
+ (void)seteuid(tuid);
+ }
+#endif
/*
* Run the actual test.
*/
(*tests[i].func)();
+#ifdef RUN_TEST_UNPRIV
+ /*
+ * Restore original credentials.
+ */
+ if (tuser != NULL) {
+ (void)seteuid(ouid);
+ (void)setegid(ogid);
+ }
+#endif
/*
* Clean up and report afterwards.
*/
@@ -3949,6 +4000,9 @@ main(int argc, char **argv)
#endif
char *pwd, *testprogdir, *tmp2 = NULL, *vlevel = NULL;
char tmpdir_timestamp[32];
+#ifdef RUN_TEST_UNPRIV
+ struct passwd *pw;
+#endif
(void)argc; /* UNUSED */
@@ -4110,6 +4164,11 @@ main(int argc, char **argv)
case 's':
fail_if_tests_skipped = 1;
break;
+#ifdef RUN_TEST_UNPRIV
+ case 'U':
+ tuser = optarg;
+ break;
+#endif
case 'u':
until_failure++;
break;
@@ -4194,6 +4253,28 @@ main(int argc, char **argv)
}
#endif
+#ifdef RUN_TEST_UNPRIV
+ /*
+ * Check if we are root, and get user to run as.
+ */
+ ouid = getuid();
+ ogid = getgid();
+ if (ouid == 0) {
+ if ((pw = getpwnam(tuser)) == NULL) {
+ fprintf(stderr, "ERROR: Unknown user %s\n", tuser);
+ exit(1);
+ }
+ tuid = pw->pw_uid;
+ tgid = pw->pw_gid;
+ printf("Will switch to user %s (uid %d gid %d)\n", tuser,
+ tuid, tgid);
+ } else {
+ tuser = NULL;
+ tuid = ouid;
+ tgid = ogid;
+ }
+#endif
+
/*
* Create a temp directory for the following tests.
* Include the time the tests started as part of the name,
diff --git a/unzip/CMakeLists.txt b/unzip/CMakeLists.txt
index f3c62cb339c6..9fe21eeebe0a 100644
--- a/unzip/CMakeLists.txt
+++ b/unzip/CMakeLists.txt
@@ -13,11 +13,11 @@ IF(ENABLE_UNZIP)
bsdunzip.h
bsdunzip_platform.h
cmdline.c
- la_getline.c
- la_getline.h
la_queue.h
../libarchive_fe/lafe_err.c
../libarchive_fe/lafe_err.h
+ ../libarchive_fe/lafe_getline.c
+ ../libarchive_fe/lafe_getline.h
../libarchive_fe/lafe_platform.h
../libarchive_fe/passphrase.c
../libarchive_fe/passphrase.h
diff --git a/unzip/bsdunzip.c b/unzip/bsdunzip.c
index 14bd418f169c..aa849568ba7e 100644
--- a/unzip/bsdunzip.c
+++ b/unzip/bsdunzip.c
@@ -9,7 +9,7 @@
#include "bsdunzip_platform.h"
#include "la_queue.h"
-#include "la_getline.h"
+#include "lafe_getline.h"
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
@@ -884,9 +884,9 @@ list(struct archive *a, struct archive_entry *e)
mtime = archive_entry_mtime(e);
tm = localtime(&mtime);
if (*y_str)
- strftime(buf, sizeof(buf), "%m-%d-%G %R", tm);
+ strftime(buf, sizeof(buf), "%m-%d-%Y %R", tm);
else
- strftime(buf, sizeof(buf), "%m-%d-%g %R", tm);
+ strftime(buf, sizeof(buf), "%m-%d-%y %R", tm);
pathname = archive_entry_pathname(e);
if (!pathname)
diff --git a/unzip/test/CMakeLists.txt b/unzip/test/CMakeLists.txt
index 57ed651a58b0..45138202a9a3 100644
--- a/unzip/test/CMakeLists.txt
+++ b/unzip/test/CMakeLists.txt
@@ -13,6 +13,7 @@ IF(ENABLE_UNZIP AND ENABLE_TEST)
test_basic.c
test_doubledash.c
test_glob.c
+ test_not_exist.c
test_singlefile.c
test_C.c
test_p.c