1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-05-08 14:29:03 +08:00

Merge branch 'upstream-LibArchive' into update-libarchive

* upstream-LibArchive:
  LibArchive 2025-03-30 (8a7a9cc5)
This commit is contained in:
Brad King 2025-04-30 11:16:49 -04:00
commit c10c626aca
35 changed files with 464 additions and 240 deletions

View File

@ -1,21 +1,8 @@
#
IF(0) # CMake handles policy settings in its own build.
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
if(APPLE AND CMAKE_VERSION VERSION_LESS "3.17.0")
message(WARNING "CMake>=3.17.0 required to make the generated shared library have the same Mach-O headers as autotools")
endif()
if(POLICY CMP0065)
cmake_policy(SET CMP0065 NEW) #3.4 don't use `-rdynamic` with executables
endif()
if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``<PackageName>_ROOT`` variables.
endif()
if(POLICY CMP0075)
cmake_policy(SET CMP0075 NEW) #3.12.0 `check_include_file()`` and friends use ``CMAKE_REQUIRED_LIBRARIES``.
endif()
cmake_minimum_required(VERSION 3.17 FATAL_ERROR)
ENDIF()
#
PROJECT(libarchive C)
#
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
@ -318,18 +305,6 @@ IF(WIN32)
SET(NTDDI_VERSION 0x06000100)
SET(_WIN32_WINNT 0x0600)
SET(WINVER 0x0600)
ELSEIF(WINDOWS_VERSION STREQUAL "VISTA")
SET(NTDDI_VERSION 0x06000000)
SET(_WIN32_WINNT 0x0600)
SET(WINVER 0x0600)
ELSEIF(WINDOWS_VERSION STREQUAL "WS03")
SET(NTDDI_VERSION 0x05020000)
SET(_WIN32_WINNT 0x0502)
SET(WINVER 0x0502)
ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
SET(NTDDI_VERSION 0x05010000)
SET(_WIN32_WINNT 0x0501)
SET(WINVER 0x0501)
ELSE(WINDOWS_VERSION STREQUAL "WIN10")
# Default to Windows Server 2003 API if we don't recognize the specifier
SET(NTDDI_VERSION 0x05020000)
@ -1554,6 +1529,8 @@ CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN)
CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
CHECK_FUNCTION_EXISTS_GLIBC(sysconf HAVE_SYSCONF)
CHECK_FUNCTION_EXISTS_GLIBC(tcgetattr HAVE_TCGETATTR)
CHECK_FUNCTION_EXISTS_GLIBC(tcsetattr HAVE_TCSETATTR)
CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT)
@ -1563,9 +1540,9 @@ CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES)
CHECK_FUNCTION_EXISTS_GLIBC(utimensat HAVE_UTIMENSAT)
CHECK_FUNCTION_EXISTS_GLIBC(vfork HAVE_VFORK)
CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB)
CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
check_symbol_exists(wcscmp wchar.h HAVE_WCSCMP)
check_symbol_exists(wcscpy wchar.h HAVE_WCSCPY)
check_symbol_exists(wcslen wchar.h HAVE_WCSLEN)
CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
@ -2166,11 +2143,6 @@ IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF(MSVC)
IF(APPLE)
# CC_MD5_Init() functions are deprecated on macOS 10.15, but we want to use them
ADD_DEFINITIONS(-Wno-deprecated-declarations)
ENDIF(APPLE)
OPTION(DONT_FAIL_ON_CRC_ERROR "Ignore CRC errors during parsing (For fuzzing)" OFF)
IF(DONT_FAIL_ON_CRC_ERROR)
ADD_DEFINITIONS(-DDONT_FAIL_ON_CRC_ERROR=1)

View File

@ -19,13 +19,13 @@
# xdg-open coverage/index.html
#################################################################
# Find programs we need
# Find programs we need
FIND_PROGRAM(LCOV_EXECUTABLE lcov DOC "Full path to lcov executable")
FIND_PROGRAM(GENHTML_EXECUTABLE genhtml DOC "Full path to genhtml executable")
MARK_AS_ADVANCED(LCOV_EXECUTABLE GENHTML_EXECUTABLE)
# Check, compiler, build types and programs are available
IF(NOT CMAKE_COMPILER_IS_GNUCC)
IF(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU")
MESSAGE(FATAL_ERROR "Coverage can only be built on GCC")
ELSEIF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
MESSAGE(FATAL_ERROR "Coverage can only be built in Debug mode")
@ -33,7 +33,7 @@ ELSEIF(NOT LCOV_EXECUTABLE)
MESSAGE(FATAL_ERROR "lcov executable not found")
ELSEIF(NOT GENHTML_EXECUTABLE)
MESSAGE(FATAL_ERROR "genhtml executable not found")
ENDIF(NOT CMAKE_COMPILER_IS_GNUCC)
ENDIF()
# Enable testing if not already done
SET(ENABLE_TEST ON)

View File

@ -519,9 +519,6 @@
/* Define to 1 if you have the `lzma' library (-llzma). */
#cmakedefine HAVE_LIBLZMA 1
/* Define to 1 if you have the `lzmadec' library (-llzmadec). */
#cmakedefine HAVE_LIBLZMADEC 1
/* Define to 1 if you have the `lzo2' library (-llzo2). */
#cmakedefine HAVE_LIBLZO2 1
@ -631,9 +628,6 @@
/* Define to 1 if you have the <lz4.h> header file. */
#cmakedefine HAVE_LZ4_H 1
/* Define to 1 if you have the <lzmadec.h> header file. */
#cmakedefine HAVE_LZMADEC_H 1
/* Define to 1 if you have the <lzma.h> header file. */
#cmakedefine HAVE_LZMA_H 1
@ -953,6 +947,12 @@
/* Define to 1 if you have the <sys/xattr.h> header file. */
#cmakedefine HAVE_SYS_XATTR_H 1
/* Define to 1 if you have the `tcgetattr' function. */
#cmakedefine HAVE_TCGETATTR 1
/* Define to 1 if you have the `tcsetattr' function. */
#cmakedefine HAVE_TCSETATTR 1
/* Define to 1 if you have the `timegm' function. */
#cmakedefine HAVE_TIMEGM 1

View File

@ -1 +1 @@
3007007
3007009

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 3007007
#define ARCHIVE_VERSION_NUMBER 3007009
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@ -152,7 +152,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.7.7"
#define ARCHIVE_VERSION_ONLY_STRING "3.7.9"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);

View File

@ -196,6 +196,13 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
// These functions are available in macOS 10.4 and later, but deprecated from 10.15 onwards.
// We need to continue supporting this feature regardless, so suppress the warnings.
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
static int
__archive_md5init(archive_md5_ctx *ctx)
{
@ -218,6 +225,10 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
return (ARCHIVE_OK);
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
static int

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 3007007
#define ARCHIVE_VERSION_NUMBER 3007009
/*
* Note: archive_entry.h is for use outside of libarchive; the

View File

@ -61,6 +61,11 @@
# endif
#endif
/* For cygwin, to avoid missing LONG, ULONG, PUCHAR, ... definitions */
#ifdef __CYGWIN__
#include <windef.h>
#endif
/* It should be possible to get rid of this by extending the feature-test
* macros to cover Windows API functions, probably along with non-trivial
* refactoring of code to find structures that sit more cleanly on top of

View File

@ -287,9 +287,14 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
return AllocUnitsRare(p, indx);
}
#define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
#define MyMem12Cpy(dest, src, num) do { \
UInt32 *d = (UInt32 *)dest; \
const UInt32 *s = (const UInt32 *)src; \
UInt32 n = num; \
do { \
d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; \
} while(--n); \
} while (0)
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{

View File

@ -246,9 +246,14 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx)
return AllocUnitsRare(p, indx);
}
#define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); }
#define MyMem12Cpy(dest, src, num) do { \
UInt32 *d = (UInt32 *)dest; \
const UInt32 *z = (const UInt32 *)src; \
UInt32 n = num; \
do { \
d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; \
} while (--n); \
} while (0)
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{
@ -348,7 +353,9 @@ static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
(p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
}
#define RESET_TEXT(offs) { p->Text = p->Base + p->AlignOffset + (offs); }
#define RESET_TEXT(offs) do { \
p->Text = p->Base + p->AlignOffset + (offs); \
} while (0)
static void RestartModel(CPpmd8 *p)
{

View File

@ -109,8 +109,12 @@ typedef struct
Byte Count; /* Count to next change of Shift */
} CPpmd_See;
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
#define Ppmd_See_Update(p) do { \
if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) { \
(p)->Summ <<= 1; \
(p)->Count = (Byte)(3 << (p)->Shift++); \
} \
} while (0)
typedef struct
{
@ -144,8 +148,12 @@ typedef
#endif
CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \
{ unsigned j; for (j = 0; j < 256 / sizeof(p[0]); j += 8) { \
p[j+7] = p[j+6] = p[j+5] = p[j+4] = p[j+3] = p[j+2] = p[j+1] = p[j+0] = ~(size_t)0; }}
#define PPMD_SetAllBitsIn256Bytes(p) do { \
unsigned j; \
for (j = 0; j < 256 / sizeof(p[0]); j += 8) { \
p[j+7] = p[j+6] = p[j+5] = p[j+4] = \
p[j+3] = p[j+2] = p[j+1] = p[j+0] = ~(size_t)0; \
} \
} while (0)
#endif

