aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2023-05-30 13:07:22 +0000
committerMartin Matuska <mm@FreeBSD.org>2023-05-30 13:12:16 +0000
commit309e35276a045cc5ae7f9414c80765863d4a09c4 (patch)
tree884319d3584d2dba990401c8195dd527fb920ab4
parentb5a00e61e90d12782d023f98d9bf9bebf65733ed (diff)
downloadsrc-309e35276a045cc5ae7f9414c80765863d4a09c4.tar.gz
src-309e35276a045cc5ae7f9414c80765863d4a09c4.zip
Update vendor/libarchive to libarchive/libarchive@1f3c62ebf
Important changes (relevant to FreeBSD): #1814 Do not account for NULL terminator when comparing with "TRAILER!!!" #1818 Add ability to produce multi-frame zstd archives #1860 Make single bit bitfields unsigned to avoid clang 16 warning #1869 Fix FreeBSD builds with WARNS=6 Obtained from: libarchive Libarchive commit: 1f3c62ebf4d492ac21d3099b3b064993100dd997
-rw-r--r--CMakeLists.txt13
-rw-r--r--NEWS2
-rw-r--r--build/cmake/FindLibGCC.cmake22
-rw-r--r--build/cmake/config.h.in18
-rw-r--r--build/version2
-rw-r--r--configure.ac37
-rw-r--r--contrib/android/config/android.h2
-rw-r--r--contrib/android/config/linux_host.h2
-rw-r--r--contrib/android/config/windows_host.h14
-rw-r--r--cpio/cpio.c19
-rw-r--r--cpio/test/test_option_J_upper.c1
-rw-r--r--cpio/test/test_option_c.c6
-rw-r--r--cpio/test/test_option_t.c17
-rw-r--r--libarchive/archive.h4
-rw-r--r--libarchive/archive_entry.h2
-rw-r--r--libarchive/archive_getdate.c119
-rw-r--r--libarchive/archive_hmac.c15
-rw-r--r--libarchive/archive_hmac_private.h2
-rw-r--r--libarchive/archive_read_data_into_fd.c7
-rw-r--r--libarchive/archive_read_open_file.c4
-rw-r--r--libarchive/archive_read_support_filter_zstd.c14
-rw-r--r--libarchive/archive_read_support_format_cpio.c2
-rw-r--r--libarchive/archive_read_support_format_iso9660.c12
-rw-r--r--libarchive/archive_read_support_format_rar.c17
-rw-r--r--libarchive/archive_read_support_format_warc.c6
-rw-r--r--libarchive/archive_read_support_format_xar.c8
-rw-r--r--libarchive/archive_write.c31
-rw-r--r--libarchive/archive_write_add_filter_zstd.c232
-rw-r--r--libarchive/archive_write_private.h1
-rw-r--r--libarchive/archive_write_set_format_7zip.c2
-rw-r--r--libarchive/archive_write_set_format_iso9660.c32
-rw-r--r--libarchive/archive_write_set_format_pax.c18
-rw-r--r--libarchive/archive_write_set_format_warc.c25
-rw-r--r--libarchive/archive_write_set_format_xar.c14
-rw-r--r--libarchive/archive_write_set_format_zip.c19
-rw-r--r--libarchive/config_freebsd.h2
-rw-r--r--libarchive/test/test_read_format_rar5.c2
-rw-r--r--libarchive/test/test_read_format_zip.c5
-rw-r--r--libarchive/test/test_short_writes.c2
-rw-r--r--libarchive/test/test_write_filter_zstd.c27
-rw-r--r--libarchive/test/test_write_format_zip_compression_store.c17
-rw-r--r--libarchive/test/test_write_format_zip_file.c17
-rw-r--r--libarchive/test/test_write_format_zip_file_zip64.c17
-rw-r--r--libarchive/xxhash.c4
-rw-r--r--tar/bsdtar.115
-rw-r--r--tar/test/test_option_lzma.c1
-rw-r--r--tar/util.c17
-rw-r--r--test_utils/test_main.c25
48 files changed, 441 insertions, 451 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 713e3bc5e63a..dbb95e34d3fd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,7 @@ endif()
# RelWithDebInfo : Release build with Debug Info
# MinSizeRel : Release Min Size build
IF(NOT CMAKE_BUILD_TYPE)
- SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
+ SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
# value type is "UNINITIALIZED".
@@ -299,6 +299,7 @@ ENDIF()
IF(MINGW)
ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO)
+ ADD_DEFINITIONS(-D__MINGW_USE_VC2005_COMPAT)
ENDIF()
#
@@ -1412,12 +1413,12 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
-CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
-CHECK_FUNCTION_EXISTS_GLIBC(_gmtime64_s HAVE__GMTIME64_S)
-CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
-CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
+CHECK_SYMBOL_EXISTS(ctime_s "time.h" HAVE_CTIME_S)
+CHECK_SYMBOL_EXISTS(gmtime_s "time.h" HAVE_GMTIME_S)
+CHECK_SYMBOL_EXISTS(localtime_s "time.h" HAVE_LOCALTIME_S)
+CHECK_SYMBOL_EXISTS(_mkgmtime "time.h" HAVE__MKGMTIME)
SET(CMAKE_REQUIRED_LIBRARIES "")
CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
@@ -1559,7 +1560,7 @@ ENDIF()
#
#
CHECK_STRUCT_HAS_MEMBER("struct tm" tm_sec
- "sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
+ "sys/types.h;sys/time.h;time.h" HAVE_SYS_TIME_H)
#
# Check for integer types
diff --git a/NEWS b/NEWS
index d6324487691b..4fac9631088f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Wed 07, 2022: libarchive 3.6.2 released
+Dec 07, 2022: libarchive 3.6.2 released
Apr 08, 2022: libarchive 3.6.1 released
diff --git a/build/cmake/FindLibGCC.cmake b/build/cmake/FindLibGCC.cmake
deleted file mode 100644
index 5883ff802642..000000000000
--- a/build/cmake/FindLibGCC.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-# - Find libgcc
-# Find the libgcc library.
-#
-# LIBGCC_LIBRARIES - List of libraries when using libgcc
-# LIBGCC_FOUND - True if libgcc found.
-
-IF (LIBGCC_LIBRARY)
- # Already in cache, be silent
- SET(LIBGCC_FIND_QUIETLY TRUE)
-ENDIF (LIBGCC_LIBRARY)
-
-FIND_LIBRARY(LIBGCC_LIBRARY NAMES gcc libgcc)
-
-# handle the QUIETLY and REQUIRED arguments and set LIBGCC_FOUND to TRUE if
-# all listed variables are TRUE
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGCC DEFAULT_MSG LIBGCC_LIBRARY)
-
-IF(LIBGCC_FOUND)
- SET(LIBGCC_LIBRARIES ${LIBGCC_LIBRARY})
- SET(HAVE_LIBGCC 1)
-ENDIF(LIBGCC_FOUND)
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index 5012ad2cc4a7..ff74f33fccd7 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -164,7 +164,7 @@ typedef unsigned char uint8_t;
#define HAVE_UINT8_T
#endif
-#if !defined(HAVE_UINT16_T)
+#if !defined(HAVE_UINT8_T)
#error No 8-bit unsigned integer type was found.
#endif
@@ -1212,8 +1212,8 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <zstd.h> header file. */
#cmakedefine HAVE_ZSTD_H 1
-/* Define to 1 if you have the `_ctime64_s' function. */
-#cmakedefine HAVE__CTIME64_S 1
+/* Define to 1 if you have the `ctime_s' function. */
+#cmakedefine HAVE_CTIME_S 1
/* Define to 1 if you have the `_fseeki64' function. */
#cmakedefine HAVE__FSEEKI64 1
@@ -1221,14 +1221,14 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `_get_timezone' function. */
#cmakedefine HAVE__GET_TIMEZONE 1
-/* Define to 1 if you have the `_gmtime64_s' function. */
-#cmakedefine HAVE__GMTIME64_S 1
+/* Define to 1 if you have the `gmtime_s' function. */
+#cmakedefine HAVE_GMTIME_S 1
-/* Define to 1 if you have the `_localtime64_s' function. */
-#cmakedefine HAVE__LOCALTIME64_S 1
+/* Define to 1 if you have the `localtime_s' function. */
+#cmakedefine HAVE_LOCALTIME_S 1
-/* Define to 1 if you have the `_mkgmtime64' function. */
-#cmakedefine HAVE__MKGMTIME64 1
+/* Define to 1 if you have the `_mkgmtime' function. */
+#cmakedefine HAVE__MKGMTIME 1
/* Define as const if the declaration of iconv() needs const. */
#define ICONV_CONST @ICONV_CONST@
diff --git a/build/version b/build/version
index 1af1bec7bba2..f95688df2e4b 100644
--- a/build/version
+++ b/build/version
@@ -1 +1 @@
-3006002
+3006003
diff --git a/configure.ac b/configure.ac
index 349e7580b5e0..24049852b65d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,15 +4,15 @@ 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.6.2])
-m4_define([LIBARCHIVE_VERSION_N],[3006002])
+m4_define([LIBARCHIVE_VERSION_S],[3.6.3dev])
+m4_define([LIBARCHIVE_VERSION_N],[3006003])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S())
m4_define([BSDCAT_VERSION_S],LIBARCHIVE_VERSION_S())
-AC_PREREQ([2.69])
+AC_PREREQ([2.71])
#
# Now starts the "real" configure script.
@@ -99,13 +99,12 @@ AM_CONDITIONAL([INC_CYGWIN_FILES], [test $inc_cygwin_files = yes])
dnl Defines that are required for specific platforms (e.g. -D_POSIX_SOURCE, etc)
PLATFORMCPPFLAGS=
case "$host_os" in
- *mingw* ) PLATFORMCPPFLAGS=-D__USE_MINGW_ANSI_STDIO ;;
+ *mingw* ) PLATFORMCPPFLAGS=-D__USE_MINGW_ANSI_STDIO -D__MINGW_USE_VC2005_COMPAT ;;
esac
AC_SUBST(PLATFORMCPPFLAGS)
# Checks for programs.
AC_PROG_CC
-AC_PROG_CC_C99
AM_PROG_CC_C_O
AC_PROG_CPP
AC_USE_SYSTEM_EXTENSIONS
@@ -378,7 +377,9 @@ if test "x$with_iconv" != "xno"; then
AC_CHECK_HEADERS([localcharset.h])
am_save_LIBS="$LIBS"
LIBS="${LIBS} ${LIBICONV}"
- LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }iconv"
+ if test -n "$LIBICONV"; then
+ LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }iconv"
+ fi
AC_CHECK_FUNCS([locale_charset])
LIBS="${am_save_LIBS}"
if test "x$ac_cv_func_locale_charset" != "xyes"; then
@@ -655,7 +656,7 @@ AC_CHECK_TYPE([wchar_t],
AX_COMPILE_CHECK_SIZEOF(int)
AX_COMPILE_CHECK_SIZEOF(long)
-AC_HEADER_TIME
+AC_CHECK_HEADERS_ONCE([sys/time.h])
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
@@ -687,8 +688,24 @@ AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strnlen strrchr symlink])
AC_CHECK_FUNCS([timegm tzset unlinkat unsetenv utime utimensat utimes vfork])
AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy wmemmove])
-AC_CHECK_FUNCS([_ctime64_s _fseeki64])
-AC_CHECK_FUNCS([_get_timezone _gmtime64_s _localtime64_s _mkgmtime64])
+AC_CHECK_FUNCS([_fseeki64 _get_timezone])
+AC_CHECK_DECL([cmtime_s],
+ [AC_DEFINE(HAVE_CMTIME_S, 1, [cmtime_s function])],
+ [],
+ [#include <time.h>])
+AC_CHECK_DECL([gmtime_s],
+ [AC_DEFINE(HAVE_GMTIME_S, 1, [gmtime_s function])],
+ [],
+ [#include <time.h>])
+AC_CHECK_TYPE([localtime_s],
+ [AC_DEFINE(HAVE_LOCALTIME_S, 1, [localtime_s function])],
+ [],
+ [#include <time.h>])
+AC_CHECK_DECL([_mkgmtime],
+ [AC_DEFINE(HAVE__MKGMTIME, 1, [_mkgmtime function])],
+ [],
+ [#include <time.h>])
+
# detects cygwin-1.7, as opposed to older versions
AC_CHECK_FUNCS([cygwin_conv_path])
@@ -1210,7 +1227,7 @@ fi
if test "x$with_openssl" != "xno"; then
AC_CHECK_HEADERS([openssl/evp.h])
saved_LIBS=$LIBS
- LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libssl libcrypto"
+ LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libcrypto"
AC_CHECK_LIB(crypto,OPENSSL_config)
CRYPTO_CHECK(MD5, OPENSSL, md5)
CRYPTO_CHECK(RMD160, OPENSSL, rmd160)
diff --git a/contrib/android/config/android.h b/contrib/android/config/android.h
index 8e18312449ed..0ccb20c4e8c4 100644
--- a/contrib/android/config/android.h
+++ b/contrib/android/config/android.h
@@ -180,5 +180,5 @@
#define SIZEOF_WCHAR_T 4
#define STDC_HEADERS 1
#define STRERROR_R_CHAR_P 1
-#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
#endif
diff --git a/contrib/android/config/linux_host.h b/contrib/android/config/linux_host.h
index 709b657c9da7..371c6cc480ad 100644
--- a/contrib/android/config/linux_host.h
+++ b/contrib/android/config/linux_host.h
@@ -183,7 +183,7 @@
#define SIZEOF_WCHAR_T 4
#define STDC_HEADERS 1
#define STRERROR_R_CHAR_P 1
-#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
#define _GNU_SOURCE 1
#endif
diff --git a/contrib/android/config/windows_host.h b/contrib/android/config/windows_host.h
index 2d899d1e75c6..712b7491be62 100644
--- a/contrib/android/config/windows_host.h
+++ b/contrib/android/config/windows_host.h
@@ -905,8 +905,8 @@
/* Define to 1 if you have the <zlib.h> header file. */
/* #undef HAVE_ZLIB_H */
-/* Define to 1 if you have the `_ctime64_s' function. */
-#define HAVE__CTIME64_S 1
+/* Define to 1 if you have the `ctime_s' function. */
+#define HAVE_CTIME_S 1
/* Define to 1 if you have the `_fseeki64' function. */
#define HAVE__FSEEKI64 1
@@ -914,11 +914,11 @@
/* Define to 1 if you have the `_get_timezone' function. */
/* #undef HAVE__GET_TIMEZONE */
-/* Define to 1 if you have the `_localtime64_s' function. */
-#define HAVE__LOCALTIME64_S 1
+/* Define to 1 if you have the `localtime_s' function. */
+#define HAVE_LOCALTIME_S 1
-/* Define to 1 if you have the `_mkgmtime64' function. */
-/* #define HAVE__MKGMTIME64 1 */
+/* Define to 1 if you have the `_mkgmtime' function. */
+/* #define HAVE__MKGMTIME 1 */
/* Define as const if the declaration of iconv() needs const. */
/* #undef ICONV_CONST */
@@ -952,7 +952,7 @@
/* #undef STRERROR_R_CHAR_P */
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 68a6301a8789..f2d83d94b647 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -442,6 +442,8 @@ main(int argc, char *argv[])
archive_match_free(cpio->matching);
free_cache(cpio->gname_cache);
free_cache(cpio->uname_cache);
+ archive_read_close(cpio->archive_read_disk);
+ archive_read_free(cpio->archive_read_disk);
free(cpio->destdir);
passphrase_free(cpio->ppbuff);
return (cpio->return_value);
@@ -1151,13 +1153,9 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
time_t mtime;
static time_t now;
struct tm *ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
if (!now)
time(&now);
@@ -1205,15 +1203,10 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
else
fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
#endif
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ ltime = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&mtime, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = mtime;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- ltime = NULL;
- else
- ltime = &tmbuf;
#else
ltime = localtime(&mtime);
#endif
diff --git a/cpio/test/test_option_J_upper.c b/cpio/test/test_option_J_upper.c
index 1d7d05131b3d..e19d599e1ec7 100644
--- a/cpio/test/test_option_J_upper.c
+++ b/cpio/test/test_option_J_upper.c
@@ -43,6 +43,7 @@ DEFINE_TEST(test_option_J_upper)
if (strstr(p, "compression not available") != NULL) {
skipping("This version of bsdcpio was compiled "
"without xz support");
+ free(p);
return;
}
failure("-J option is broken");
diff --git a/cpio/test/test_option_c.c b/cpio/test/test_option_c.c
index 013caed56030..dfa62c13b13e 100644
--- a/cpio/test/test_option_c.c
+++ b/cpio/test/test_option_c.c
@@ -37,10 +37,10 @@ is_octal(const char *p, size_t l)
return (1);
}
-static int
+static long long int
from_octal(const char *p, size_t l)
{
- int r = 0;
+ long long int r = 0;
while (l > 0) {
r *= 8;
@@ -161,7 +161,7 @@ DEFINE_TEST(test_option_c)
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
assertEqualMem(e + 36, "000001", 6); /* nlink */
- failure("file entries should have rdev == 0 (dev was 0%o)",
+ failure("file entries should have rdev == 0 (dev was 0%llo)",
from_octal(e + 6, 6));
assertEqualMem(e + 42, "000000", 6); /* rdev */
t = from_octal(e + 48, 11); /* mtime */
diff --git a/cpio/test/test_option_t.c b/cpio/test/test_option_t.c
index 0f2dda27cc20..9eef0da571c4 100644
--- a/cpio/test/test_option_t.c
+++ b/cpio/test/test_option_t.c
@@ -37,13 +37,9 @@ DEFINE_TEST(test_option_t)
char date[32];
char date2[32];
struct tm *tmptr;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
/* List reference archive, make sure the TOC is correct. */
extract_reference_file("test_option_t.cpio");
@@ -95,15 +91,10 @@ DEFINE_TEST(test_option_t)
#ifdef HAVE_LOCALE_H
setlocale(LC_ALL, "");
#endif
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tmptr = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
tmptr = localtime_r(&mtime, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = mtime;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- tmptr = NULL;
- else
- tmptr = &tmbuf;
#else
tmptr = localtime(&mtime);
#endif
diff --git a/libarchive/archive.h b/libarchive/archive.h
index 217ac198931e..fa293ddfd34a 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3006002
+#define ARCHIVE_VERSION_NUMBER 3006003
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -157,7 +157,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.6.2"
+#define ARCHIVE_VERSION_ONLY_STRING "3.6.3dev"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h
index e579e9f33123..13d95fc5bea0 100644
--- a/libarchive/archive_entry.h
+++ b/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3006002
+#define ARCHIVE_VERSION_NUMBER 3006003
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/libarchive/archive_getdate.c b/libarchive/archive_getdate.c
index 39e224cb9010..20ab1b1588fe 100644
--- a/libarchive/archive_getdate.c
+++ b/libarchive/archive_getdate.c
@@ -698,13 +698,9 @@ Convert(time_t Month, time_t Day, time_t Year,
time_t Julian;
int i;
struct tm *ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
if (Year < 69)
Year += 2000;
@@ -731,15 +727,10 @@ Convert(time_t Month, time_t Day, time_t Year,
Julian *= DAY;
Julian += Timezone;
Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Julian, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = Julian;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- ltime = NULL;
- else
- ltime = &tmbuf;
#else
ltime = localtime(&Julian);
#endif
@@ -755,36 +746,21 @@ DSTcorrect(time_t Start, time_t Future)
time_t StartDay;
time_t FutureDay;
struct tm *ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
-
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = Start;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- ltime = NULL;
- else
- ltime = &tmbuf;
#else
ltime = localtime(&Start);
#endif
StartDay = (ltime->tm_hour + 1) % 24;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Future, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = Future;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- ltime = NULL;
- else
- ltime = &tmbuf;
#else
ltime = localtime(&Future);
#endif
@@ -799,24 +775,15 @@ RelativeDate(time_t Start, time_t zone, int dstmode,
{
struct tm *tm;
time_t t, now;
-#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__GMTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
t = Start - zone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+ tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_GMTIME_R)
tm = gmtime_r(&t, &tmbuf);
-#elif defined(HAVE__GMTIME64_S)
- tmptime = t;
- terr = _gmtime64_s(&tmbuf, &tmptime);
- if (terr)
- tm = NULL;
- else
- tm = &tmbuf;
#else
tm = gmtime(&t);
#endif
@@ -835,25 +802,16 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
struct tm *tm;
time_t Month;
time_t Year;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
if (RelMonth == 0)
return 0;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = Start;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- tm = NULL;
- else
- tm = &tmbuf;
#else
tm = localtime(&Start);
#endif
@@ -993,10 +951,6 @@ __archive_get_date(time_t now, const char *p)
time_t Start;
time_t tod;
long tzone;
-#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
/* Clear out the parsed token array. */
memset(tokens, 0, sizeof(tokens));
@@ -1005,36 +959,26 @@ __archive_get_date(time_t now, const char *p)
gds = &_gds;
/* Look up the current time. */
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tm = localtime_s(&local, &now) ? NULL : &local;
+#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&now, &local);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = now;
- terr = _localtime64_s(&local, &tmptime);
- if (terr)
- tm = NULL;
- else
- tm = &local;
#else
memset(&local, 0, sizeof(local));
tm = localtime(&now);
#endif
if (tm == NULL)
return -1;
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
local = *tm;
#endif
/* Look up UTC if we can and use that to determine the current
* timezone offset. */
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+ gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
- tmptime = now;
- terr = _gmtime64_s(&gmt, &tmptime);
- if (terr)
- gmt_ptr = NULL;
- else
- gmt_ptr = &gmt;
#else
memset(&gmt, 0, sizeof(gmt));
gmt_ptr = gmtime(&now);
@@ -1076,15 +1020,10 @@ __archive_get_date(time_t now, const char *p)
* time components instead of the local timezone. */
if (gds->HaveZone && gmt_ptr != NULL) {
now -= gds->Timezone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+ gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
- tmptime = now;
- terr = _gmtime64_s(&gmt, &tmptime);
- if (terr)
- gmt_ptr = NULL;
- else
- gmt_ptr = &gmt;
#else
gmt_ptr = gmtime(&now);
#endif
diff --git a/libarchive/archive_hmac.c b/libarchive/archive_hmac.c
index 012fe1596211..edb3bf5abd42 100644
--- a/libarchive/archive_hmac.c
+++ b/libarchive/archive_hmac.c
@@ -231,15 +231,20 @@ static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- OSSL_PARAM params[2];
+ EVP_MAC *mac;
- EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ char sha1[] = "SHA1";
+ OSSL_PARAM params[] = {
+ OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
+ OSSL_PARAM_END
+ };
+
+ mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
*ctx = EVP_MAC_CTX_new(mac);
+ EVP_MAC_free(mac);
if (*ctx == NULL)
return -1;
- EVP_MAC_free(mac);
- params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
- params[1] = OSSL_PARAM_construct_end();
+
EVP_MAC_init(*ctx, key, key_len, params);
#else
*ctx = HMAC_CTX_new();
diff --git a/libarchive/archive_hmac_private.h b/libarchive/archive_hmac_private.h
index 50044a045e37..d0fda7f9667a 100644
--- a/libarchive/archive_hmac_private.h
+++ b/libarchive/archive_hmac_private.h
@@ -77,6 +77,8 @@ typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
#include <openssl/opensslv.h>
#include <openssl/hmac.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/params.h>
+
typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
#else
diff --git a/libarchive/archive_read_data_into_fd.c b/libarchive/archive_read_data_into_fd.c
index b4398f1ecce8..f16ca5c82b15 100644
--- a/libarchive/archive_read_data_into_fd.c
+++ b/libarchive/archive_read_data_into_fd.c
@@ -95,8 +95,13 @@ archive_read_data_into_fd(struct archive *a, int fd)
"archive_read_data_into_fd");
can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
- if (!can_lseek)
+ if (!can_lseek) {
nulls = calloc(1, nulls_size);
+ if (!nulls) {
+ r = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ }
while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
ARCHIVE_OK) {
diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c
index 101dae6cd9e3..03719e8bff0c 100644
--- a/libarchive/archive_read_open_file.c
+++ b/libarchive/archive_read_open_file.c
@@ -154,10 +154,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
#ifdef __ANDROID__
/* fileno() isn't safe on all platforms ... see above. */
if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
-#elif HAVE_FSEEKO
- if (fseeko(mine->f, skip, SEEK_CUR) != 0)
#elif HAVE__FSEEKI64
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
+#elif HAVE_FSEEKO
+ if (fseeko(mine->f, skip, SEEK_CUR) != 0)
#else
if (fseek(mine->f, skip, SEEK_CUR) != 0)
#endif
diff --git a/libarchive/archive_read_support_filter_zstd.c b/libarchive/archive_read_support_filter_zstd.c
index 39f25f1bf88e..1959b5ac3991 100644
--- a/libarchive/archive_read_support_filter_zstd.c
+++ b/libarchive/archive_read_support_filter_zstd.c
@@ -115,9 +115,9 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
unsigned prefix;
/* Zstd frame magic values */
- const unsigned zstd_magic = 0xFD2FB528U;
- const unsigned zstd_magic_skippable_start = 0x184D2A50U;
- const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
+ unsigned zstd_magic = 0xFD2FB528U;
+ unsigned zstd_magic_skippable_start = 0x184D2A50U;
+ unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
(void) self; /* UNUSED */
@@ -170,7 +170,7 @@ static int
zstd_bidder_init(struct archive_read_filter *self)
{
struct private_data *state;
- const size_t out_block_size = ZSTD_DStreamOutSize();
+ size_t out_block_size = ZSTD_DStreamOutSize();
void *out_block;
ZSTD_DStream *dstream;
@@ -211,6 +211,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
ssize_t avail_in;
ZSTD_outBuffer out;
ZSTD_inBuffer in;
+ size_t ret;
state = (struct private_data *)self->data;
@@ -219,7 +220,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
/* Try to fill the output buffer. */
while (out.pos < out.size && !state->eof) {
if (!state->in_frame) {
- const size_t ret = ZSTD_initDStream(state->dstream);
+ ret = ZSTD_initDStream(state->dstream);
if (ZSTD_isError(ret)) {
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC,
@@ -249,8 +250,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
in.pos = 0;
{
- const size_t ret =
- ZSTD_decompressStream(state->dstream, &out, &in);
+ ret = ZSTD_decompressStream(state->dstream, &out, &in);
if (ZSTD_isError(ret)) {
archive_set_error(&self->archive->archive,
diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
index 6b8ae33a480b..a4899144965c 100644
--- a/libarchive/archive_read_support_format_cpio.c
+++ b/libarchive/archive_read_support_format_cpio.c
@@ -441,7 +441,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
- 11) == 0) {
+ 10) == 0) {
/* TODO: Store file location of start of block. */
archive_clear_error(&a->archive);
return (ARCHIVE_EOF);
diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index 33bf330cbfe4..f5414be2a565 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -1901,7 +1901,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* NUMBER of RRIP "PX" extension.
* Note: Old mkisofs did not record that FILE SERIAL NUMBER
* in ISO images.
- * Note2: xorriso set 0 to the location of a symlink file.
+ * Note2: xorriso set 0 to the location of a symlink file.
*/
if (file->size == 0 && location >= 0) {
/* If file->size is zero, its location points wrong place,
@@ -1955,7 +1955,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* made by makefs is not zero and its location is
* the same as those of next regular file. That is
* the same as hard like file and it causes unexpected
- * error.
+ * error.
*/
if (file->size > 0 &&
(file->mode & AE_IFMT) == AE_IFLNK) {
@@ -2747,7 +2747,7 @@ next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
* If directory entries all which are descendant of
* rr_moved are still remaining, expose their.
*/
- if (iso9660->re_files.first != NULL &&
+ if (iso9660->re_files.first != NULL &&
iso9660->rr_moved != NULL &&
iso9660->rr_moved->rr_moved_has_re_only)
/* Expose "rr_moved" entry. */
@@ -3180,11 +3180,11 @@ isodate17(const unsigned char *v)
static time_t
time_from_tm(struct tm *t)
{
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+ return _mkgmtime(t);
+#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
-#elif HAVE__MKGMTIME64
- return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
index 793e8e985214..8f239da9b39d 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -1830,13 +1830,9 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
struct tm *tm;
time_t t;
long nsec;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
if (p + 2 > endp)
return (-1);
@@ -1868,15 +1864,10 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
p++;
}
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = t;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- tm = NULL;
- else
- tm = &tmbuf;
#else
tm = localtime(&t);
#endif
diff --git a/libarchive/archive_read_support_format_warc.c b/libarchive/archive_read_support_format_warc.c
index 27329962d6d1..61ab29ea145d 100644
--- a/libarchive/archive_read_support_format_warc.c
+++ b/libarchive/archive_read_support_format_warc.c
@@ -530,11 +530,11 @@ strtoi_lim(const char *str, const char **ep, int llim, int ulim)
static time_t
time_from_tm(struct tm *t)
{
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+ return _mkgmtime(t);
+#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
-#elif HAVE__MKGMTIME64
- return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c
index ec5b06edacd5..ec9cb1981f3d 100644
--- a/libarchive/archive_read_support_format_xar.c
+++ b/libarchive/archive_read_support_format_xar.c
@@ -1127,7 +1127,7 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
x |= p[1] - '0';
else
return (-1);
-
+
*b++ = x;
bsize--;
p += 2;
@@ -1139,11 +1139,11 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
static time_t
time_from_tm(struct tm *t)
{
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+ return _mkgmtime(t);
+#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
-#elif HAVE__MKGMTIME64
- return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
index 27626b54147f..ec3c95c56685 100644
--- a/libarchive/archive_write.c
+++ b/libarchive/archive_write.c
@@ -310,6 +310,25 @@ __archive_write_output(struct archive_write *a, const void *buff, size_t length)
return (__archive_write_filter(a->filter_first, buff, length));
}
+static int
+__archive_write_filters_flush(struct archive_write *a)
+{
+ struct archive_write_filter *f;
+ int ret, ret1;
+
+ ret = ARCHIVE_OK;
+ for (f = a->filter_first; f != NULL; f = f->next_filter) {
+ if (f->flush != NULL && f->bytes_written > 0) {
+ ret1 = (f->flush)(f);
+ if (ret1 < ret)
+ ret = ret1;
+ if (ret1 < ARCHIVE_WARN)
+ f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
+ }
+ }
+ return (ret);
+}
+
int
__archive_write_nulls(struct archive_write *a, size_t length)
{
@@ -740,6 +759,18 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
return (ARCHIVE_FAILED);
}
+ /* Flush filters at boundary. */
+ r2 = __archive_write_filters_flush(a);
+ if (r2 == ARCHIVE_FAILED) {
+ return (ARCHIVE_FAILED);
+ }
+ if (r2 == ARCHIVE_FATAL) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ if (r2 < ret)
+ ret = r2;
+
/* Format and write header. */
r2 = ((a->format_write_header)(a, entry));
if (r2 == ARCHIVE_FAILED) {
diff --git a/libarchive/archive_write_add_filter_zstd.c b/libarchive/archive_write_add_filter_zstd.c
index e85b7669c50d..37c5e741ebee 100644
--- a/libarchive/archive_write_add_filter_zstd.c
+++ b/libarchive/archive_write_add_filter_zstd.c
@@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -50,10 +53,21 @@ __FBSDID("$FreeBSD$");
struct private_data {
int compression_level;
- int threads;
+ int threads;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+ enum {
+ running,
+ finishing,
+ resetting,
+ } state;
+ int frame_per_file;
+ size_t min_frame_size;
+ size_t max_frame_size;
+ size_t cur_frame;
+ size_t cur_frame_in;
+ size_t cur_frame_out;
+ size_t total_in;
ZSTD_CStream *cstream;
- int64_t total_in;
ZSTD_outBuffer out;
#else
struct archive_write_program_data *pdata;
@@ -75,6 +89,7 @@ static int archive_compressor_zstd_options(struct archive_write_filter *,
static int archive_compressor_zstd_open(struct archive_write_filter *);
static int archive_compressor_zstd_write(struct archive_write_filter *,
const void *, size_t);
+static int archive_compressor_zstd_flush(struct archive_write_filter *);
static int archive_compressor_zstd_close(struct archive_write_filter *);
static int archive_compressor_zstd_free(struct archive_write_filter *);
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
@@ -103,6 +118,7 @@ archive_write_add_filter_zstd(struct archive *_a)
f->data = data;
f->open = &archive_compressor_zstd_open;
f->options = &archive_compressor_zstd_options;
+ f->flush = &archive_compressor_zstd_flush;
f->close = &archive_compressor_zstd_close;
f->free = &archive_compressor_zstd_free;
f->code = ARCHIVE_FILTER_ZSTD;
@@ -110,6 +126,11 @@ archive_write_add_filter_zstd(struct archive *_a)
data->compression_level = CLEVEL_DEFAULT;
data->threads = 0;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+ data->frame_per_file = 0;
+ data->min_frame_size = 0;
+ data->max_frame_size = SIZE_MAX;
+ data->cur_frame_in = 0;
+ data->cur_frame_out = 0;
data->cstream = ZSTD_createCStream();
if (data->cstream == NULL) {
free(data);
@@ -147,29 +168,18 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
return (ARCHIVE_OK);
}
-static int string_is_numeric (const char* value)
+static int string_to_number(const char *string, intmax_t *numberp)
{
- size_t len = strlen(value);
- size_t i;
-
- if (len == 0) {
- return (ARCHIVE_WARN);
- }
- else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
- return (ARCHIVE_WARN);
- }
- else if (!(value[0] >= '0' && value[0] <= '9') &&
- value[0] != '-' && value[0] != '+') {
- return (ARCHIVE_WARN);
- }
-
- for (i = 1; i < len; i++) {
- if (!(value[i] >= '0' && value[i] <= '9')) {
- return (ARCHIVE_WARN);
- }
- }
-
- return (ARCHIVE_OK);
+ char *end;
+
+ if (string == NULL || *string == '\0')
+ return (ARCHIVE_WARN);
+ *numberp = strtoimax(string, &end, 10);
+ if (end == string || *end != '\0' || errno == EOVERFLOW) {
+ *numberp = 0;
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
}
/*
@@ -182,13 +192,13 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
struct private_data *data = (struct private_data *)f->data;
if (strcmp(key, "compression-level") == 0) {
- int level = atoi(value);
+ intmax_t level;
+ if (string_to_number(value, &level) != ARCHIVE_OK) {
+ return (ARCHIVE_WARN);
+ }
/* If we don't have the library, hard-code the max level */
int minimum = CLEVEL_MIN;
int maximum = CLEVEL_MAX;
- if (string_is_numeric(value) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
- }
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
maximum = ZSTD_maxCLevel();
#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
@@ -207,19 +217,40 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
data->compression_level = level;
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
- int threads = atoi(value);
- if (string_is_numeric(value) != ARCHIVE_OK) {
+ intmax_t threads;
+ if (string_to_number(value, &threads) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
-
- int minimum = 0;
-
- if (threads < minimum) {
+ if (threads < 0) {
return (ARCHIVE_WARN);
}
-
data->threads = threads;
return (ARCHIVE_OK);
+#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+ } else if (strcmp(key, "frame-per-file") == 0) {
+ data->frame_per_file = 1;
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "min-frame-size") == 0) {
+ intmax_t min_frame_size;
+ if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) {
+ return (ARCHIVE_WARN);
+ }
+ if (min_frame_size < 0) {
+ return (ARCHIVE_WARN);
+ }
+ data->min_frame_size = min_frame_size;
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "max-frame-size") == 0) {
+ intmax_t max_frame_size;
+ if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) {
+ return (ARCHIVE_WARN);
+ }
+ if (max_frame_size < 1024) {
+ return (ARCHIVE_WARN);
+ }
+ data->max_frame_size = max_frame_size;
+ return (ARCHIVE_OK);
+#endif
}
/* Note: The "warn" return is just to inform the options
@@ -281,15 +312,22 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
size_t length)
{
struct private_data *data = (struct private_data *)f->data;
- int ret;
- /* Update statistics */
- data->total_in += length;
+ return (drive_compressor(f, data, 0, buff, length));
+}
- if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
- return (ret);
+/*
+ * Flush the compressed stream.
+ */
+static int
+archive_compressor_zstd_flush(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
- return (ARCHIVE_OK);
+ if (data->frame_per_file && data->state == running &&
+ data->cur_frame_out > data->min_frame_size)
+ data->state = finishing;
+ return (drive_compressor(f, data, 1, NULL, 0));
}
/*
@@ -300,57 +338,72 @@ archive_compressor_zstd_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- /* Finish zstd frame */
- return drive_compressor(f, data, 1, NULL, 0);
+ if (data->state == running)
+ data->state = finishing;
+ return (drive_compressor(f, data, 1, NULL, 0));
}
/*
* Utility function to push input data through compressor,
* writing full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
*/
static int
drive_compressor(struct archive_write_filter *f,
- struct private_data *data, int finishing, const void *src, size_t length)
+ struct private_data *data, int flush, const void *src, size_t length)
{
- ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
+ ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 };
+ size_t ipos, opos, zstdret = 0;
+ int ret;
for (;;) {
- if (data->out.pos == data->out.size) {
- const int ret = __archive_write_filter(f->next_filter,
- data->out.dst, data->out.size);
+ ipos = in.pos;
+ opos = data->out.pos;
+ switch (data->state) {
+ case running:
+ if (in.pos == in.size)
+ return (ARCHIVE_OK);
+ zstdret = ZSTD_compressStream(data->cstream,
+ &data->out, &in);
+ if (ZSTD_isError(zstdret))
+ goto zstd_fatal;
+ break;
+ case finishing:
+ zstdret = ZSTD_endStream(data->cstream, &data->out);
+ if (ZSTD_isError(zstdret))
+ goto zstd_fatal;
+ if (zstdret == 0)
+ data->state = resetting;
+ break;
+ case resetting:
+ ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only);
+ data->cur_frame++;
+ data->cur_frame_in = 0;
+ data->cur_frame_out = 0;
+ data->state = running;
+ break;
+ }
+ data->total_in += in.pos - ipos;
+ data->cur_frame_in += in.pos - ipos;
+ data->cur_frame_out += data->out.pos - opos;
+ if (data->state == running &&
+ data->cur_frame_in >= data->max_frame_size) {
+ data->state = finishing;
+ }
+ if (data->out.pos == data->out.size ||
+ (flush && data->out.pos > 0)) {
+ ret = __archive_write_filter(f->next_filter,
+ data->out.dst, data->out.pos);
if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
+ goto fatal;
data->out.pos = 0;
}
-
- /* If there's nothing to do, we're done. */
- if (!finishing && in.pos == in.size)
- return (ARCHIVE_OK);
-
- {
- const size_t zstdret = !finishing ?
- ZSTD_compressStream(data->cstream, &data->out, &in)
- : ZSTD_endStream(data->cstream, &data->out);
-
- if (ZSTD_isError(zstdret)) {
- archive_set_error(f->archive,
- ARCHIVE_ERRNO_MISC,
- "Zstd compression failed: %s",
- ZSTD_getErrorName(zstdret));
- return (ARCHIVE_FATAL);
- }
-
- /* If we're finishing, 0 means nothing left to flush */
- if (finishing && zstdret == 0) {
- const int ret = __archive_write_filter(f->next_filter,
- data->out.dst, data->out.pos);
- return (ret);
- }
- }
}
+zstd_fatal:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Zstd compression failed: %s",
+ ZSTD_getErrorName(zstdret));
+fatal:
+ return (ARCHIVE_FATAL);
}
#else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
@@ -367,17 +420,9 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
archive_strcpy(&as, "zstd --no-check");
if (data->compression_level < CLEVEL_STD_MIN) {
- struct archive_string as2;
- archive_string_init(&as2);
- archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
- archive_string_concat(&as, &as2);
- archive_string_free(&as2);
+ archive_string_sprintf(&as, " --fast=%d", -data->compression_level);
} else {
- struct archive_string as2;
- archive_string_init(&as2);
- archive_string_sprintf(&as2, " -%d", data->compression_level);
- archive_string_concat(&as, &as2);
- archive_string_free(&as2);
+ archive_string_sprintf(&as, " -%d", data->compression_level);
}
if (data->compression_level > CLEVEL_STD_MAX) {
@@ -385,11 +430,7 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
}
if (data->threads != 0) {
- struct archive_string as2;
- archive_string_init(&as2);
- archive_string_sprintf(&as2, " --threads=%d", data->threads);
- archive_string_concat(&as, &as2);
- archive_string_free(&as2);
+ archive_string_sprintf(&as, " --threads=%d", data->threads);
}
f->write = archive_compressor_zstd_write;
@@ -408,6 +449,13 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
}
static int
+archive_compressor_zstd_flush(struct archive_write_filter *f)
+{
+
+ return (ARCHIVE_OK);
+}
+
+static int
archive_compressor_zstd_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
diff --git a/libarchive/archive_write_private.h b/libarchive/archive_write_private.h
index 155fdd734887..6522e6521beb 100644
--- a/libarchive/archive_write_private.h
+++ b/libarchive/archive_write_private.h
@@ -53,6 +53,7 @@ struct archive_write_filter {
const char *key, const char *value);
int (*open)(struct archive_write_filter *);
int (*write)(struct archive_write_filter *, const void *, size_t);
+ int (*flush)(struct archive_write_filter *);
int (*close)(struct archive_write_filter *);
int (*free)(struct archive_write_filter *);
void *data;
diff --git a/libarchive/archive_write_set_format_7zip.c b/libarchive/archive_write_set_format_7zip.c
index d5ca9a665654..95fd7164527e 100644
--- a/libarchive/archive_write_set_format_7zip.c
+++ b/libarchive/archive_write_set_format_7zip.c
@@ -165,7 +165,7 @@ struct file {
mode_t mode;
uint32_t crc32;
- signed int dir:1;
+ unsigned dir:1;
};
struct _7zip {
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
index 58b7216a8071..2a3ae07fa2b2 100644
--- a/libarchive/archive_write_set_format_iso9660.c
+++ b/libarchive/archive_write_set_format_iso9660.c
@@ -289,12 +289,12 @@ struct isoent {
struct extr_rec *current;
} extr_rec_list;
- signed int virtual:1;
+ unsigned int virtual:1;
/* If set to one, this file type is a directory.
* A convenience flag to be used as
* "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
*/
- signed int dir:1;
+ unsigned int dir:1;
};
struct hardlink {
@@ -652,7 +652,7 @@ struct iso_option {
#define VOLUME_IDENTIFIER_SIZE 32
/*
- * Usage : !zisofs [DEFAULT]
+ * Usage : !zisofs [DEFAULT]
* : Disable to generate RRIP 'ZF' extension.
* : zisofs
* : Make files zisofs file and generate RRIP 'ZF'
@@ -689,7 +689,7 @@ struct iso9660 {
uint64_t bytes_remaining;
int need_multi_extent;
- /* Temporary string buffer for Joliet extension. */
+ /* Temporary string buffer for Joliet extension. */
struct archive_string utf16be;
struct archive_string mbs;
@@ -755,9 +755,9 @@ struct iso9660 {
/* Used for making zisofs. */
struct {
- signed int detect_magic:1;
- signed int making:1;
- signed int allzero:1;
+ unsigned int detect_magic:1;
+ unsigned int making:1;
+ unsigned int allzero:1;
unsigned char magic_buffer[64];
int magic_cnt;
@@ -2521,12 +2521,11 @@ get_gmoffset(struct tm *tm)
static void
get_tmfromtime(struct tm *tm, time_t *t)
{
-#if HAVE_LOCALTIME_R
+#if HAVE_LOCALTIME_S
+ localtime_s(tm, t);
+#elif HAVE_LOCALTIME_R
tzset();
localtime_r(t, tm);
-#elif HAVE__LOCALTIME64_S
- __time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
- _localtime64_s(tm, &tmp_t);
#else
memcpy(tm, localtime(t), sizeof(*tm));
#endif
@@ -4074,11 +4073,8 @@ write_information_block(struct archive_write *a)
}
memset(info.s, 0, info_size);
opt = 0;
-#if defined(HAVE__CTIME64_S)
- {
- __time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
- _ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
- }
+#if defined(HAVE_CTIME_S)
+ ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
#elif defined(HAVE_CTIME_R)
ctime_r(&(iso9660->birth_time), buf);
#else
@@ -7802,8 +7798,8 @@ struct zisofs_extract {
uint64_t pz_uncompressed_size;
size_t uncompressed_buffer_size;
- signed int initialized:1;
- signed int header_passed:1;
+ unsigned int initialized:1;
+ unsigned int header_passed:1;
uint32_t pz_offset;
unsigned char *block_pointers;
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
index cf1f4770ebe6..f946fc7b5acd 100644
--- a/libarchive/archive_write_set_format_pax.c
+++ b/libarchive/archive_write_set_format_pax.c
@@ -45,6 +45,15 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_pax.c 201162 20
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
+ /*
+ * Technically, the mtime field in the ustar header can
+ * support 33 bits. We are using all of them to keep
+ * tar/test/test_option_C_mtree.c simple and passing after 2038.
+ * Platforms that use signed 32-bit time values need to fix
+ * their handling of timestamps anyway.
+ */
+#define USTAR_MAX_MTIME 0x1ffffffff
+
struct sparse_block {
struct sparse_block *next;
int is_hole;
@@ -1116,16 +1125,13 @@ archive_write_pax_header(struct archive_write *a,
}
/*
- * Technically, the mtime field in the ustar header can
- * support 33 bits, but many platforms use signed 32-bit time
- * values. The cutoff of 0x7fffffff here is a compromise.
* Yes, this check is duplicated just below; this helps to
* avoid writing an mtime attribute just to handle a
* high-resolution timestamp in "restricted pax" mode.
*/
if (!need_extension &&
((archive_entry_mtime(entry_main) < 0)
- || (archive_entry_mtime(entry_main) >= 0x7fffffff)))
+ || (archive_entry_mtime(entry_main) >= USTAR_MAX_MTIME)))
need_extension = 1;
/* I use a star-compatible file flag attribute. */
@@ -1190,7 +1196,7 @@ archive_write_pax_header(struct archive_write *a,
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
need_extension) {
if (archive_entry_mtime(entry_main) < 0 ||
- archive_entry_mtime(entry_main) >= 0x7fffffff ||
+ archive_entry_mtime(entry_main) >= USTAR_MAX_MTIME ||
archive_entry_mtime_nsec(entry_main) != 0)
add_pax_attr_time(&(pax->pax_header), "mtime",
archive_entry_mtime(entry_main),
@@ -1428,7 +1434,7 @@ archive_write_pax_header(struct archive_write *a,
/* Copy mtime, but clip to ustar limits. */
s = archive_entry_mtime(entry_main);
if (s < 0) { s = 0; }
- if (s >= 0x7fffffff) { s = 0x7fffffff; }
+ if (s > USTAR_MAX_MTIME) { s = USTAR_MAX_MTIME; }
archive_entry_set_mtime(pax_attr_entry, s, 0);
/* Standard ustar doesn't support atime. */
diff --git a/libarchive/archive_write_set_format_warc.c b/libarchive/archive_write_set_format_warc.c
index 46b05734121c..0ef003e2fc94 100644
--- a/libarchive/archive_write_set_format_warc.c
+++ b/libarchive/archive_write_set_format_warc.c
@@ -329,30 +329,21 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
{
/** like strftime(3) but for time_t objects */
struct tm *rt;
-#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
struct tm timeHere;
#endif
-#if defined(HAVE__GMTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
char strtime[100];
size_t len;
-#ifdef HAVE_GMTIME_R
- if ((rt = gmtime_r(&t, &timeHere)) == NULL)
- return;
-#elif defined(HAVE__GMTIME64_S)
- tmptime = t;
- terr = _gmtime64_s(&timeHere, &tmptime);
- if (terr)
- rt = NULL;
- else
- rt = &timeHere;
+#if defined(HAVE_GMTIME_S)
+ rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere;
+#elif defined(HAVE_GMTIME_R)
+ rt = gmtime_r(&t, &timeHere);
#else
- if ((rt = gmtime(&t)) == NULL)
- return;
+ rt = gmtime(&t);
#endif
+ if (!rt)
+ return;
/* leave the hard yacker to our role model strftime() */
len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
archive_strncat(as, strtime, len);
diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c
index d885f5c256d3..7307757d37a1 100644
--- a/libarchive/archive_write_set_format_xar.c
+++ b/libarchive/archive_write_set_format_xar.c
@@ -212,8 +212,8 @@ struct file {
struct heap_data data;
struct archive_string script;
- signed int virtual:1;
- signed int dir:1;
+ unsigned int virtual:1;
+ unsigned int dir:1;
};
struct hardlink {
@@ -906,15 +906,11 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
{
char timestr[100];
struct tm tm;
-#if defined(HAVE__GMTIME64_S)
- __time64_t tmptime;
-#endif
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+ gmtime_s(&tm, &t);
+#elif defined(HAVE_GMTIME_R)
gmtime_r(&t, &tm);
-#elif defined(HAVE__GMTIME64_S)
- tmptime = t;
- _gmtime64_s(&tm, &tmptime);
#else
memcpy(&tm, gmtime(&t), sizeof(tm));
#endif
diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c
index 8c14a7027eba..6821049c945a 100644
--- a/libarchive/archive_write_set_format_zip.c
+++ b/libarchive/archive_write_set_format_zip.c
@@ -1382,25 +1382,14 @@ dos_time(const time_t unix_time)
{
struct tm *t;
unsigned int dt;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
- /* This will not preserve time when creating/extracting the archive
- * on two systems with different time zones. */
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
t = localtime_r(&unix_time, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = unix_time;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- t = NULL;
- else
- t = &tmbuf;
#else
t = localtime(&unix_time);
#endif
diff --git a/libarchive/config_freebsd.h b/libarchive/config_freebsd.h
index 758621c4b68f..498fd4c5d2c3 100644
--- a/libarchive/config_freebsd.h
+++ b/libarchive/config_freebsd.h
@@ -234,7 +234,7 @@
#define HAVE_WMEMCPY 1
#define HAVE_WMEMMOVE 1
#define HAVE_ZLIB_H 1
-#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
#if __FreeBSD_version >= 800505
#define HAVE_LIBLZMA 1
diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c
index 54aae0ed1784..34f33ccb3f93 100644
--- a/libarchive/test/test_read_format_rar5.c
+++ b/libarchive/test/test_read_format_rar5.c
@@ -1310,6 +1310,8 @@ DEFINE_TEST(test_read_format_rar5_sfx)
assertA(size == archive_read_data(a, buff, size));
assertEqualMem(buff, test_txt, size);
+
+ EPILOGUE();
}
DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read)
diff --git a/libarchive/test/test_read_format_zip.c b/libarchive/test/test_read_format_zip.c
index 642a5e222ebe..6809641432ce 100644
--- a/libarchive/test/test_read_format_zip.c
+++ b/libarchive/test/test_read_format_zip.c
@@ -746,6 +746,7 @@ DEFINE_TEST(test_read_format_zip_zstd_one_file)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
+ archive_read_free(a);
return;
}
extract_reference_file(refname);
@@ -771,6 +772,7 @@ DEFINE_TEST(test_read_format_zip_zstd_one_file_blockread)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
+ archive_read_free(a);
return;
}
extract_reference_file(refname);
@@ -796,6 +798,7 @@ DEFINE_TEST(test_read_format_zip_zstd_multi)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
+ archive_read_free(a);
return;
}
extract_reference_file(refname);
@@ -833,6 +836,7 @@ DEFINE_TEST(test_read_format_zip_zstd_multi_blockread)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
+ archive_read_free(a);
return;
}
extract_reference_file(refname);
@@ -1017,6 +1021,7 @@ DEFINE_TEST(test_read_format_zip_lzma_alone_leak)
if(ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading is not fully supported on this platform");
archive_read_close(a);
+ archive_read_free(a);
return;
}
diff --git a/libarchive/test/test_short_writes.c b/libarchive/test/test_short_writes.c
index afa0206f07cd..8221cece1721 100644
--- a/libarchive/test/test_short_writes.c
+++ b/libarchive/test/test_short_writes.c
@@ -171,6 +171,8 @@ checker_free(struct checker *checker)
{
free(checker->shortbuf);
free(checker->fullbuf);
+ archive_read_free(checker->short_archive);
+ archive_read_free(checker->full_archive);
free(checker);
}
diff --git a/libarchive/test/test_write_filter_zstd.c b/libarchive/test/test_write_filter_zstd.c
index 263cea5bc49e..aa77b49860c0 100644
--- a/libarchive/test/test_write_filter_zstd.c
+++ b/libarchive/test/test_write_filter_zstd.c
@@ -133,6 +133,33 @@ DEFINE_TEST(test_write_filter_zstd)
archive_write_set_filter_option(a, NULL, "threads", "-1")); /* negative */
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "threads", "4"));
+#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+ /* frame-per-file: boolean */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "frame-per-file", ""));
+ /* min-frame-size: >= 0 */
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "min-frame-size", ""));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "min-frame-size", "-1"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "min-frame-size", "0"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "min-frame-size", "1048576"));
+ /* max-frame-size: >= 1024 */
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "max-frame-size", ""));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "max-frame-size", "-1"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "max-frame-size", "0"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "max-frame-size", "1023"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "max-frame-size", "1024"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "max-frame-size", "1048576"));
+#endif
assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
snprintf(path, sizeof(path), "file%03d", i);
diff --git a/libarchive/test/test_write_format_zip_compression_store.c b/libarchive/test/test_write_format_zip_compression_store.c
index ed0908787579..b52d170ccea0 100644
--- a/libarchive/test/test_write_format_zip_compression_store.c
+++ b/libarchive/test/test_write_format_zip_compression_store.c
@@ -129,26 +129,17 @@ static void verify_uncompressed_contents(const char *buff, size_t used)
/* Misc variables */
unsigned long crc;
struct tm *tm;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
/* p is the pointer to walk over the central directory,
* q walks over the local headers, the data and the data descriptors. */
const char *p, *q, *local_header, *extra_start;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tm = localtime_s(&tmbuf, &now) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&now, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = now;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- tm = NULL;
- else
- tm = &tmbuf;
#else
tm = localtime(&now);
#endif
diff --git a/libarchive/test/test_write_format_zip_file.c b/libarchive/test/test_write_format_zip_file.c
index 7796a48cdac3..4ccc30360691 100644
--- a/libarchive/test/test_write_format_zip_file.c
+++ b/libarchive/test/test_write_format_zip_file.c
@@ -74,13 +74,9 @@ DEFINE_TEST(test_write_format_zip_file)
struct archive_entry *ae;
time_t t = 1234567890;
struct tm *tm;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
size_t used, buffsize = 1000000;
unsigned long crc;
int file_perm = 00644;
@@ -98,15 +94,10 @@ DEFINE_TEST(test_write_format_zip_file)
zip_compression = 0;
#endif
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = t;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- tm = NULL;
- else
- tm = &tmbuf;
#else
tm = localtime(&t);
#endif
diff --git a/libarchive/test/test_write_format_zip_file_zip64.c b/libarchive/test/test_write_format_zip_file_zip64.c
index c4161bc3a89b..6a00fe14c389 100644
--- a/libarchive/test/test_write_format_zip_file_zip64.c
+++ b/libarchive/test/test_write_format_zip_file_zip64.c
@@ -76,13 +76,9 @@ DEFINE_TEST(test_write_format_zip_file_zip64)
struct archive_entry *ae;
time_t t = 1234567890;
struct tm *tm;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
size_t used, buffsize = 1000000;
unsigned long crc;
int file_perm = 00644;
@@ -99,15 +95,10 @@ DEFINE_TEST(test_write_format_zip_file_zip64)
zip_compression = 0;
#endif
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = t;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- tm = NULL;
- else
- tm = &tmbuf;
#else
tm = localtime(&t);
#endif
diff --git a/libarchive/xxhash.c b/libarchive/xxhash.c
index f96e9d93493e..beacd2391221 100644
--- a/libarchive/xxhash.c
+++ b/libarchive/xxhash.c
@@ -149,6 +149,10 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
#if GCC_VERSION >= 409
__attribute__((__no_sanitize_undefined__))
+#else
+# if defined(__clang__)
+__attribute__((no_sanitize("undefined")))
+# endif
#endif
#if defined(_MSC_VER)
static __inline U32 A32(const void * x)
diff --git a/tar/bsdtar.1 b/tar/bsdtar.1
index b57835adbef2..1b78fbc04943 100644
--- a/tar/bsdtar.1
+++ b/tar/bsdtar.1
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 31, 2020
+.Dd December 1, 2022
.Dt TAR 1
.Os
.Sh NAME
@@ -643,6 +643,19 @@ Specify the number of worker threads to use.
Setting threads to a special value 0 makes
.Xr zstd 1
use as many threads as there are CPU cores on the system.
+.It Cm zstd:frame-per-file
+Start a new compression frame at the beginning of each file in the
+archive.
+.It Cm zstd:min-frame-size Ns = Ns Ar N
+In combination with
+.Cm zstd:frame-per-file ,
+do not start a new compression frame unless the current frame is at least
+.Ar N
+bytes.
+.It Cm zstd:max-frame-size Ns = Ns Ar N
+Start a new compression frame as soon as the current frame exceeds
+.Ar N
+bytes.
.It Cm lzop:compression-level
A decimal integer from 1 to 9 specifying the lzop compression level.
.It Cm xz:compression-level
diff --git a/tar/test/test_option_lzma.c b/tar/test/test_option_lzma.c
index a618ff8a3403..ab6f13f91744 100644
--- a/tar/test/test_option_lzma.c
+++ b/tar/test/test_option_lzma.c
@@ -44,6 +44,7 @@ DEFINE_TEST(test_option_lzma)
if (strstr(p, "Unsupported compression") != NULL) {
skipping("This version of bsdtar was compiled "
"without lzma support");
+ free(p);
return;
}
failure("--lzma option is broken");
diff --git a/tar/util.c b/tar/util.c
index 5a4ab0b3a0fa..403d7ff35c50 100644
--- a/tar/util.c
+++ b/tar/util.c
@@ -668,13 +668,9 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
time_t tim;
static time_t now;
struct tm *ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
/*
* We avoid collecting the entire list in memory at once by
@@ -746,15 +742,10 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y";
else
fmt = bsdtar->day_first ? DAY_FMT " %b %H:%M" : "%b " DAY_FMT " %H:%M";
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ ltime = localtime_s(&tmbuf, &tim) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&tim, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = tim;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- ltime = NULL;
- else
- ltime = &tmbuf;
#else
ltime = localtime(&tim);
#endif
diff --git a/test_utils/test_main.c b/test_utils/test_main.c
index 74250ad748c2..3250423a14c2 100644
--- a/test_utils/test_main.c
+++ b/test_utils/test_main.c
@@ -2345,7 +2345,7 @@ static void assert_version_id(char **qq, size_t *ss)
q += 3;
s -= 3;
}
-
+
/* Skip a single trailing a,b,c, or d. */
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
++q;
@@ -2391,7 +2391,7 @@ void assertVersion(const char *prog, const char *base)
/* Version message should start with name of program, then space. */
assert(s > prog_len + 1);
-
+
failure("Version must start with '%s': ``%s''", base, p);
if (!assertEqualMem(q, base, prog_len)) {
free(p);
@@ -2729,7 +2729,7 @@ canNodump(void)
/* Get extended attribute value from a path */
void *
getXattr(const char *path, const char *name, size_t *sizep)
-{
+{
void *value = NULL;
#if ARCHIVE_XATTR_SUPPORT
ssize_t size;
@@ -3863,18 +3863,14 @@ main(int argc, char **argv)
int test_set[sizeof(tests) / sizeof(tests[0])];
int i = 0, j = 0, tests_run = 0, tests_failed = 0, option;
int testprogdir_len;
-#ifdef PROGRAM
+#ifdef PROGRAM
int tmp2_len;
#endif
time_t now;
struct tm *tmptr;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
-#if defined(HAVE__LOCALTIME64_S)
- errno_t terr;
- __time64_t tmptime;
-#endif
char *refdir_alloc = NULL;
const char *progname;
char **saved_argv;
@@ -4109,15 +4105,10 @@ main(int argc, char **argv)
*/
now = time(NULL);
for (i = 0; ; i++) {
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+ tmptr = localtime_s(&tmbuf, &now) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
tmptr = localtime_r(&now, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
- tmptime = now;
- terr = _localtime64_s(&tmbuf, &tmptime);
- if (terr)
- tmptr = NULL;
- else
- tmptr = &tmbuf;
#else
tmptr = localtime(&now);
#endif