1
0
mirror of https://git.FreeBSD.org/src.git synced 2026-06-02 11:24:32 +00:00

Update vendor/libarchive to 3.8.7

Important bugfixes between 3.8.6 and 3.8.7:
 #2871 libarchive: fix handling of option failures
 #2897 iso9660: fix undefined behavior
 #2898 RAR: fix LZSS window size mismatch after PPMd block
 #2900 CAB: fix NULL pointer dereference during skip
 #2911 libarchive: do not continue with truncated numbers
 #2919 CAB: Fix Heap OOB Write in CAB LZX decoder
 #2934 iso9660: fix posibble heap buffer overflow on 32-bit systems
 #2939 cpio: Fix -R memory leak
 #2947 libarchive: lzop and grzip filter support

Important bugfixes between 3.8.5 and 3.8.6:
 #2860 bsdunzip: fix ISO week year and Gregorian year confusion
 #2864 7zip: ix SEGV in check_7zip_header_in_sfx via ELF offset validation
 #2875 7zip: fix out-of-bounds access on ELF 64-bit header
 #2877 RAR5 reader: fix infinite loop in rar5 decompression
 #2878 mtree reader: Fix file descriptor leak in mtree parser cleanup
       (CWE-775)
 #2892 RAR5 reader: fix potential memory leak
 #2893 RAR5: fix SIGSEGV when archive_read_support_format_rar5 is called
       twice
 #2895 CAB reader: fix memory leak on repeated calls to
       archive_read_support_format_cab

Obtained from:	libarchive
Vendor commit:	ded82291ab41d5e355831b96b0e1ff49e24d8939
This commit is contained in:
Martin Matuska
2026-04-13 15:22:49 +02:00
parent 01333e8c4d
commit f2cd95a372
108 changed files with 3065 additions and 403 deletions
+7 -12
View File
@@ -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:
+1
View File
@@ -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)
+14 -3
View File
@@ -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+=
+4
View File
@@ -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
+6 -3
View File
@@ -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
+6
View File
@@ -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
+1 -1
View File
@@ -1 +1 @@
3008005
3008007
+2 -2
View File
@@ -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())
+1
View File
@@ -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
@@ -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]);
+2 -2
View File
@@ -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;
+2
View File
@@ -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
+11 -4
View File
@@ -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);
+67 -56
View File
@@ -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
-2
View File
@@ -71,8 +71,6 @@ struct cpio {
/* Work data. */
struct archive *matching;
char *buff;
size_t buff_size;
char *ppbuff;
};
+7
View File
@@ -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
+2 -2
View File
@@ -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);
+5 -1
View File
@@ -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':
+2 -2
View File
@@ -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;
+4
View File
@@ -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;
+1 -1
View File
@@ -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
+6
View File
@@ -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
+3 -1
View File
@@ -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;
}
+2 -2
View File
@@ -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;
}
+11 -11
View File
@@ -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)
-25
View File
@@ -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
{
+6 -6
View File
@@ -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);
+4
View File
@@ -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");
+3 -3
View File
@@ -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) {
+3 -3
View File
@@ -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) {
+4 -3
View File
@@ -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;
@@ -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);
+2 -2
View File
@@ -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);
}
@@ -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);
@@ -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);
}
+16 -8
View File
@@ -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 -=
+18 -6
View File
@@ -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) {
@@ -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;
}
@@ -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
+9 -2
View File
@@ -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);
@@ -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;
+40 -33
View File
@@ -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;
+29 -16
View File
@@ -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;
}
+3 -3
View File
@@ -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);
}
+7 -7
View File
@@ -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);
+11 -11
View File
@@ -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);
+13 -3
View File
@@ -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;
+1 -1
View File
@@ -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);
}
@@ -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;
}
+5 -2
View File
@@ -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
+9 -3
View File
@@ -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);
}
+15 -6
View File
@@ -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);
}
+10 -4
View File
@@ -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);
}
+5 -2
View File
@@ -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);
}
+19 -3
View File
@@ -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;
}
+22 -9
View File
@@ -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);
errno = 0;
data->threads = (int)strtoul(value, &endptr, 10);
if (errno != 0 || *endptr != '\0') {
data->threads = 1;
return (ARCHIVE_WARN);
if (value == NULL) {
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
"threads option requires an argument");
return (ARCHIVE_FAILED);
}
errno = 0;
val = strtoul(value, &endptr, 10);
if (errno != 0 || *endptr != '\0' || val > (unsigned)INT_MAX) {
data->threads = 1;
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();
+38 -14
View File
@@ -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);
+19 -11
View File
@@ -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__ */
+1 -1
View File
@@ -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);
}
+7 -2
View File
@@ -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) {
@@ -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;
}
@@ -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;
}
@@ -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;
}
+29 -5
View File
@@ -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);
@@ -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;
+1 -1
View File
@@ -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);
}
+3 -3
View File
@@ -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);
+20 -7
View File
@@ -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);
+22 -5
View File
@@ -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);
+4 -2
View File
@@ -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();
+37 -12
View File
@@ -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);
+6
View File
@@ -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
+23
View File
@@ -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);
}
+18
View File
@@ -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));
}
@@ -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__)
@@ -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
}
+26
View File
@@ -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;
@@ -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();
}
@@ -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
@@ -0,0 +1,5 @@
begin 664 test_read_format_7zip_sfx_elf64trunc.elf
M?T5,1@("````````````````````````````````````````````````````
2```````````````````H``$`
`
end
@@ -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));
}
@@ -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
@@ -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);
}
@@ -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
@@ -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));
}
File diff suppressed because it is too large Load Diff
@@ -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));
}
@@ -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
@@ -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));
}
@@ -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
+34
View File
@@ -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;
@@ -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
}
@@ -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
}
@@ -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);
+29
View File
@@ -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__ */
}
+9 -2
View File
@@ -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;
@@ -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
}
@@ -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
@@ -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 */
+10 -10
View File
@@ -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);
}

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