View File

@ -96,6 +96,10 @@ archive_read_append_filter(struct archive *_a, int code)
strcpy(str, "lzip");
r1 = archive_read_support_filter_lzip(_a);
break;
case ARCHIVE_FILTER_LZOP:
strcpy(str, "lzop");
r1 = archive_read_support_filter_lzop(_a);
break;
case ARCHIVE_FILTER_LRZIP:
strcpy(str, "lrzip");
r1 = archive_read_support_filter_lrzip(_a);

View File

@ -888,7 +888,7 @@ setup_sparse_fiemap(struct archive_read_disk *a,
count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
fm = (struct fiemap *)buff;
fm->fm_start = 0;
fm->fm_length = ~0ULL;;
fm->fm_length = ~0ULL;
fm->fm_flags = FIEMAP_FLAG_SYNC;
fm->fm_extent_count = count;
do_fiemap = 1;

View File

@ -56,9 +56,10 @@ struct read_FILE_data {
char can_skip;
};
static int file_close(struct archive *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
static int64_t file_skip(struct archive *, void *, int64_t request);
static int FILE_close(struct archive *, void *);
static ssize_t FILE_read(struct archive *, void *, const void **buff);
static int64_t FILE_seek(struct archive *, void *, int64_t, int);
static int64_t FILE_skip(struct archive *, void *, int64_t);
int
archive_read_open_FILE(struct archive *a, FILE *f)
@ -69,7 +70,7 @@ archive_read_open_FILE(struct archive *a, FILE *f)
void *b;
archive_clear_error(a);
mine = malloc(sizeof(*mine));
mine = calloc(1, sizeof(*mine));
b = malloc(block_size);
if (mine == NULL || b == NULL) {
archive_set_error(a, ENOMEM, "No memory");
@ -90,22 +91,22 @@ archive_read_open_FILE(struct archive *a, FILE *f)
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
/* Enable the seek optimization only for regular files. */
mine->can_skip = 1;
} else
mine->can_skip = 0;
}
#if defined(__CYGWIN__) || defined(_WIN32)
setmode(fileno(mine->f), O_BINARY);
#endif
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
archive_read_set_close_callback(a, file_close);
archive_read_set_read_callback(a, FILE_read);
archive_read_set_skip_callback(a, FILE_skip);
archive_read_set_seek_callback(a, FILE_seek);
archive_read_set_close_callback(a, FILE_close);
archive_read_set_callback_data(a, mine);
return (archive_read_open1(a));
}
static ssize_t
file_read(struct archive *a, void *client_data, const void **buff)
FILE_read(struct archive *a, void *client_data, const void **buff)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
size_t bytes_read;
@ -119,13 +120,13 @@ file_read(struct archive *a, void *client_data, const void **buff)
}
static int64_t
file_skip(struct archive *a, void *client_data, int64_t request)
FILE_skip(struct archive *a, void *client_data, int64_t request)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
#if HAVE_FSEEKO
off_t skip = (off_t)request;
#elif HAVE__FSEEKI64
#if HAVE__FSEEKI64
int64_t skip = request;
#elif HAVE_FSEEKO
off_t skip = (off_t)request;
#else
long skip = (long)request;
#endif
@ -167,8 +168,57 @@ file_skip(struct archive *a, void *client_data, int64_t request)
return (request);
}
/*
* TODO: Store the offset and use it in the read callback.
*/
static int64_t
FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
#if HAVE__FSEEKI64
int64_t skip = request;
#elif HAVE_FSEEKO
off_t skip = (off_t)request;
#else
long skip = (long)request;
#endif
int skip_bits = sizeof(skip) * 8 - 1;
(void)a; /* UNUSED */
/* If request is too big for a long or an off_t, reduce it. */
if (sizeof(request) > sizeof(skip)) {
int64_t max_skip =
(((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
if (request > max_skip)
skip = max_skip;
}
#ifdef __ANDROID__
/* Newer Android versions have fseeko...to meditate. */
int64_t ret = lseek(fileno(mine->f), skip, whence);
if (ret >= 0) {
return ret;
}
#elif HAVE__FSEEKI64
if (_fseeki64(mine->f, skip, whence) == 0) {
return _ftelli64(mine->f);
}
#elif HAVE_FSEEKO
if (fseeko(mine->f, skip, whence) == 0) {
return ftello(mine->f);
}
#else
if (fseek(mine->f, skip, whence) == 0) {
return ftell(mine->f);
}
#endif
/* If we arrive here, the input is corrupted or truncated so fail. */
archive_set_error(a, errno, "Error seeking in FILE* pointer");
return (ARCHIVE_FATAL);
}
static int
file_close(struct archive *a, void *client_data)
FILE_close(struct archive *a, void *client_data)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;

View File

@ -303,7 +303,7 @@ file_open(struct archive *a, void *client_data)
}
if (fd < 0) {
archive_set_error(a, errno,
"Failed to open '%S'", wfilename);
"Failed to open '%ls'", wfilename);
return (ARCHIVE_FATAL);
}
#else
@ -315,7 +315,7 @@ file_open(struct archive *a, void *client_data)
if (fstat(fd, &st) != 0) {
#if defined(_WIN32) && !defined(__CYGWIN__)
if (mine->filename_type == FNT_WCS)
archive_set_error(a, errno, "Can't stat '%S'",
archive_set_error(a, errno, "Can't stat '%ls'",
wfilename);
else
#endif
@ -447,7 +447,7 @@ file_read(struct archive *a, void *client_data, const void **buff)
"Error reading '%s'", mine->filename.m);
else
archive_set_error(a, errno,
"Error reading '%S'", mine->filename.w);
"Error reading '%ls'", mine->filename.w);
}
return (bytes_read);
}
@ -509,7 +509,7 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
archive_set_error(a, errno, "Error seeking in '%s'",
mine->filename.m);
else
archive_set_error(a, errno, "Error seeking in '%S'",
archive_set_error(a, errno, "Error seeking in '%ls'",
mine->filename.w);
return (-1);
}
@ -555,7 +555,7 @@ file_seek(struct archive *a, void *client_data, int64_t request, int whence)
archive_set_error(a, errno, "Error seeking in '%s'",
mine->filename.m);
else
archive_set_error(a, errno, "Error seeking in '%S'",
archive_set_error(a, errno, "Error seeking in '%ls'",
mine->filename.w);
return (ARCHIVE_FATAL);
}

