From 309e35276a045cc5ae7f9414c80765863d4a09c4 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Tue, 30 May 2023 15:07:22 +0200 Subject: 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 --- CMakeLists.txt | 13 +- NEWS | 2 +- build/cmake/FindLibGCC.cmake | 22 -- build/cmake/config.h.in | 18 +- build/version | 2 +- configure.ac | 37 +++- contrib/android/config/android.h | 2 +- contrib/android/config/linux_host.h | 2 +- contrib/android/config/windows_host.h | 14 +- cpio/cpio.c | 19 +- cpio/test/test_option_J_upper.c | 1 + cpio/test/test_option_c.c | 6 +- cpio/test/test_option_t.c | 17 +- libarchive/archive.h | 4 +- libarchive/archive_entry.h | 2 +- libarchive/archive_getdate.c | 119 +++-------- libarchive/archive_hmac.c | 15 +- libarchive/archive_hmac_private.h | 2 + libarchive/archive_read_data_into_fd.c | 7 +- libarchive/archive_read_open_file.c | 4 +- libarchive/archive_read_support_filter_zstd.c | 14 +- libarchive/archive_read_support_format_cpio.c | 2 +- libarchive/archive_read_support_format_iso9660.c | 12 +- libarchive/archive_read_support_format_rar.c | 17 +- libarchive/archive_read_support_format_warc.c | 6 +- libarchive/archive_read_support_format_xar.c | 8 +- libarchive/archive_write.c | 31 +++ libarchive/archive_write_add_filter_zstd.c | 232 +++++++++++++-------- libarchive/archive_write_private.h | 1 + libarchive/archive_write_set_format_7zip.c | 2 +- libarchive/archive_write_set_format_iso9660.c | 32 ++- libarchive/archive_write_set_format_pax.c | 18 +- libarchive/archive_write_set_format_warc.c | 25 +-- libarchive/archive_write_set_format_xar.c | 14 +- libarchive/archive_write_set_format_zip.c | 19 +- libarchive/config_freebsd.h | 2 +- libarchive/test/test_read_format_rar5.c | 2 + libarchive/test/test_read_format_zip.c | 5 + libarchive/test/test_short_writes.c | 2 + libarchive/test/test_write_filter_zstd.c | 27 +++ .../test/test_write_format_zip_compression_store.c | 17 +- libarchive/test/test_write_format_zip_file.c | 17 +- libarchive/test/test_write_format_zip_file_zip64.c | 17 +- libarchive/xxhash.c | 4 + tar/bsdtar.1 | 15 +- tar/test/test_option_lzma.c | 1 + tar/util.c | 17 +- test_utils/test_main.c | 25 +-- 48 files changed, 441 insertions(+), 451 deletions(-) delete mode 100644 build/cmake/FindLibGCC.cmake 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 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 ]) +AC_CHECK_DECL([gmtime_s], + [AC_DEFINE(HAVE_GMTIME_S, 1, [gmtime_s function])], + [], + [#include ]) +AC_CHECK_TYPE([localtime_s], + [AC_DEFINE(HAVE_LOCALTIME_S, 1, [localtime_s function])], + [], + [#include ]) +AC_CHECK_DECL([_mkgmtime], + [AC_DEFINE(HAVE__MKGMTIME, 1, [_mkgmtime function])], + [], + [#include ]) + # 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 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 and . */ -#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 #include /* 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 #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include + 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 #endif +#ifdef HAVE_STDINT_H +#include +#endif #ifdef HAVE_STDLIB_H #include #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; @@ -407,6 +448,13 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff, return __archive_write_program_write(f, data->pdata, buff, length); } +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) { 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,12 +74,8 @@ 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; @@ -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,12 +76,8 @@ 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; @@ -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,17 +3863,13 @@ 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; @@ -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 -- cgit v1.2.3