View File

@ -37,46 +37,32 @@ archive_read_support_filter_by_code(struct archive *a, int filter_code)
switch (filter_code) {
case ARCHIVE_FILTER_NONE:
return archive_read_support_filter_none(a);
break;
case ARCHIVE_FILTER_GZIP:
return archive_read_support_filter_gzip(a);
break;
case ARCHIVE_FILTER_BZIP2:
return archive_read_support_filter_bzip2(a);
break;
case ARCHIVE_FILTER_COMPRESS:
return archive_read_support_filter_compress(a);
break;
case ARCHIVE_FILTER_LZMA:
return archive_read_support_filter_lzma(a);
break;
case ARCHIVE_FILTER_XZ:
return archive_read_support_filter_xz(a);
break;
case ARCHIVE_FILTER_UU:
return archive_read_support_filter_uu(a);
break;
case ARCHIVE_FILTER_RPM:
return archive_read_support_filter_rpm(a);
break;
case ARCHIVE_FILTER_LZIP:
return archive_read_support_filter_lzip(a);
break;
case ARCHIVE_FILTER_LRZIP:
return archive_read_support_filter_lrzip(a);
break;
case ARCHIVE_FILTER_LZOP:
return archive_read_support_filter_lzop(a);
break;
case ARCHIVE_FILTER_GRZIP:
return archive_read_support_filter_grzip(a);
break;
case ARCHIVE_FILTER_LZ4:
return archive_read_support_filter_lz4(a);
break;
case ARCHIVE_FILTER_ZSTD:
return archive_read_support_filter_zstd(a);
break;
}
return (ARCHIVE_FATAL);
}

View File

@ -323,7 +323,6 @@ lz4_filter_read(struct archive_read_filter *self, const void **p)
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC, "Program error.");
return (ARCHIVE_FATAL);
break;
}
while (state->stage == SELECT_STREAM) {

View File

@ -28,6 +28,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@ -439,6 +442,8 @@ static void arm_Init(struct _7zip *);
static size_t arm_Convert(struct _7zip *, uint8_t *, size_t);
static size_t arm64_Convert(struct _7zip *, uint8_t *, size_t);
static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
static size_t sparc_Convert(struct _7zip *, uint8_t *, size_t);
static size_t powerpc_Convert(struct _7zip *, uint8_t *, size_t);
int
@ -774,7 +779,7 @@ archive_read_format_7zip_read_header(struct archive_read *a,
/* allocate for ",rdonly,hidden,system" */
fflags_text = malloc(22 * sizeof(*fflags_text));
if (fflags_text != NULL) {
ptr = fflags_text;
ptr = fflags_text;
if (zip_entry->attr & FILE_ATTRIBUTE_READONLY) {
strcpy(ptr, ",rdonly");
ptr = ptr + 7;
@ -1116,7 +1121,9 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
if (coder2->codec != _7Z_X86 &&
coder2->codec != _7Z_X86_BCJ2 &&
coder2->codec != _7Z_ARM &&
coder2->codec != _7Z_ARM64) {
coder2->codec != _7Z_ARM64 &&
coder2->codec != _7Z_POWERPC &&
coder2->codec != _7Z_SPARC) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Unsupported filter %lx for %lx",
@ -1715,6 +1722,10 @@ decompress(struct archive_read *a, struct _7zip *zip,
*outbytes = arm_Convert(zip, buff, *outbytes);
} else if (zip->codec2 == _7Z_ARM64) {
*outbytes = arm64_Convert(zip, buff, *outbytes);
} else if (zip->codec2 == _7Z_SPARC) {
*outbytes = sparc_Convert(zip, buff, *outbytes);
} else if (zip->codec2 == _7Z_POWERPC) {
*outbytes = powerpc_Convert(zip, buff, *outbytes);
}
}
@ -4017,6 +4028,121 @@ arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
return i;
}
static size_t
sparc_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
{
// This function was adapted from
// static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
// in https://git.tukaani.org/xz-embedded.git
/*
* Branch/Call/Jump (BCJ) filter decoders
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
* Igor Pavlov <https://7-zip.org/>
*
* Copyright (C) The XZ Embedded authors and contributors
*
* Permission to use, copy, modify, and/or distribute this
* software for any purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
size_t i;
uint32_t instr;
size &= ~(size_t)3;
for (i = 0; i < size; i += 4) {
instr = (uint32_t)(buf[i] << 24)
| ((uint32_t)buf[i+1] << 16)
| ((uint32_t)buf[i+2] << 8)
| (uint32_t)buf[i+3];
if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
instr <<= 2;
instr -= zip->bcj_ip + (uint32_t)i;
instr >>= 2;
instr = ((uint32_t)0x40000000 - (instr & 0x400000))
| 0x40000000 | (instr & 0x3FFFFF);
buf[i] = (uint8_t)(instr >> 24);
buf[i+1] = (uint8_t)(instr >> 16);
buf[i+2] = (uint8_t)(instr >> 8);
buf[i+3] = (uint8_t)instr;
}
}
zip->bcj_ip += (uint32_t)i;
return i;
}
static size_t
powerpc_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
{
// This function was adapted from
// static size_t powerpc_code(void *simple, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size)
// in https://git.tukaani.org/xz.git
/*
* Filter for PowerPC (big endian) binaries
*
* Authors: Igor Pavlov
* Lasse Collin
*
* Copyright (C) The XZ Utils authors and contributors
*
* Permission to use, copy, modify, and/or distribute this
* software for any purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
size &= ~(size_t)3;
size_t i;
for (i = 0; i < size; i += 4) {
// PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
if ((buf[i] >> 2) == 0x12
&& ((buf[i + 3] & 3) == 1)) {
const uint32_t src
= (((uint32_t)(buf[i + 0]) & 3) << 24)
| ((uint32_t)(buf[i + 1]) << 16)
| ((uint32_t)(buf[i + 2]) << 8)
| ((uint32_t)(buf[i + 3]) & ~UINT32_C(3));
uint32_t dest = src - (zip->bcj_ip + (uint32_t)(i));
buf[i + 0] = 0x48 | ((dest >> 24) & 0x03);
buf[i + 1] = (dest >> 16);
buf[i + 2] = (dest >> 8);
buf[i + 3] &= 0x03;
buf[i + 3] |= dest;
}
}
zip->bcj_ip += (uint32_t)i;
return i;
}
/*
* Brought from LZMA SDK.
*
@ -4039,8 +4165,17 @@ arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
#define RC_READ_BYTE (*buffer++)
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
#define RC_INIT2 zip->bcj2_code = 0; zip->bcj2_range = 0xFFFFFFFF; \
{ int ii; for (ii = 0; ii < 5; ii++) { RC_TEST; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }}
#define RC_INIT2 do { \
zip->bcj2_code = 0; \
zip->bcj2_range = 0xFFFFFFFF; \
{ \
int ii; \
for (ii = 0; ii < 5; ii++) { \
RC_TEST; \
zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; \
} \
} \
} while (0)
#define NORMALIZE if (zip->bcj2_range < kTopValue) { RC_TEST; zip->bcj2_range <<= 8; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }

View File

@ -41,49 +41,34 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
switch (format_code & ARCHIVE_FORMAT_BASE_MASK) {
case ARCHIVE_FORMAT_7ZIP:
return archive_read_support_format_7zip(a);
break;
case ARCHIVE_FORMAT_AR:
return archive_read_support_format_ar(a);
break;
case ARCHIVE_FORMAT_CAB:
return archive_read_support_format_cab(a);
break;
case ARCHIVE_FORMAT_CPIO:
return archive_read_support_format_cpio(a);
break;
case ARCHIVE_FORMAT_EMPTY:
return archive_read_support_format_empty(a);
break;
case ARCHIVE_FORMAT_ISO9660:
return archive_read_support_format_iso9660(a);
break;
case ARCHIVE_FORMAT_LHA:
return archive_read_support_format_lha(a);
break;
case ARCHIVE_FORMAT_MTREE:
return archive_read_support_format_mtree(a);
break;
case ARCHIVE_FORMAT_RAR:
return archive_read_support_format_rar(a);
break;
case ARCHIVE_FORMAT_RAR_V5:
return archive_read_support_format_rar5(a);
break;
case ARCHIVE_FORMAT_RAW:
return archive_read_support_format_raw(a);
break;
case ARCHIVE_FORMAT_TAR:
return archive_read_support_format_tar(a);
break;
case ARCHIVE_FORMAT_WARC:
return archive_read_support_format_warc(a);
break;
case ARCHIVE_FORMAT_XAR:
return archive_read_support_format_xar(a);
break;
case ARCHIVE_FORMAT_ZIP:
return archive_read_support_format_zip(a);
break;
}
archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
"Invalid format code specified");

View File

@ -1429,7 +1429,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
* information first, then store all file bodies. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Ignoring out-of-order file @%jx (%s) %jd < %jd",
(intmax_t)file->number,
(uintmax_t)file->number,
iso9660->pathname.s,
(intmax_t)file->offset,
(intmax_t)iso9660->current_position);

View File

@ -477,7 +477,7 @@ static inline uint32_t vm_read_32(struct rar_virtual_machine*, size_t);
((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n)))
/* Notify how many bits we consumed. */
#define rar_br_consume(br, n) ((br)->cache_avail -= (n))
#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7)
#define rar_br_consume_unaligned_bits(br) ((br)->cache_avail &= ~7)
static const uint32_t cache_masks[] = {
0x00000000, 0x00000001, 0x00000003, 0x00000007,
@ -2278,7 +2278,7 @@ parse_codes(struct archive_read *a)
free_codes(a);
/* Skip to the next byte */
rar_br_consume_unalined_bits(br);
rar_br_consume_unaligned_bits(br);
/* PPMd block flag */
if (!rar_br_read_ahead(a, br, 1))
@ -2805,7 +2805,7 @@ make_table(struct archive_read *a, struct huffman_code *code)
else
code->tablesize = code->maxlength;
code->table = calloc(1U << code->tablesize, sizeof(*code->table));
code->table = calloc(((size_t)1U) << code->tablesize, sizeof(*code->table));
return make_table_recurse(a, code, 0, code->table, 0, code->tablesize);
}

View File

@ -691,7 +691,8 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported filter type: 0x%x", flt->type);
"Unsupported filter type: 0x%x",
(unsigned int)flt->type);
return ARCHIVE_FATAL;
}
@ -1293,7 +1294,7 @@ static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
*extra_data_size -= hash_size;
} else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported hash type (0x%x)", (int) hash_type);
"Unsupported hash type (0x%jx)", (uintmax_t)hash_type);
return ARCHIVE_FATAL;
}
@ -1896,7 +1897,8 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
} else {
/* Unknown host OS */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported Host OS: 0x%x", (int) host_os);
"Unsupported Host OS: 0x%jx",
(uintmax_t)host_os);
return ARCHIVE_FATAL;
}
@ -2104,8 +2106,8 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported extra type (0x%x)",
(int) extra_field_id);
"Unsupported extra type (0x%jx)",
(uintmax_t)extra_field_id);
return ARCHIVE_FATAL;
}
@ -3994,7 +3996,7 @@ static int do_unpack(struct archive_read* a, struct rar5* rar,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Compression method not supported: 0x%x",
rar->cstate.method);
(unsigned int)rar->cstate.method);
return ARCHIVE_FATAL;
}

View File

@ -129,7 +129,11 @@ struct tar {
int64_t entry_offset;
int64_t entry_padding;
int64_t entry_bytes_unconsumed;
int64_t realsize;
int64_t disk_size;
int64_t GNU_sparse_realsize;
int64_t GNU_sparse_size;
int64_t SCHILY_sparse_realsize;
int64_t pax_size;
struct sparse_block *sparse_list;
struct sparse_block *sparse_last;
int64_t sparse_offset;
@ -138,6 +142,7 @@ struct tar {
int sparse_gnu_minor;
char sparse_gnu_attributes_seen;
char filetype;
char size_fields; /* Bits defined below */
struct archive_string localname;
struct archive_string_conv *opt_sconv;
@ -148,9 +153,15 @@ struct tar {
int compat_2x;
int process_mac_extensions;
int read_concatenated_archives;
int realsize_override;
};
/* Track which size fields were present in the headers */
#define TAR_SIZE_PAX_SIZE 1
#define TAR_SIZE_GNU_SPARSE_REALSIZE 2
#define TAR_SIZE_GNU_SPARSE_SIZE 4
#define TAR_SIZE_SCHILY_SPARSE_REALSIZE 8
static int archive_block_is_null(const char *p);
static char *base64_decode(const char *, size_t, size_t *);
static int gnu_add_sparse_entry(struct archive_read *, struct tar *,
@ -529,8 +540,7 @@ archive_read_format_tar_read_header(struct archive_read *a,
tar = (struct tar *)(a->format->data);
tar->entry_offset = 0;
gnu_clear_sparse_list(tar);
tar->realsize = -1; /* Mark this as "unset" */
tar->realsize_override = 0;
tar->size_fields = 0; /* We don't have any size info yet */
/* Setup default string conversion. */
tar->sconv = tar->opt_sconv;
@ -622,7 +632,7 @@ archive_read_format_tar_read_data(struct archive_read *a,
tar->entry_padding = 0;
*buff = NULL;
*size = 0;
*offset = tar->realsize;
*offset = tar->disk_size;
return (ARCHIVE_EOF);
}
@ -750,7 +760,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
* if there's no regular header, then this is
* a premature EOF. */
archive_set_error(&a->archive, EINVAL,
"Damaged tar archive");
"Damaged tar archive (end-of-archive within a sequence of headers)");
return (ARCHIVE_FATAL);
} else {
return (ARCHIVE_EOF);
@ -760,7 +770,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated tar archive"
" detected while reading next heaader");
" detected while reading next header");
return (ARCHIVE_FATAL);
}
*unconsumed += 512;
@ -787,7 +797,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
/* This is NOT a null block, so it must be a valid header. */
if (!checksum(a, h)) {
tar_flush_unconsumed(a, unconsumed);
archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
archive_set_error(&a->archive, EINVAL,
"Damaged tar archive (bad header checksum)");
/* If we've read some critical information (pax headers, etc)
* and _then_ see a bad header, we can't really recover. */
if (eof_fatal) {
@ -1038,7 +1049,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
struct archive_string acl_text;
size_t size;
int err, acl_type;
int64_t type;
uint64_t type;
char *acl, *p;
header = (const struct archive_entry_header_ustar *)h;
@ -1075,7 +1086,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
}
p++;
}
switch ((int)type & ~0777777) {
switch (type & ~0777777) {
case 01000000:
/* POSIX.1e ACL */
acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
@ -1086,8 +1097,8 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (unsupported type %o)",
(int)type);
"Malformed Solaris ACL attribute (unsupported type %"
PRIo64 ")", type);
archive_string_free(&acl_text);
return (ARCHIVE_WARN);
}
@ -1145,7 +1156,9 @@ header_gnu_longlink(struct archive_read *a, struct tar *tar,
struct archive_string linkpath;
archive_string_init(&linkpath);
err = read_body_to_string(a, tar, &linkpath, h, unconsumed);
archive_entry_set_link(entry, linkpath.s);
if (err == ARCHIVE_OK) {
archive_entry_set_link(entry, linkpath.s);
}
archive_string_free(&linkpath);
return (err);
}
@ -1287,6 +1300,11 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
* allows header_old_tar and header_ustar
* to handle filenames differently, while still putting most of the
* common parsing into one place.
*
* This is called _after_ ustar, GNU tar, Schily, etc, special
* fields have already been parsed into the `tar` structure.
* So we can make final decisions here about how to reconcile
* size, mode, etc, information.
*/
static int
header_common(struct archive_read *a, struct tar *tar,
@ -1308,34 +1326,73 @@ header_common(struct archive_read *a, struct tar *tar,
archive_entry_set_perm(entry,
(mode_t)tar_atol(header->mode, sizeof(header->mode)));
}
/* Set uid, gid, mtime if not already set */
if (!archive_entry_uid_is_set(entry)) {
archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
}
if (!archive_entry_gid_is_set(entry)) {
archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
}
if (!archive_entry_mtime_is_set(entry)) {
archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
}
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
/* Reconcile the size info. */
/* First, how big is the file on disk? */
if ((tar->size_fields & TAR_SIZE_GNU_SPARSE_REALSIZE) != 0) {
/* GNU sparse format 1.0 uses `GNU.sparse.realsize`
* to hold the size of the file on disk. */
tar->disk_size = tar->GNU_sparse_realsize;
} else if ((tar->size_fields & TAR_SIZE_GNU_SPARSE_SIZE) != 0
&& (tar->sparse_gnu_major == 0)) {
/* GNU sparse format 0.0 and 0.1 use `GNU.sparse.size`
* to hold the size of the file on disk. */
tar->disk_size = tar->GNU_sparse_size;
} else if ((tar->size_fields & TAR_SIZE_SCHILY_SPARSE_REALSIZE) != 0) {
tar->disk_size = tar->SCHILY_sparse_realsize;
} else if ((tar->size_fields & TAR_SIZE_PAX_SIZE) != 0) {
tar->disk_size = tar->pax_size;
} else {
/* There wasn't a suitable pax header, so use the ustar info */
tar->disk_size = tar_atol(header->size, sizeof(header->size));
}
if (tar->disk_size < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Tar entry has negative file size");
return (ARCHIVE_FATAL);
} else if (tar->disk_size > entry_limit) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Tar entry size overflow");
return (ARCHIVE_FATAL);
} else {
archive_entry_set_size(entry, tar->disk_size);
}
/* Second, how big is the data in the archive? */
if ((tar->size_fields & TAR_SIZE_GNU_SPARSE_SIZE) != 0
&& (tar->sparse_gnu_major == 1)) {
/* GNU sparse format 1.0 uses `GNU.sparse.size`
* to hold the size of the data in the archive. */
tar->entry_bytes_remaining = tar->GNU_sparse_size;
} else if ((tar->size_fields & TAR_SIZE_PAX_SIZE) != 0) {
tar->entry_bytes_remaining = tar->pax_size;
} else {
tar->entry_bytes_remaining
= tar_atol(header->size, sizeof(header->size));
}
if (tar->entry_bytes_remaining < 0) {
tar->entry_bytes_remaining = 0;
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Tar entry has negative size");
"Tar entry has negative size");
return (ARCHIVE_FATAL);
}
if (tar->entry_bytes_remaining > entry_limit) {
} else if (tar->entry_bytes_remaining > entry_limit) {
tar->entry_bytes_remaining = 0;
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Tar entry size overflow");
"Tar entry size overflow");
return (ARCHIVE_FATAL);
}
if (!tar->realsize_override) {
tar->realsize = tar->entry_bytes_remaining;
}
archive_entry_set_size(entry, tar->realsize);
if (!archive_entry_mtime_is_set(entry)) {
archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
}
/* Handle the tar type flag appropriately. */
tar->filetype = header->typeflag[0];
@ -2290,10 +2347,13 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
}
else if (key_length == 4 && memcmp(key, "size", 4) == 0) {
/* GNU.sparse.size */
/* This is either the size of stored entry OR the size of data on disk,
* depending on which GNU sparse format version is in use.
* Since pax attributes can be in any order, we may not actually
* know at this point how to interpret this. */
if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
tar->realsize = t;
archive_entry_set_size(entry, tar->realsize);
tar->realsize_override = 1;
tar->GNU_sparse_size = t;
tar->size_fields |= TAR_SIZE_GNU_SPARSE_SIZE;
}
return (err);
}
@ -2361,11 +2421,10 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
return (err);
}
else if (key_length == 8 && memcmp(key, "realsize", 8) == 0) {
/* GNU.sparse.realsize */
/* GNU.sparse.realsize = size of file on disk */
if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
tar->realsize = t;
archive_entry_set_size(entry, tar->realsize);
tar->realsize_override = 1;
tar->GNU_sparse_realsize = t;
tar->size_fields |= TAR_SIZE_GNU_SPARSE_REALSIZE;
}
return (err);
}
@ -2546,12 +2605,12 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
}
else if (key_length == 8 && memcmp(key, "realsize", 8) == 0) {
if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
tar->realsize = t;
tar->realsize_override = 1;
archive_entry_set_size(entry, tar->realsize);
tar->SCHILY_sparse_realsize = t;
tar->size_fields |= TAR_SIZE_SCHILY_SPARSE_REALSIZE;
}
return (err);
}
/* TODO: Is there a SCHILY.sparse.size similar to GNU.sparse.size ? */
else if (key_length > 6 && memcmp(key, "xattr.", 6) == 0) {
key_length -= 6;
key += 6;
@ -2718,19 +2777,8 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
if (key_length == 4 && memcmp(key, "size", 4) == 0) {
/* "size" is the size of the data in the entry. */
if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
tar->entry_bytes_remaining = t;
/*
* The "size" pax header keyword always overrides the
* "size" field in the tar header.
* GNU.sparse.realsize, GNU.sparse.size and
* SCHILY.realsize override this value.
*/
if (!tar->realsize_override) {
archive_entry_set_size(entry,
tar->entry_bytes_remaining);
tar->realsize
= tar->entry_bytes_remaining;
}
tar->pax_size = t;
tar->size_fields |= TAR_SIZE_PAX_SIZE;
}
else if (t == INT64_MAX) {
/* Note: pax_attr_read_number returns INT64_MAX on overflow or < 0 */
@ -2842,11 +2890,6 @@ header_gnutar(struct archive_read *a, struct tar *tar,
* filename is stored as in old-style archives.
*/
/* Grab fields common to all tar variants. */
err = header_common(a, tar, entry, h);
if (err == ARCHIVE_FATAL)
return (err);
/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_gnutar *)h;
const char *existing_pathname = archive_entry_pathname(entry);
@ -2895,8 +2938,6 @@ header_gnutar(struct archive_read *a, struct tar *tar,
archive_entry_set_rdev(entry, 0);
}
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
/* Grab GNU-specific fields. */
if (!archive_entry_atime_is_set(entry)) {
t = tar_atol(header->atime, sizeof(header->atime));
@ -2910,10 +2951,10 @@ header_gnutar(struct archive_read *a, struct tar *tar,
}
if (header->realsize[0] != 0) {
tar->realsize
/* Treat as a synonym for the pax GNU.sparse.realsize attr */
tar->GNU_sparse_realsize
= tar_atol(header->realsize, sizeof(header->realsize));
archive_entry_set_size(entry, tar->realsize);
tar->realsize_override = 1;
tar->size_fields |= TAR_SIZE_GNU_SPARSE_REALSIZE;
}
if (header->sparse[0].offset[0] != 0) {
@ -2926,6 +2967,13 @@ header_gnutar(struct archive_read *a, struct tar *tar,
}
}
/* Grab fields common to all tar variants. */
err = header_common(a, tar, entry, h);
if (err == ARCHIVE_FATAL)
return (err);
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
return (err);
}
@ -3105,8 +3153,7 @@ gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p, size
* it's not possible to support both variants. This code supports
* the later variant at the expense of not supporting the former.
*
* This variant also replaced GNU.sparse.size with GNU.sparse.realsize
* and introduced the GNU.sparse.major/GNU.sparse.minor attributes.
* This variant also introduced the GNU.sparse.major/GNU.sparse.minor attributes.
*/
/*

View File

@ -1745,15 +1745,6 @@ decompression_cleanup(struct archive_read *a)
#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
if (xar->lzstream_valid)
lzma_end(&(xar->lzstream));
#elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
if (xar->lzstream_valid) {
if (lzmadec_end(&(xar->lzstream)) != LZMADEC_OK) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Failed to clean up lzmadec decompressor");
r = ARCHIVE_FATAL;
}
}
#endif
return (r);
}
@ -2070,7 +2061,7 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
if (xar->file->link > 0)
if (add_link(a, xar, xar->file) != ARCHIVE_OK) {
return (ARCHIVE_FATAL);
};
}
}
}
}
@ -2851,7 +2842,6 @@ xml_data(void *userData, const char *s, size_t len)
xar->file->has |= HAS_XATTR;
archive_strncpy(&(xar->xattr->fstype), s, len);
break;
break;
case FILE_ACL_DEFAULT:
case FILE_ACL_ACCESS:
case FILE_ACL_APPLEEXTENDED:

View File

@ -2134,15 +2134,15 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
if(order < 2 || restore_method > 2) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid parameter set in PPMd8 stream (order=%" PRId32 ", "
"restore=%" PRId32 ")", order, restore_method);
"Invalid parameter set in PPMd8 stream (order=%" PRIu32 ", "
"restore=%" PRIu32 ")", order, restore_method);
return (ARCHIVE_FAILED);
}
/* Allocate the memory needed to properly decompress the file. */
if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
archive_set_error(&a->archive, ENOMEM,
"Unable to allocate memory for PPMd8 stream: %" PRId32 " bytes",
"Unable to allocate memory for PPMd8 stream: %" PRIu32 " bytes",
mem << 20);
return (ARCHIVE_FATAL);
}
@ -3168,7 +3168,6 @@ archive_read_format_zip_read_data(struct archive_read *a,
/* We can't decompress this entry, but we will
* be able to skip() it and try the next entry. */
return (ARCHIVE_FAILED);
break;
}
if (r != ARCHIVE_OK)
return (r);

View File

@ -154,7 +154,6 @@ static int archive_wstring_append_from_mbs_in_codepage(
struct archive_string_conv *);
static int archive_string_append_from_wcs_in_codepage(struct archive_string *,
const wchar_t *, size_t, struct archive_string_conv *);
static int is_big_endian(void);
static int strncat_in_codepage(struct archive_string *, const void *,
size_t, struct archive_string_conv *);
static int win_strncat_from_utf16be(struct archive_string *, const void *,
@ -199,6 +198,29 @@ static int archive_string_normalize_D(struct archive_string *, const void *,
static int archive_string_append_unicode(struct archive_string *,
const void *, size_t, struct archive_string_conv *);
#if defined __LITTLE_ENDIAN__
#define IS_BIG_ENDIAN 0
#elif defined __BIG_ENDIAN__
#define IS_BIG_ENDIAN 1
#elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define IS_BIG_ENDIAN 0
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define IS_BIG_ENDIAN 1
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || defined(_M_ARM64))
#define IS_BIG_ENDIAN 0
#else
// Detect endianness at runtime.
static int
is_big_endian(void)
{
uint16_t d = 1;
return (archive_be16dec(&d) == 1);
}
#define IS_BIG_ENDIAN is_big_endian()
#endif
static struct archive_string *
archive_string_append(struct archive_string *as, const char *p, size_t s)
{
@ -485,7 +507,7 @@ archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
struct archive_string u16;
int saved_flag = sc->flag;/* save current flag. */
if (is_big_endian())
if (IS_BIG_ENDIAN)
sc->flag |= SCONV_TO_UTF16BE;
else
sc->flag |= SCONV_TO_UTF16LE;
@ -504,7 +526,7 @@ archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
count = (int)mbsnbytes(s, length);
}
u16.s = (char *)dest->s;
u16.length = dest->length << 1;;
u16.length = dest->length << 1;
u16.buffer_length = dest->buffer_length;
if (sc->flag & SCONV_NORMALIZATION_C)
ret = archive_string_normalize_C(&u16, s, count, sc);
@ -523,14 +545,14 @@ archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
dest->length + count + 1))
return (-1);
wmemcpy(dest->s + dest->length, (const wchar_t *)s, count);
if ((sc->flag & SCONV_FROM_UTF16BE) && !is_big_endian()) {
if ((sc->flag & SCONV_FROM_UTF16BE) && !IS_BIG_ENDIAN) {
uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
int b;
for (b = 0; b < count; b++) {
uint16_t val = archive_le16dec(u16+b);
archive_be16enc(u16+b, val);
}
} else if ((sc->flag & SCONV_FROM_UTF16LE) && is_big_endian()) {
} else if ((sc->flag & SCONV_FROM_UTF16LE) && IS_BIG_ENDIAN) {
uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
int b;
for (b = 0; b < count; b++) {
@ -3538,7 +3560,7 @@ win_strncat_from_utf16(struct archive_string *as, const void *_p, size_t bytes,
archive_string_init(&tmp);
if (be) {
if (is_big_endian()) {
if (IS_BIG_ENDIAN) {
u16 = _p;
} else {
if (archive_string_ensure(&tmp, bytes+2) == NULL)
@ -3551,7 +3573,7 @@ win_strncat_from_utf16(struct archive_string *as, const void *_p, size_t bytes,
u16 = tmp.s;
}
} else {
if (!is_big_endian()) {
if (!IS_BIG_ENDIAN) {
u16 = _p;
} else {
if (archive_string_ensure(&tmp, bytes+2) == NULL)
@ -3605,14 +3627,6 @@ win_strncat_from_utf16le(struct archive_string *as, const void *_p,
return (win_strncat_from_utf16(as, _p, bytes, sc, 0));
}
static int
is_big_endian(void)
{
uint16_t d = 1;
return (archive_be16dec(&d) == 1);
}
/*
* Convert a current locale string to UTF-16BE/LE and copy the result.
* Return -1 if conversion fails.
@ -3673,7 +3687,7 @@ win_strncat_to_utf16(struct archive_string *as16, const void *_p,
if (count == 0)
return (-1);
if (is_big_endian()) {
if (IS_BIG_ENDIAN) {
if (!bigendian) {
while (count > 0) {
uint16_t v = archive_be16dec(u16);

View File

@ -166,7 +166,7 @@ archive_filter_b64encode_open(struct archive_write_filter *f)
}
archive_string_sprintf(&state->encoded_buff, "begin-base64 %o %s\n",
state->mode, state->name.s);
(unsigned int)state->mode, state->name.s);
f->data = state;
return (0);

View File

@ -155,7 +155,7 @@ archive_filter_uuencode_open(struct archive_write_filter *f)
}
archive_string_sprintf(&state->encoded_buff, "begin %o %s\n",
state->mode, state->name.s);
(unsigned int)state->mode, state->name.s);
f->data = state;
return (0);

View File

@ -478,9 +478,11 @@ la_verify_filetype(mode_t mode, __LA_MODE_T filetype) {
case AE_IFLNK:
ret = (S_ISLNK(mode));
break;
#ifdef S_ISSOCK
case AE_IFSOCK:
ret = (S_ISSOCK(mode));
break;
#endif
case AE_IFCHR:
ret = (S_ISCHR(mode));
break;
@ -3605,7 +3607,7 @@ set_time_tru64(int fd, int mode, const char *name,
tstamp.atime.tv_sec = atime;
tstamp.mtime.tv_sec = mtime;
tstamp.ctime.tv_sec = ctime;
#if defined (__hpux) && defined (__ia64)
#if defined (__hpux) && ( defined (__ia64) || defined (__hppa) )
tstamp.atime.tv_nsec = atime_nsec;
tstamp.mtime.tv_nsec = mtime_nsec;
tstamp.ctime.tv_nsec = ctime_nsec;
@ -3788,7 +3790,7 @@ set_mode(struct archive_write_disk *a, int mode)
* permissions on symlinks, so a failure here has no
* impact.
*/
if (lchmod(a->name, mode) != 0) {
if (lchmod(a->name, (mode_t)mode) != 0) {
switch (errno) {
case ENOTSUP:
case ENOSYS:
@ -3803,7 +3805,8 @@ set_mode(struct archive_write_disk *a, int mode)
break;
default:
archive_set_error(&a->archive, errno,
"Can't set permissions to 0%o", (int)mode);
"Can't set permissions to 0%o",
(unsigned int)mode);
r = ARCHIVE_WARN;
}
}
@ -3817,16 +3820,16 @@ set_mode(struct archive_write_disk *a, int mode)
*/
#ifdef HAVE_FCHMOD
if (a->fd >= 0)
r2 = fchmod(a->fd, mode);
r2 = fchmod(a->fd, (mode_t)mode);
else
#endif
/* If this platform lacks fchmod(), then
* we'll just use chmod(). */
r2 = chmod(a->name, mode);
r2 = chmod(a->name, (mode_t)mode);
if (r2 != 0) {
archive_set_error(&a->archive, errno,
"Can't set permissions to 0%o", (int)mode);
"Can't set permissions to 0%o", (unsigned int)mode);
r = ARCHIVE_WARN;
}
}

View File

@ -2606,7 +2606,7 @@ set_times(struct archive_write_disk *a,
time_t ctime_sec, long ctime_nanos)
{
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
#define WINTIME(sec, nsec) (((sec * 10000000LL) + EPOC_TIME)\
+ ((nsec)/100))
HANDLE hw = 0;

View File

@ -118,7 +118,7 @@ open_filename(struct archive *a, int mbs_fn, const void *filename)
(const char *)filename);
else
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Can't convert '%S' to MBS",
"Can't convert '%ls' to MBS",
(const wchar_t *)filename);
return (ARCHIVE_FAILED);
}
@ -170,7 +170,7 @@ file_open(struct archive *a, void *client_data)
else {
archive_mstring_get_wcs(a, &mine->filename, &wcs);
archive_set_error(a, errno,
"Can't convert '%S' to MBS", wcs);
"Can't convert '%ls' to MBS", wcs);
}
return (ARCHIVE_FATAL);
}
@ -181,7 +181,7 @@ file_open(struct archive *a, void *client_data)
if (mbs != NULL)
archive_set_error(a, errno, "Failed to open '%s'", mbs);
else
archive_set_error(a, errno, "Failed to open '%S'", wcs);
archive_set_error(a, errno, "Failed to open '%ls'", wcs);
return (ARCHIVE_FATAL);
}
@ -189,7 +189,7 @@ file_open(struct archive *a, void *client_data)
if (mbs != NULL)
archive_set_error(a, errno, "Couldn't stat '%s'", mbs);
else
archive_set_error(a, errno, "Couldn't stat '%S'", wcs);
archive_set_error(a, errno, "Couldn't stat '%ls'", wcs);
return (ARCHIVE_FATAL);
}

View File

@ -915,7 +915,7 @@ static int iso9660_finish_entry(struct archive_write *);
static int iso9660_close(struct archive_write *);
static int iso9660_free(struct archive_write *);
static void get_system_identitier(char *, size_t);
static void get_system_identifier(char *, size_t);
static void set_str(unsigned char *, const char *, size_t, char,
const char *);
static inline int joliet_allowed_char(unsigned char, unsigned char);
@ -2170,7 +2170,7 @@ iso9660_free(struct archive_write *a)
* Get the System Identifier
*/
static void
get_system_identitier(char *system_id, size_t size)
get_system_identifier(char *system_id, size_t size)
{
#if defined(HAVE_SYS_UTSNAME_H)
struct utsname u;
@ -3876,7 +3876,7 @@ write_VD(struct archive_write *a, struct vdd *vdd)
/* Unused Field */
set_unused_field_bp(bp, 8, 8);
/* System Identifier */
get_system_identitier(identifier, sizeof(identifier));
get_system_identifier(identifier, sizeof(identifier));
r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc);
if (r != ARCHIVE_OK)
return (r);
@ -4041,7 +4041,7 @@ set_option_info(struct archive_string *info, int *opt, const char *key,
case KEY_HEX:
d = va_arg(ap, int);
archive_string_sprintf(info, "%c%s=%x",
prefix, key, d);
prefix, key, (unsigned int)d);
break;
}
va_end(ap);

View File

@ -54,7 +54,7 @@ struct attr_counter {
int count;
};
struct att_counter_set {
struct attr_counter_set {
struct attr_counter *uid_list;
struct attr_counter *gid_list;
struct attr_counter *mode_list;
@ -141,7 +141,7 @@ struct mtree_writer {
unsigned long fflags_set;
unsigned long fflags_clear;
} set;
struct att_counter_set acs;
struct attr_counter_set acs;
int classic;
int depth;
@ -437,7 +437,7 @@ write_global(struct mtree_writer *mtree)
{
struct archive_string setstr;
struct archive_string unsetstr;
struct att_counter_set *acs;
struct attr_counter_set *acs;
int keys, oldkeys, effkeys;
archive_string_init(&setstr);
@ -638,7 +638,7 @@ static int
attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me)
{
struct attr_counter *ac, *last;
struct att_counter_set *acs = &mtree->acs;
struct attr_counter_set *acs = &mtree->acs;
int keys = mtree->keys;
if (keys & (F_UNAME | F_UID)) {
@ -714,7 +714,7 @@ attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me)
static void
attr_counter_set_free(struct mtree_writer *mtree)
{
struct att_counter_set *acs = &mtree->acs;
struct attr_counter_set *acs = &mtree->acs;
attr_counter_free(&acs->uid_list);
attr_counter_free(&acs->gid_list);

View File

@ -529,7 +529,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
__archive_write_entry_filetype_unsupported(
&a->archive, entry, "zip");
return ARCHIVE_FAILED;
};
}
/* If we're not using Zip64, reject large files. */
if (zip->flags & ZIP_FLAG_AVOID_ZIP64) {

View File

@ -210,6 +210,8 @@
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_UTSNAME_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_TCGETATTR 1
#define HAVE_TCSETATTR 1
#define HAVE_TIMEGM 1
#define HAVE_TIME_H 1
#define HAVE_TZSET 1