Compare commits

...

24 Commits

Author SHA1 Message Date
Martin Matuska
9525f90ca4 Release 3.8.1 2025-06-01 21:26:44 +02:00
Martin Matuška
7a0b0caea1 Merge pull request #2627 from heirecka/do-not-hard-code-pkg-config
Use PKG_CONFIG instead of hard-coded pkg-config

(cherry picked from commit 70978468e9078601d9f8e0c2be55762c0b3ff3e2)
2025-05-31 21:40:54 +02:00
Martin Matuška
bc2fcdafce Merge pull request #2643 from stoeckmann/tar_pax_sparse
tar: Handle extra bytes after sparse entries
(cherry picked from commit c7b7bd7c0e3aa29caf874efe6686cd0f78e1842d)
2025-05-31 21:32:50 +02:00
Tim Kientzle
14de0d62d3 Merge pull request #2652 from stoeckmann/wstring_ensure
Check archive_wstring_ensure return value

(cherry picked from commit 8d074302ac6b50e54d7e0430ced19c1b878cce32)
2025-05-31 21:25:32 +02:00
Tim Kientzle
8e1092726c Merge pull request #2651 from stoeckmann/string_ensure_check
Always check archive_string_ensure return value

(cherry picked from commit 101230094c5793b3f82a2f3531b0ebd4b406e85f)
2025-05-31 21:25:32 +02:00
Tim Kientzle
94208dc524 Merge pull request #2648 from stoeckmann/test_en_us
test_utils: Enforce C locale for all tests

(cherry picked from commit 8540cb7cfbfb47340ecae856d7f2a1292096e936)
2025-05-31 21:25:32 +02:00
Tim Kientzle
6050823986 Merge pull request #2650 from stoeckmann/string_sort
archive_utility_string_sort: Use qsort directly

(cherry picked from commit e2eda9e68b7174eb37b80c0dd4761e71a989db5c)
2025-05-31 21:25:32 +02:00
Tim Kientzle
95a8adc7e5 Merge pull request #2634 from stoeckmann/tar_neg_time
tar: Support negative time values with pax
(cherry picked from commit 9b07a143ee0e55d04ef602e926f2d343ee5a9a8f)
2025-05-31 21:25:32 +02:00
Tim Kientzle
3e718bf2d4 Merge pull request #2649 from stoeckmann/compress_recursion
compress: Prevent call stack overflow
(cherry picked from commit cd5c44c5d0470a5bb497541ae7bcb617c4480855)
2025-05-31 21:25:32 +02:00
Tim Kientzle
0dc4f71fcb Merge pull request #2642 from stoeckmann/seek_regress
Fix FILE_skip regression

(cherry picked from commit 59b09796c3402489c3f47625b6401a28d24ad8a4)
2025-05-31 21:25:32 +02:00
Tim Kientzle
b92f70d190 Merge pull request #2644 from stoeckmann/tar_neg_size
tar: Always treat negative sizes as error
(cherry picked from commit d261f46ae57f115a48c0bef10643753cb305a9a5)
2025-05-31 21:25:32 +02:00
Tim Kientzle
ab1d9a37eb Merge pull request #2645 from stoeckmann/tar_formatter
tar: Fix archive_set_error formatters
(cherry picked from commit dcdd7338d68c30d8171b483c7fa25729ae1a1f56)
2025-05-31 21:25:32 +02:00
Tim Kientzle
119aec5306 Merge pull request #2646 from stoeckmann/sparse32
tar: Handle many sparse comments on 32 bit systems
(cherry picked from commit 702f31a01cf2a867b2df8c4be6a6d2e8ae403078)
2025-05-31 21:25:32 +02:00
Tim Kientzle
ebbd18c365 Merge pull request #2640 from robUx4/xml-uuid
[cmake] add uuid library when using xmllite

(cherry picked from commit 6389d172ed25de1b84606716553241c171a30111)
2025-05-31 21:25:32 +02:00
Tim Kientzle
6445be4ea6 Merge pull request #2637 from stoeckmann/pax_nl
tar: Keep block alignment after pax error
(cherry picked from commit 341dd5d1d45ce320ff05928e50efafd8ed42ed81)
2025-05-31 21:25:32 +02:00
Tim Kientzle
30e662a0a5 Merge pull request #2639 from stoeckmann/sprintf_ll
Add ll length modifier to archive_string_vsprintf

(cherry picked from commit 18d456377ea7c8fe7946fa7b45b87d5da294640b)
2025-05-31 21:25:32 +02:00
Tim Kientzle
66b380ed5a Merge pull request #2636 from zhaofengli/reset-header-state-after-mac-metadata
tar: Reset accumulated header state after reading macOS metadata blob
(cherry picked from commit b6e1f06457e61c182dd2f34b9fb37701cfda041b)
2025-05-31 21:25:32 +02:00
Tim Kientzle
ad4d2eefa8 Merge pull request #2630 from stoeckmann/wincrypt_casts
Fix archive_wincrypt_version

(cherry picked from commit 42c2f8464962990bf7df0df2f3cbd0ce80121190)
2025-05-31 21:25:32 +02:00
Tim Kientzle
8a3cdd71cb Merge pull request #2633 from stoeckmann/match_cleanup
archive_match: Simplify and clean up code

(cherry picked from commit 6dbea2df3bc8288d52c65cb3d543a1e883162a20)
2025-05-31 21:25:32 +02:00
Tim Kientzle
22ef0ee13e Merge pull request #2632 from stoeckmann/cygwin_definition
Prefer __CYGWIN__ over CYGWIN definition

(cherry picked from commit cdc185e9177edcdc03bb5c1983d59874d434fb12)
2025-05-31 21:25:32 +02:00
Tim Kientzle
4937278516 Merge pull request #2631 from stoeckmann/configure_windows
configure.ac: Improve Windows version detection

(cherry picked from commit 0ed4435209b9b694cc190d937e4709a0609580e6)
2025-05-31 21:25:32 +02:00
Tim Kientzle
97a48a0d79 Merge pull request #2509 from tesap/install-lib-dir
Make installation lib dir depend on CMAKE_INSTALL_LIBDIR variable

(cherry picked from commit 992734d6cc557e3387f9cfd44a0cca3934d22262)
2025-05-31 21:25:32 +02:00
Tim Kientzle
53c7eb8adf Merge pull request #2629 from mmatuska/fix/versiontest
tests: accept underscore in arbitrary third-party version strings
(cherry picked from commit 627ba5bbbf80fe25dbf5015ef304a905a2820f17)
2025-05-31 21:25:32 +02:00
Martin Matuska
70ff28fcf0 Release 3.8.0 2025-05-20 10:35:52 +02:00
38 changed files with 944 additions and 294 deletions

View File

@ -16,7 +16,7 @@ endif()
# MinSizeRel : Release Min Size build
# None : No build type
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
SET(CMAKE_BUILD_TYPE "Release" 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".
@ -1257,7 +1257,7 @@ ELSE(LIBXML2_FOUND)
# Check linkage as well; versions of mingw-w64 before v11.0.0
# do not contain an import library for xmllite.
cmake_push_check_state()
SET(CMAKE_REQUIRED_LIBRARIES "xmllite")
SET(CMAKE_REQUIRED_LIBRARIES "xmllite" "uuid")
check_c_source_compiles("
#include <initguid.h>
#include <xmllite.h>
@ -1268,7 +1268,7 @@ ELSE(LIBXML2_FOUND)
cmake_pop_check_state()
IF(HAVE_XMLLITE_H)
SET(XMLLITE_FOUND TRUE)
LIST(APPEND ADDITIONAL_LIBS "xmllite")
LIST(APPEND ADDITIONAL_LIBS "xmllite" "uuid")
ENDIF()
ENDIF()
ENDIF(EXPAT_FOUND)

View File

@ -531,8 +531,10 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_tar_empty_with_gnulabel.c \
libarchive/test/test_read_format_tar_filename.c \
libarchive/test/test_read_format_tar_invalid_pax_size.c \
libarchive/test/test_read_format_tar_mac_metadata.c \
libarchive/test/test_read_format_tar_pax_g_large.c \
libarchive/test/test_read_format_tar_pax_large_attr.c \
libarchive/test/test_read_format_tar_pax_negative_time.c \
libarchive/test/test_read_format_tbz.c \
libarchive/test/test_read_format_tgz.c \
libarchive/test/test_read_format_tlz.c \
@ -565,6 +567,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_zip_zip64.c \
libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c \
libarchive/test/test_read_large.c \
libarchive/test/test_read_pax_empty_val_no_nl.c \
libarchive/test/test_read_pax_xattr_rht_security_selinux.c \
libarchive/test/test_read_pax_xattr_schily.c \
libarchive/test/test_read_pax_truncated.c \
@ -975,8 +978,10 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_tar_empty_pax.tar.Z.uu \
libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu \
libarchive/test/test_read_format_tar_mac_metadata_1.tar.uu \
libarchive/test/test_read_format_tar_pax_g_large.tar.uu \
libarchive/test/test_read_format_tar_pax_large_attr.tar.Z.uu \
libarchive/test/test_read_format_tar_pax_negative_time.tar.uu \
libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
@ -1041,6 +1046,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_large_splitted_rar_ac.uu \
libarchive/test/test_read_large_splitted_rar_ad.uu \
libarchive/test/test_read_large_splitted_rar_ae.uu \
libarchive/test/test_read_pax_empty_val_no_nl.tar.uu \
libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu \
libarchive/test/test_read_pax_xattr_schily.tar.uu \
libarchive/test/test_read_splitted_rar_aa.uu \

12
NEWS
View File

@ -1,3 +1,15 @@
Jun 01, 2026: libarchive 3.8.1 released
May 20, 2025: libarchive 3.8.0 released
Mar 30, 2025: libarchive 3.7.9 released
Mar 20, 2025: libarchive 3.7.8 released
Oct 13, 2024: libarchive 3.7.7 released
Sep 23, 2024: libarchive 3.7.6 released
Sep 13, 2024: libarchive 3.7.5 released
Apr 26, 2024: libarchive 3.7.4 released

View File

@ -29,5 +29,5 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in
# And install it, of course ;).
IF(ENABLE_INSTALL)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc
DESTINATION "lib/pkgconfig")
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
ENDIF()

View File

@ -1 +1 @@
3008000
3008001

View File

@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release.
m4_define([LIBARCHIVE_VERSION_S],[3.8.0dev])
m4_define([LIBARCHIVE_VERSION_N],[3008000])
m4_define([LIBARCHIVE_VERSION_S],[3.8.1])
m4_define([LIBARCHIVE_VERSION_N],[3008001])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
@ -258,7 +258,8 @@ AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ])
case $host in
*mingw* | *cygwin* | *msys* )
AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
[[#ifdef _WIN32_WINNT
[[#include <windows.h>
#ifdef _WIN32_WINNT
# error _WIN32_WINNT already defined
#endif
]],[[;]])
@ -267,7 +268,8 @@ case $host in
AC_DEFINE([NTDDI_VERSION], 0x05020000, [Define to '0x05020000' for Windows Server 2003 APIs.])
])
AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
[[#ifdef WINVER
[[#include <windows.h>
#ifdef WINVER
# error WINVER already defined
#endif
]],[[;]])
@ -436,13 +438,15 @@ if test "x$with_bz2lib" != "xno"; then
esac
fi
PKG_PROG_PKG_CONFIG
AC_ARG_WITH([libb2],
AS_HELP_STRING([--without-libb2], [Don't build support for BLAKE2 through libb2]))
if test "x$with_libb2" != "xno"; then
AC_CHECK_HEADERS([blake2.h])
AC_CHECK_LIB(b2,blake2sp_init)
BLAKE2_PC_VER=`pkg-config --modversion libb2`
BLAKE2_PC_VER=`$PKG_CONFIG --modversion libb2`
if test "x$BLAKE2_PC_VER" != "x"; then
AC_DEFINE_UNQUOTED([LIBB2_PKGCONFIG_VERSION], ["$BLAKE2_PC_VER"], [Libb2 version coming from pkg-config.])
fi
@ -925,7 +929,7 @@ if test "x$enable_xattr" != "xno"; then
])
AC_CHECK_DECLS([XATTR_NOFOLLOW], [], [], [#include <sys/xattr.h>
])
ATTR_PC_VER=`pkg-config --modversion libattr`
ATTR_PC_VER=`$PKG_CONFIG --modversion libattr`
if test "x$ATTR_PC_VER" != "x"; then
AC_DEFINE_UNQUOTED([LIBATTR_PKGCONFIG_VERSION], ["$ATTR_PC_VER"], [Libattr version coming from pkg-config.])
fi
@ -1024,7 +1028,7 @@ AC_ARG_ENABLE([acl],
if test "x$enable_acl" != "xno"; then
# Libacl
AC_CHECK_LIB([acl], [acl_get_file])
ACL_PC_VER=`pkg-config --modversion libacl`
ACL_PC_VER=`$PKG_CONFIG --modversion libacl`
if test "x$ACL_PC_VER" != "x"; then
AC_DEFINE_UNQUOTED([LIBACL_PKGCONFIG_VERSION], ["$ACL_PC_VER"], [Libacl version coming from pkg-config.])
fi
@ -1038,7 +1042,7 @@ if test "x$enable_acl" != "xno"; then
])
AC_CHECK_LIB([richacl], [richacl_get_file])
RICHACL_PC_VER=`pkg-config --modversion librichacl`
RICHACL_PC_VER=`$PKG_CONFIG --modversion librichacl`
if test "x$RICHACL_PC_VER" != "x"; then
AC_DEFINE_UNQUOTED([LIBRICHACL_PKGCONFIG_VERSION], ["$RICHACL_PC_VER"], [Librichacl version coming from pkg-config.])
fi

View File

@ -219,7 +219,7 @@ DEFINE_TEST(test_format_newc)
assert(is_hex(e, 110));
assertEqualMem(e + 0, "070701", 6); /* Magic */
assert(is_hex(e + 6, 8)); /* ino */
#if defined(_WIN32) && !defined(CYGWIN)
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Mode: Group members bits and others bits do not work. */
assertEqualInt(0xa180, from_hex(e + 14, 8) & 0xffc0);
#else

View File

@ -52,7 +52,7 @@ test_create(void)
* #ifdef this section out. Most of the test below is
* still valid. */
memset(&times, 0, sizeof(times));
#if defined(_WIN32) && !defined(CYGWIN)
#if defined(_WIN32) && !defined(__CYGWIN__)
times.actime = 86400;
times.modtime = 86400;
#else

View File

@ -248,7 +248,7 @@ IF(BUILD_SHARED_LIBS)
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive PROPERTIES
SET_TARGET_PROPERTIES(archive PROPERTIES
VERSION ${SOVERSION_FULL}
SOVERSION ${SOVERSION}
MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
@ -266,18 +266,22 @@ IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(CMAKE_INSTALL_LIBDIR "lib")
endif()
IF(ENABLE_INSTALL)
# How to install the libraries
IF(BUILD_SHARED_LIBS)
INSTALL(TARGETS archive
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
ENDIF(BUILD_SHARED_LIBS)
INSTALL(TARGETS archive_static
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
INSTALL_MAN(${libarchive_MANS})
INSTALL(FILES ${include_HEADERS} DESTINATION include)
ENDIF()

View File

@ -34,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3008000
#define ARCHIVE_VERSION_NUMBER 3008001
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.8.0dev"
#define ARCHIVE_VERSION_ONLY_STRING "3.8.1"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@ -1250,8 +1250,10 @@ __LA_DECL int archive_match_include_gname_w(struct archive *,
const wchar_t *);
/* Utility functions */
#if ARCHIVE_VERSION_NUMBER < 4000000
/* Convenience function to sort a NULL terminated list of strings */
__LA_DECL int archive_utility_string_sort(char **);
#endif
#ifdef __cplusplus
}

View File

@ -144,6 +144,10 @@ typedef struct {
#else
#if defined(_WIN32) && !defined(__CYGWIN__) && !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
#define ARCHIVE_CRYPTOR_USE_WINCRYPT 1
#endif
#define AES_BLOCK_SIZE 16
#define AES_MAX_KEY_SIZE 32
typedef int archive_crypto_ctx;

View File

@ -28,7 +28,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3008000
#define ARCHIVE_VERSION_NUMBER 3008001
/*
* Note: archive_entry.h is for use outside of libarchive; the

View File

@ -35,6 +35,9 @@
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include "archive.h"
#include "archive_private.h"
@ -53,8 +56,7 @@ struct match {
struct match_list {
struct match *first;
struct match **last;
int count;
int unmatched_count;
size_t unmatched_count;
struct match *unmatched_next;
int unmatched_eof;
};
@ -73,7 +75,6 @@ struct match_file {
struct entry_list {
struct match_file *first;
struct match_file **last;
int count;
};
struct id_array {
@ -144,12 +145,15 @@ static int add_pattern_mbs(struct archive_match *, struct match_list *,
const char *);
static int add_pattern_wcs(struct archive_match *, struct match_list *,
const wchar_t *);
#if !defined(_WIN32) || defined(__CYGWIN__)
static int cmp_key_mbs(const struct archive_rb_node *, const void *);
static int cmp_key_wcs(const struct archive_rb_node *, const void *);
static int cmp_node_mbs(const struct archive_rb_node *,
const struct archive_rb_node *);
#else
static int cmp_key_wcs(const struct archive_rb_node *, const void *);
static int cmp_node_wcs(const struct archive_rb_node *,
const struct archive_rb_node *);
#endif
static void entry_list_add(struct entry_list *, struct match_file *);
static void entry_list_free(struct entry_list *);
static void entry_list_init(struct entry_list *);
@ -189,12 +193,12 @@ static int validate_time_flag(struct archive *, int, const char *);
#define get_date archive_parse_date
static const struct archive_rb_tree_ops rb_ops_mbs = {
static const struct archive_rb_tree_ops rb_ops = {
#if !defined(_WIN32) || defined(__CYGWIN__)
cmp_node_mbs, cmp_key_mbs
};
static const struct archive_rb_tree_ops rb_ops_wcs = {
#else
cmp_node_wcs, cmp_key_wcs
#endif
};
/*
@ -228,7 +232,7 @@ archive_match_new(void)
a->recursive_include = 1;
match_list_init(&(a->inclusions));
match_list_init(&(a->exclusions));
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops);
entry_list_init(&(a->exclusion_entry_list));
match_list_init(&(a->inclusion_unames));
match_list_init(&(a->inclusion_gnames));
@ -507,7 +511,9 @@ archive_match_path_unmatched_inclusions(struct archive *_a)
ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions");
a = (struct archive_match *)_a;
return (a->inclusions.unmatched_count);
if (a->inclusions.unmatched_count > (size_t)INT_MAX)
return INT_MAX;
return (int)(a->inclusions.unmatched_count);
}
int
@ -650,7 +656,7 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
break;
}
} else {
if (*b == 0x0d || *b == 0x0a) {
if (*b == 0x0d || *b == 0x0a) {
found_separator = 1;
break;
}
@ -735,7 +741,7 @@ path_excluded(struct archive_match *a, int mbs, const void *pathname)
}
}
/* Exclusions take priority */
/* Exclusions take priority. */
for (match = a->exclusions.first; match != NULL;
match = match->next){
r = match_path_exclusion(a, match, mbs, pathname);
@ -834,7 +840,6 @@ match_list_init(struct match_list *list)
{
list->first = NULL;
list->last = &(list->first);
list->count = 0;
}
static void
@ -855,7 +860,6 @@ match_list_add(struct match_list *list, struct match *m)
{
*list->last = m;
list->last = &(m->next);
list->count++;
list->unmatched_count++;
}
@ -1275,6 +1279,7 @@ set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
/*
* Call back functions for archive_rb.
*/
#if !defined(_WIN32) || defined(__CYGWIN__)
static int
cmp_node_mbs(const struct archive_rb_node *n1,
const struct archive_rb_node *n2)
@ -1291,7 +1296,7 @@ cmp_node_mbs(const struct archive_rb_node *n1,
return (-1);
return (strcmp(p1, p2));
}
static int
cmp_key_mbs(const struct archive_rb_node *n, const void *key)
{
@ -1303,7 +1308,7 @@ cmp_key_mbs(const struct archive_rb_node *n, const void *key)
return (-1);
return (strcmp(p, (const char *)key));
}
#else
static int
cmp_node_wcs(const struct archive_rb_node *n1,
const struct archive_rb_node *n2)
@ -1320,7 +1325,7 @@ cmp_node_wcs(const struct archive_rb_node *n1,
return (-1);
return (wcscmp(p1, p2));
}
static int
cmp_key_wcs(const struct archive_rb_node *n, const void *key)
{
@ -1332,13 +1337,13 @@ cmp_key_wcs(const struct archive_rb_node *n, const void *key)
return (-1);
return (wcscmp(p, (const wchar_t *)key));
}
#endif
static void
entry_list_init(struct entry_list *list)
{
list->first = NULL;
list->last = &(list->first);
list->count = 0;
}
static void
@ -1359,7 +1364,6 @@ entry_list_add(struct entry_list *list, struct match_file *file)
{
*list->last = file;
list->last = &(file->next);
list->count++;
}
static int
@ -1382,9 +1386,7 @@ add_entry(struct archive_match *a, int flag,
return (ARCHIVE_FAILED);
}
archive_mstring_copy_wcs(&(f->pathname), pathname);
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
#else
(void)rb_ops_wcs;
pathname = archive_entry_pathname(entry);
if (pathname == NULL) {
free(f);
@ -1392,7 +1394,6 @@ add_entry(struct archive_match *a, int flag,
return (ARCHIVE_FAILED);
}
archive_mstring_copy_mbs(&(f->pathname), pathname);
a->exclusion_tree.rbt_ops = &rb_ops_mbs;
#endif
f->flag = flag;
f->mtime_sec = archive_entry_mtime(entry);
@ -1517,16 +1518,13 @@ time_excluded(struct archive_match *a, struct archive_entry *entry)
}
/* If there is no exclusion list, include the file. */
if (a->exclusion_entry_list.count == 0)
if (a->exclusion_entry_list.first == NULL)
return (0);
#if defined(_WIN32) && !defined(__CYGWIN__)
pathname = archive_entry_pathname_w(entry);
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
#else
(void)rb_ops_wcs;
pathname = archive_entry_pathname(entry);
a->exclusion_tree.rbt_ops = &rb_ops_mbs;
#endif
if (pathname == NULL)
return (0);
@ -1682,7 +1680,7 @@ archive_match_owner_excluded(struct archive *_a,
static int
add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
{
unsigned i;
size_t i;
if (ids->count + 1 >= ids->size) {
void *p;
@ -1719,10 +1717,10 @@ add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
static int
match_owner_id(struct id_array *ids, int64_t id)
{
unsigned b, m, t;
size_t b, m, t;
t = 0;
b = (unsigned)ids->count;
b = ids->count;
while (t < b) {
m = (t + b)>>1;
if (ids->ids[m] == id)
@ -1817,7 +1815,7 @@ owner_excluded(struct archive_match *a, struct archive_entry *entry)
return (1);
}
if (a->inclusion_unames.count) {
if (a->inclusion_unames.first != NULL) {
#if defined(_WIN32) && !defined(__CYGWIN__)
r = match_owner_name_wcs(a, &(a->inclusion_unames),
archive_entry_uname_w(entry));
@ -1831,7 +1829,7 @@ owner_excluded(struct archive_match *a, struct archive_entry *entry)
return (r);
}
if (a->inclusion_gnames.count) {
if (a->inclusion_gnames.first != NULL) {
#if defined(_WIN32) && !defined(__CYGWIN__)
r = match_owner_name_wcs(a, &(a->inclusion_gnames),
archive_entry_gname_w(entry));

View File

@ -1652,7 +1652,7 @@ tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
/*
* Append a name to the current dir path.
*/
static void
static int
tree_append(struct tree *t, const wchar_t *name, size_t name_length)
{
size_t size_needed;
@ -1665,7 +1665,8 @@ tree_append(struct tree *t, const wchar_t *name, size_t name_length)
/* Resize pathname buffer as needed. */
size_needed = name_length + t->dirname_length + 2;
archive_wstring_ensure(&t->path, size_needed);
if (archive_wstring_ensure(&t->path, size_needed) == NULL)
return (TREE_ERROR_FATAL);
/* Add a separating '/' if it's needed. */
if (t->dirname_length > 0 &&
t->path.s[archive_strlen(&t->path)-1] != L'/')
@ -1677,13 +1678,15 @@ tree_append(struct tree *t, const wchar_t *name, size_t name_length)
t->full_path.s[t->full_path_dir_length] = L'\0';
t->full_path.length = t->full_path_dir_length;
size_needed = name_length + t->full_path_dir_length + 2;
archive_wstring_ensure(&t->full_path, size_needed);
if (archive_wstring_ensure(&t->full_path, size_needed) == NULL)
return (TREE_ERROR_FATAL);
/* Add a separating '\' if it's needed. */
if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
archive_wstrappend_wchar(&t->full_path, L'\\');
archive_wstrncat(&t->full_path, name, name_length);
t->restore_time.full_path = t->full_path.s;
}
return (0);
}
/*
@ -1697,7 +1700,10 @@ tree_open(const wchar_t *path, int symlink_mode, int restore_time)
t = calloc(1, sizeof(*t));
archive_string_init(&(t->full_path));
archive_string_init(&t->path);
archive_wstring_ensure(&t->path, 15);
if (archive_wstring_ensure(&t->path, 15) == NULL) {
free(t);
return (NULL);
}
t->initial_symlink_mode = symlink_mode;
return (tree_reopen(t, path, restore_time));
}
@ -1756,7 +1762,8 @@ tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
p = wcsrchr(base, L'/');
if (p != NULL) {
*p = L'\0';
tree_append(t, base, p - base);
if (tree_append(t, base, p - base))
goto failed;
t->dirname_length = archive_strlen(&t->path);
base = p + 1;
}
@ -1892,8 +1899,10 @@ tree_next(struct tree *t)
}
/* Top stack item needs a regular visit. */
t->current = t->stack;
tree_append(t, t->stack->name.s,
r = tree_append(t, t->stack->name.s,
archive_strlen(&(t->stack->name)));
if (r != 0)
return (r);
//t->dirname_length = t->path_length;
//tree_pop(t);
t->stack->flags &= ~needsFirstVisit;
@ -1901,8 +1910,10 @@ tree_next(struct tree *t)
} else if (t->stack->flags & needsDescent) {
/* Top stack item is dir to descend into. */
t->current = t->stack;
tree_append(t, t->stack->name.s,
r = tree_append(t, t->stack->name.s,
archive_strlen(&(t->stack->name)));
if (r != 0)
return (r);
t->stack->flags &= ~needsDescent;
r = tree_descent(t);
if (r != 0) {
@ -1945,9 +1956,10 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
struct archive_wstring pt;
archive_string_init(&pt);
archive_wstring_ensure(&pt,
if (archive_wstring_ensure(&pt,
archive_strlen(&(t->full_path))
+ 2 + wcslen(pattern));
+ 2 + wcslen(pattern)) == NULL)
return (TREE_ERROR_FATAL);
archive_wstring_copy(&pt, &(t->full_path));
archive_wstrappend_wchar(&pt, L'\\');
archive_wstrcat(&pt, pattern);
@ -1979,7 +1991,9 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
continue;
if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
continue;
tree_append(t, name, namelen);
r = tree_append(t, name, namelen);
if (r != 0)
return (r);
return (t->visit_type = TREE_REGULAR);
}
}

View File

@ -132,7 +132,7 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
#else
long skip = (long)request;
#endif
int64_t old_offset, new_offset;
int64_t old_offset, new_offset = -1;
int skip_bits = sizeof(skip) * 8 - 1;
(void)a; /* UNUSED */
@ -170,11 +170,14 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
#ifdef __ANDROID__
new_offset = lseek(fileno(mine->f), skip, SEEK_CUR);
#elif HAVE__FSEEKI64
new_offset = _fseeki64(mine->f, skip, SEEK_CUR);
if (_fseeki64(mine->f, skip, SEEK_CUR) == 0)
new_offset = _ftelli64(mine->f);
#elif HAVE_FSEEKO
new_offset = fseeko(mine->f, skip, SEEK_CUR);
if (fseeko(mine->f, skip, SEEK_CUR) == 0)
new_offset = ftello(mine->f);
#else
new_offset = fseek(mine->f, skip, SEEK_CUR);
if (fseek(mine->f, skip, SEEK_CUR) == 0)
new_offset = ftell(mine->f);
#endif
if (new_offset >= 0)
return (new_offset - old_offset);

View File

@ -328,6 +328,7 @@ next_code(struct archive_read_filter *self)
static int debug_buff[1024];
static unsigned debug_index;
again:
code = newcode = getbits(self, state->bits);
if (code < 0)
return (code);
@ -360,7 +361,7 @@ next_code(struct archive_read_filter *self)
state->section_end_code = (1 << state->bits) - 1;
state->free_ent = 257;
state->oldcode = -1;
return (next_code(self));
goto again;
}
if (code > state->free_ent

View File

@ -363,7 +363,12 @@ archive_read_support_format_cab(struct archive *_a)
return (ARCHIVE_FATAL);
}
archive_string_init(&cab->ws);
archive_wstring_ensure(&cab->ws, 256);
if (archive_wstring_ensure(&cab->ws, 256) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory");
free(cab);
return (ARCHIVE_FATAL);
}
r = __archive_read_register_format(a,
cab,

View File

@ -174,7 +174,7 @@ static int gnu_sparse_old_parse(struct archive_read *, struct tar *,
const struct gnu_sparse *sparse, int length);
static int gnu_sparse_01_parse(struct archive_read *, struct tar *,
const char *, size_t);
static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *,
static int64_t gnu_sparse_10_read(struct archive_read *, struct tar *,
int64_t *);
static int header_Solaris_ACL(struct archive_read *, struct tar *,
struct archive_entry *, const void *, int64_t *);
@ -628,7 +628,10 @@ archive_read_format_tar_read_data(struct archive_read *a,
/* If we're at end of file, return EOF. */
if (tar->sparse_list == NULL ||
tar->entry_bytes_remaining == 0) {
if (__archive_read_consume(a, tar->entry_padding) < 0)
int64_t request = tar->entry_bytes_remaining +
tar->entry_padding;
if (__archive_read_consume(a, request) != request)
return (ARCHIVE_FATAL);
tar->entry_padding = 0;
*buff = NULL;
@ -666,29 +669,15 @@ archive_read_format_tar_read_data(struct archive_read *a,
static int
archive_read_format_tar_skip(struct archive_read *a)
{
int64_t bytes_skipped;
int64_t request;
struct sparse_block *p;
struct tar* tar;
tar = (struct tar *)(a->format->data);
/* Do not consume the hole of a sparse file. */
request = 0;
for (p = tar->sparse_list; p != NULL; p = p->next) {
if (!p->hole) {
if (p->remaining >= INT64_MAX - request) {
return ARCHIVE_FATAL;
}
request += p->remaining;
}
}
if (request > tar->entry_bytes_remaining)
request = tar->entry_bytes_remaining;
request += tar->entry_padding + tar->entry_bytes_unconsumed;
request = tar->entry_bytes_remaining + tar->entry_padding +
tar->entry_bytes_unconsumed;
bytes_skipped = __archive_read_consume(a, request);
if (bytes_skipped < 0)
if (__archive_read_consume(a, request) != request)
return (ARCHIVE_FATAL);
tar->entry_bytes_remaining = 0;
@ -701,6 +690,22 @@ archive_read_format_tar_skip(struct archive_read *a)
return (ARCHIVE_OK);
}
/*
* This function resets the accumulated state while reading
* a header.
*/
static void
tar_reset_header_state(struct tar *tar)
{
tar->pax_hdrcharset_utf8 = 1;
tar->sparse_gnu_attributes_seen = 0;
archive_string_empty(&(tar->entry_gname));
archive_string_empty(&(tar->entry_pathname));
archive_string_empty(&(tar->entry_pathname_override));
archive_string_empty(&(tar->entry_uname));
archive_string_empty(&tar->entry_linkpath);
}
/*
* This function reads and interprets all of the headers associated
* with a single entry.
@ -726,13 +731,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
static const int32_t seen_x_header = 32; /* Also X */
static const int32_t seen_mac_metadata = 512;
tar->pax_hdrcharset_utf8 = 1;
tar->sparse_gnu_attributes_seen = 0;
archive_string_empty(&(tar->entry_gname));
archive_string_empty(&(tar->entry_pathname));
archive_string_empty(&(tar->entry_pathname_override));
archive_string_empty(&(tar->entry_uname));
archive_string_empty(&tar->entry_linkpath);
tar_reset_header_state(tar);
/* Ensure format is set. */
if (a->archive.archive_format_name == NULL) {
@ -936,6 +935,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
err = err_combine(err, err2);
/* Note: Other headers can appear again. */
seen_headers = seen_mac_metadata;
tar_reset_header_state(tar);
break;
}
@ -1118,8 +1118,8 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (unsupported type %"
PRIo64 ")", type);
"Malformed Solaris ACL attribute (unsupported type %llu)",
(unsigned long long)type);
archive_string_free(&acl_text);
return (ARCHIVE_WARN);
}
@ -1293,18 +1293,21 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
(void)tar; /* UNUSED */
header = (const struct archive_entry_header_ustar *)h;
size = tar_atol(header->size, sizeof(header->size));
if (size > entry_limit) {
if (size < 0 || size > entry_limit) {
archive_set_error(&a->archive, EINVAL,
"Special header has invalid size: %lld",
(long long)size);
return (ARCHIVE_FATAL);
}
if ((size > (int64_t)pathname_limit) || (size < 0)) {
if (size > (int64_t)pathname_limit) {
archive_string_empty(as);
int64_t to_consume = ((size + 511) & ~511);
if (to_consume != __archive_read_consume(a, to_consume)) {
return (ARCHIVE_FATAL);
}
archive_set_error(&a->archive, EINVAL,
"Special header too large: %d > 1MiB",
(int)size);
"Special header too large: %lld > 1MiB",
(long long)size);
return (ARCHIVE_WARN);
}
r = read_bytes_to_string(a, as, size, unconsumed);
@ -1743,7 +1746,10 @@ header_pax_global(struct archive_read *a, struct tar *tar,
header = (const struct archive_entry_header_ustar *)h;
size = tar_atol(header->size, sizeof(header->size));
if (size > entry_limit) {
if (size < 0 || size > entry_limit) {
archive_set_error(&a->archive, EINVAL,
"Special header has invalid size: %lld",
(long long)size);
return (ARCHIVE_FATAL);
}
to_consume = ((size + 511) & ~511);
@ -1890,8 +1896,8 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
}
archive_set_error(&a->archive, EINVAL,
"Ignoring oversized pax extensions: %d > %d",
(int)ext_size, (int)ext_size_limit);
"Ignoring oversized pax extensions: %lld > %lld",
(long long)ext_size, (long long)ext_size_limit);
return (ARCHIVE_WARN);
}
tar_flush_unconsumed(a, unconsumed);
@ -1990,6 +1996,13 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
*unconsumed += p - attr_start;
tar_flush_unconsumed(a, unconsumed);
if (value_length == 0) {
archive_set_error(&a->archive, EINVAL,
"Malformed pax attributes");
*unconsumed += ext_size + ext_padding;
return (ARCHIVE_WARN);
}
/* pax_attribute will consume value_length - 1 */
r = pax_attribute(a, tar, entry, attr_name.s, archive_strlen(&attr_name), value_length - 1, unconsumed);
ext_size -= value_length - 1;
@ -2199,8 +2212,9 @@ pax_attribute_SCHILY_acl(struct archive_read *a, struct tar *tar,
if (value_length > acl_limit) {
__archive_read_consume(a, value_length);
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Unreasonably large ACL: %d > %d",
(int)value_length, (int)acl_limit);
"Unreasonably large ACL: %llu > %llu",
(unsigned long long)value_length,
(unsigned long long)acl_limit);
return (ARCHIVE_WARN);
}
@ -2247,12 +2261,16 @@ pax_attribute_read_time(struct archive_read *a, size_t value_length, int64_t *ps
r = read_bytes_to_string(a, &as, value_length, unconsumed);
if (r < ARCHIVE_OK) {
archive_string_free(&as);
*ps = 0;
*pn = 0;
return (r);
}
pax_time(as.s, archive_strlen(&as), ps, pn);
archive_string_free(&as);
if (*ps < 0 || *ps == INT64_MAX) {
if (*ps == INT64_MIN) {
*ps = 0;
*pn = 0;
return (ARCHIVE_WARN);
}
return (ARCHIVE_OK);
@ -2386,8 +2404,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
tar->sparse_gnu_minor = 1;
if (value_length > sparse_map_limit) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Unreasonably large sparse map: %d > %d",
(int)value_length, (int)sparse_map_limit);
"Unreasonably large sparse map: %llu > %llu",
(unsigned long long)value_length,
(unsigned long long)sparse_map_limit);
err = ARCHIVE_FAILED;
} else {
p = __archive_read_ahead(a, value_length, &bytes_read);
@ -2494,8 +2513,8 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
} else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"symlink type is very long"
"(longest recognized value is 4 bytes, this is %d)",
(int)value_length);
"(longest recognized value is 4 bytes, this is %llu)",
(unsigned long long)value_length);
err = ARCHIVE_WARN;
}
__archive_read_consume(a, value_length);
@ -2531,8 +2550,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
if (value_length > xattr_limit) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Ignoring unreasonably large security.selinux attribute:"
" %d > %d",
(int)value_length, (int)xattr_limit);
" %llu > %llu",
(unsigned long long)value_length,
(unsigned long long)xattr_limit);
/* TODO: Should this be FAILED instead? */
err = ARCHIVE_WARN;
} else {
@ -2649,8 +2669,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
}
} else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Unreasonably large xattr: %d > %d",
(int)value_length, (int)xattr_limit);
"Unreasonably large xattr: %llu > %llu",
(unsigned long long)value_length,
(unsigned long long)xattr_limit);
err = ARCHIVE_WARN;
}
__archive_read_consume(a, value_length);
@ -2680,8 +2701,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
}
} else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Unreasonably large sparse map: %d > %d",
(int)value_length, (int)sparse_map_limit);
"Unreasonably large sparse map: %llu > %llu",
(unsigned long long)value_length,
(unsigned long long)sparse_map_limit);
err = ARCHIVE_FAILED;
}
__archive_read_consume(a, value_length);
@ -2750,8 +2772,8 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
}
} else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"hdrcharset attribute is unreasonably large (%d bytes)",
(int)value_length);
"hdrcharset attribute is unreasonably large (%llu bytes)",
(unsigned long long)value_length);
err = ARCHIVE_WARN;
}
__archive_read_consume(a, value_length);
@ -2838,7 +2860,9 @@ pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *ent
/*
* parse a decimal time value, which may include a fractional portion
* Parse a decimal time value, which may include a fractional portion
*
* Sets ps to INT64_MIN on error.
*/
static void
pax_time(const char *p, size_t length, int64_t *ps, long *pn)
@ -2854,6 +2878,7 @@ pax_time(const char *p, size_t length, int64_t *ps, long *pn)
if (length <= 0) {
*ps = 0;
*pn = 0;
return;
}
s = 0;
@ -2867,8 +2892,9 @@ pax_time(const char *p, size_t length, int64_t *ps, long *pn)
digit = *p - '0';
if (s > limit ||
(s == limit && digit > last_digit_limit)) {
s = INT64_MAX;
break;
*ps = INT64_MIN;
*pn = 0;
return;
}
s = (s * 10) + digit;
++p;
@ -3229,12 +3255,10 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
* Returns length (in bytes) of the sparse data description
* that was read.
*/
static ssize_t
static int64_t
gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed)
{
ssize_t bytes_read;
int entries;
int64_t offset, size, to_skip, remaining;
int64_t bytes_read, entries, offset, size, to_skip, remaining;
/* Clear out the existing sparse list. */
gnu_clear_sparse_list(tar);
@ -3242,7 +3266,7 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed)
remaining = tar->entry_bytes_remaining;
/* Parse entries. */
entries = (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
entries = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
if (entries < 0)
return (ARCHIVE_FATAL);
/* Parse the individual entries. */
@ -3260,14 +3284,14 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed)
}
/* Skip rest of block... */
tar_flush_unconsumed(a, unconsumed);
bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
bytes_read = tar->entry_bytes_remaining - remaining;
to_skip = 0x1ff & -bytes_read;
/* Fail if tar->entry_bytes_remaing would get negative */
if (to_skip > remaining)
return (ARCHIVE_FATAL);
if (to_skip != __archive_read_consume(a, to_skip))
return (ARCHIVE_FATAL);
return ((ssize_t)(bytes_read + to_skip));
return (bytes_read + to_skip);
}
/*

View File

@ -116,8 +116,14 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
long_flag = '\0';
switch(*p) {
case 'j':
case 'l':
if (p[1] == 'l') {
long_flag = 'L';
p += 2;
break;
}
__LA_FALLTHROUGH;
case 'j':
case 'z':
long_flag = *p;
p++;
@ -136,6 +142,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
switch(long_flag) {
case 'j': s = va_arg(ap, intmax_t); break;
case 'l': s = va_arg(ap, long); break;
case 'L': s = va_arg(ap, long long); break;
case 'z': s = va_arg(ap, ssize_t); break;
default: s = va_arg(ap, int); break;
}
@ -144,6 +151,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
case 's':
switch(long_flag) {
case 'l':
case 'L':
pw = va_arg(ap, wchar_t *);
if (pw == NULL)
pw = L"(null)";
@ -172,6 +180,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
switch(long_flag) {
case 'j': u = va_arg(ap, uintmax_t); break;
case 'l': u = va_arg(ap, unsigned long); break;
case 'L': u = va_arg(ap, unsigned long long); break;
case 'z': u = va_arg(ap, size_t); break;
default: u = va_arg(ap, unsigned int); break;
}

View File

@ -77,7 +77,9 @@
#define O_CLOEXEC 0
#endif
static int archive_utility_string_sort_helper(char **, unsigned int);
#if ARCHIVE_VERSION_NUMBER < 4000000
static int __LA_LIBC_CC archive_utility_string_sort_helper(const void *, const void *);
#endif
/* Generic initialization of 'struct archive' objects. */
int
@ -629,74 +631,28 @@ __archive_ensure_cloexec_flag(int fd)
#endif
}
#if ARCHIVE_VERSION_NUMBER < 4000000
/*
* Utility function to sort a group of strings using quicksort.
* Utility functions to sort a group of strings using quicksort.
*/
static int
archive_utility_string_sort_helper(char **strings, unsigned int n)
__LA_LIBC_CC
archive_utility_string_sort_helper(const void *p1, const void *p2)
{
unsigned int i, lesser_count, greater_count;
char **lesser, **greater, **tmp, *pivot;
int retval1, retval2;
const char * const * const s1 = p1;
const char * const * const s2 = p2;
/* A list of 0 or 1 elements is already sorted */
if (n <= 1)
return (ARCHIVE_OK);
lesser_count = greater_count = 0;
lesser = greater = NULL;
pivot = strings[0];
for (i = 1; i < n; i++)
{
if (strcmp(strings[i], pivot) < 0)
{
lesser_count++;
tmp = realloc(lesser, lesser_count * sizeof(*tmp));
if (!tmp) {
free(greater);
free(lesser);
return (ARCHIVE_FATAL);
}
lesser = tmp;
lesser[lesser_count - 1] = strings[i];
}
else
{
greater_count++;
tmp = realloc(greater, greater_count * sizeof(*tmp));
if (!tmp) {
free(greater);
free(lesser);
return (ARCHIVE_FATAL);
}
greater = tmp;
greater[greater_count - 1] = strings[i];
}
}
/* quicksort(lesser) */
retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
for (i = 0; i < lesser_count; i++)
strings[i] = lesser[i];
free(lesser);
/* pivot */
strings[lesser_count] = pivot;
/* quicksort(greater) */
retval2 = archive_utility_string_sort_helper(greater, greater_count);
for (i = 0; i < greater_count; i++)
strings[lesser_count + 1 + i] = greater[i];
free(greater);
return (retval1 < retval2) ? retval1 : retval2;
return strcmp(*s1, *s2);
}
int
archive_utility_string_sort(char **strings)
{
unsigned int size = 0;
while (strings[size] != NULL)
size_t size = 0;
while (strings[size] != NULL)
size++;
return archive_utility_string_sort_helper(strings, size);
qsort(strings, size, sizeof(char *),
archive_utility_string_sort_helper);
return (ARCHIVE_OK);
}
#endif

View File

@ -134,31 +134,31 @@ archive_libb2_version(struct archive_string* str)
static void
archive_crypto_version(struct archive_string* str)
{
#if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto) || defined(ARCHIVE_DIGEST_USE_Apple_CommonCrypto)
#if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto)
archive_strcat(str, " CommonCrypto/");
archive_strcat(str, archive_commoncrypto_version());
#endif
#if defined(ARCHIVE_CRYPTOR_USE_CNG) || defined(ARCHIVE_DIGEST_USE_CNG)
#if defined(ARCHIVE_CRYPTOR_USE_CNG)
archive_strcat(str, " cng/");
archive_strcat(str, archive_cng_version());
#endif
#if defined(ARCHIVE_CRYPTOR_USE_MBED) || defined(ARCHIVE_DIGEST_USE_MBED)
#if defined(ARCHIVE_CRYPTOR_USE_MBED)
archive_strcat(str, " mbedtls/");
archive_strcat(str, archive_mbedtls_version());
#endif
#if defined(ARCHIVE_CRYPTOR_USE_NETTLE) || defined(ARCHIVE_DIGEST_USE_NETTLE)
#if defined(ARCHIVE_CRYPTOR_USE_NETTLE)
archive_strcat(str, " nettle/");
archive_strcat(str, archive_nettle_version());
#endif
#if defined(ARCHIVE_CRYPTOR_USE_OPENSSL) || defined(ARCHIVE_DIGEST_USE_OPENSSL)
#if defined(ARCHIVE_CRYPTOR_USE_OPENSSL)
archive_strcat(str, " openssl/");
archive_strcat(str, archive_openssl_version());
#endif
#if defined(ARCHIVE_CRYPTOR_USE_LIBMD) || defined(ARCHIVE_DIGEST_USE_LIBMD)
#if defined(ARCHIVE_CRYPTOR_USE_LIBMD)
archive_strcat(str, " libmd/");
archive_strcat(str, archive_libmd_version());
#endif
#if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT) || defined(ARCHIVE_DIGEST_USE_WINCRYPT)
#if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT)
archive_strcat(str, " WinCrypt/");
archive_strcat(str, archive_wincrypt_version());
#endif
@ -439,11 +439,11 @@ archive_wincrypt_version(void)
if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
return NULL;
}
DWORD length, version;
if (!CryptGetProvParam(prov, PP_VERSION, &version, &length, 0)) {
DWORD version, length = sizeof(version);
if (!CryptGetProvParam(prov, PP_VERSION, (BYTE *)&version, &length, 0)) {
return NULL;
} else {
char major = version >> 8;
char major = (version >> 8) & 0xFF;
char minor = version & 0xFF;
static char wincrypt_version[6];
snprintf(wincrypt_version, 6, "%hhd.%hhd", major, minor);

View File

@ -408,7 +408,11 @@ permissive_name_w(struct archive_write_disk *a)
wn = _wcsdup(wnp);
if (wn == NULL)
return (-1);
archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1);
if (archive_wstring_ensure(&(a->_name_data),
4 + wcslen(wn) + 1) == NULL) {
free(wn);
return (-1);
}
a->name = a->_name_data.s;
/* Prepend "\\?\" */
archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
@ -438,8 +442,11 @@ permissive_name_w(struct archive_write_disk *a)
wn = _wcsdup(wnp);
if (wn == NULL)
return (-1);
archive_wstring_ensure(&(a->_name_data),
8 + wcslen(wn) + 1);
if (archive_wstring_ensure(&(a->_name_data),
8 + wcslen(wn) + 1) == NULL) {
free(wn);
return (-1);
}
a->name = a->_name_data.s;
/* Prepend "\\?\UNC\" */
archive_wstrncpy(&(a->_name_data),
@ -471,10 +478,16 @@ permissive_name_w(struct archive_write_disk *a)
*/
if (wnp[0] == L'\\') {
wn = _wcsdup(wnp);
if (wn == NULL)
if (wn == NULL) {
free(wsp);
return (-1);
archive_wstring_ensure(&(a->_name_data),
4 + 2 + wcslen(wn) + 1);
}
if (archive_wstring_ensure(&(a->_name_data),
4 + 2 + wcslen(wn) + 1) == NULL) {
free(wsp);
free(wn);
return (-1);
}
a->name = a->_name_data.s;
/* Prepend "\\?\" and drive name. */
archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
@ -486,9 +499,16 @@ permissive_name_w(struct archive_write_disk *a)
}
wn = _wcsdup(wnp);
if (wn == NULL)
if (wn == NULL) {
free(wsp);
return (-1);
archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
}
if (archive_wstring_ensure(&(a->_name_data),
4 + l + 1 + wcslen(wn) + 1) == NULL) {
free(wsp);
free(wn);
return (-1);
}
a->name = a->_name_data.s;
/* Prepend "\\?\" and drive name if not already added. */
if (l > 3 && wsp[0] == L'\\' && wsp[1] == L'\\' &&

View File

@ -1167,7 +1167,12 @@ archive_write_set_format_iso9660(struct archive *_a)
iso9660->primary.rootent->parent = iso9660->primary.rootent;
iso9660->cur_dirent = iso9660->primary.rootent;
archive_string_init(&(iso9660->cur_dirstr));
archive_string_ensure(&(iso9660->cur_dirstr), 1);
if (archive_string_ensure(&(iso9660->cur_dirstr), 1) == NULL) {
free(iso9660);
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory");
return (ARCHIVE_FATAL);
}
iso9660->cur_dirstr.s[0] = 0;
iso9660->sconv_to_utf16be = NULL;
iso9660->sconv_from_utf16be = NULL;
@ -5666,9 +5671,15 @@ isoent_tree(struct archive_write *a, struct isoent **isoentpp)
* inserted. */
iso9660->cur_dirent = dent;
archive_string_empty(&(iso9660->cur_dirstr));
archive_string_ensure(&(iso9660->cur_dirstr),
if (archive_string_ensure(&(iso9660->cur_dirstr),
archive_strlen(&(dent->file->parentdir)) +
archive_strlen(&(dent->file->basename)) + 2);
archive_strlen(&(dent->file->basename)) + 2) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory");
_isoent_free(isoent);
*isoentpp = NULL;
return (ARCHIVE_FATAL);
}
if (archive_strlen(&(dent->file->parentdir)) +
archive_strlen(&(dent->file->basename)) == 0)
iso9660->cur_dirstr.s[0] = 0;

View File

@ -2209,9 +2209,13 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
* inserted. */
mtree->cur_dirent = dent;
archive_string_empty(&(mtree->cur_dirstr));
archive_string_ensure(&(mtree->cur_dirstr),
if (archive_string_ensure(&(mtree->cur_dirstr),
archive_strlen(&(dent->parentdir)) +
archive_strlen(&(dent->basename)) + 2);
archive_strlen(&(dent->basename)) + 2) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory");
return (ARCHIVE_FATAL);
}
if (archive_strlen(&(dent->parentdir)) +
archive_strlen(&(dent->basename)) == 0)
mtree->cur_dirstr.s[0] = 0;

View File

@ -174,8 +174,10 @@ IF(ENABLE_TEST)
test_read_format_tar_empty_pax.c
test_read_format_tar_filename.c
test_read_format_tar_invalid_pax_size.c
test_read_format_tar_mac_metadata.c
test_read_format_tar_pax_g_large.c
test_read_format_tar_pax_large_attr.c
test_read_format_tar_pax_negative_time.c
test_read_format_tbz.c
test_read_format_tgz.c
test_read_format_tlz.c
@ -208,6 +210,7 @@ IF(ENABLE_TEST)
test_read_format_zip_zip64.c
test_read_format_zip_with_invalid_traditional_eocd.c
test_read_large.c
test_read_pax_empty_val_no_nl.c
test_read_pax_xattr_rht_security_selinux.c
test_read_pax_xattr_schily.c
test_read_pax_truncated.c

View File

@ -436,7 +436,7 @@ DEFINE_TEST(test_entry)
archive_entry_fflags(e, &set, &clear);
assertEqualInt(UF_HIDDEN, set);
assertEqualInt(UF_NODUMP | UF_IMMUTABLE | UF_APPEND, clear);
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
archive_entry_copy_fflags_text_w(e, L"rdonly,hidden,nosystem");
archive_entry_fflags(e, &set, &clear);
assertEqualInt(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN, set);

View File

@ -39,7 +39,7 @@ atimeIsUpdated(void)
{
const char *fn = "fs_noatime";
struct stat st;
#if defined(_WIN32) && !defined(CYGWIN)
#if defined(_WIN32) && !defined(__CYGWIN__)
char *buff = NULL;
char *ptr;
int r;

View File

@ -1,15 +1,15 @@
begin 644 test_read_format_gtar_sparse_skip_entry.tar.Z
M'YV04,+@05(F#)DR<EZ$`<"PH<.'$"-*G$BQHL6*,#+:L$$#!(",,6[4@.$1
MI$B2'S.JS#A#A@P0,63,L`$C!HP9-VB\K"FCAHT8`$#@N4BTJ-&C2"/6F4,G
MC)R48^J424HQZE2J$E=F+*G5(]:O8,.*'3M6!LDY:?24Z6'S!DX:,7#(H$%#
MP0R2;>BD:;,V!@T8-6)NE&'#10T<-#;>R(%CAEV28_3R9?LW\(P8-F[`<#%C
M)@T<->#6>`PBC.2^E07;J#'#Q>J-F5DJ<`GBB),J+N;`<3JGC(LV8=2\D<-V
M]DO;N'7S]MTFC9OA/6#,CE'[=N[=<GJ[<!-F<AB[-:HGQZY=3D$V:-6RA>$V
M9]RY=<G*GT^_OOW[^/.#13Z%?!DC:;!1AD+Z%6B12AMUE%)((W'%($I:U603
M#!W%-%---^6T4PPM8184#`:&"-9233V5D57SH2A?A%RMY)6(,,8HHPP*2/=7
M#C8HT-9;[_VE0'PR!BGDD$06:>212"9YD1EOO*&`DE!&*>645%9IY9589JGE
MC)R48^J424HQZE2J$E=F+*G5(]:O8,.*'3M6!LDY:?24Z:$U(XV?,A3,(-F&
M3IHV:V/0@%$CYD89-ES4P/'6QHT<.&;()3G&+MX>>OG&F!'#,`P7,V;2P%&#
M1HP:BT&$<9QW;U_`-FK,<)%ZH^6;"ER"..*DBHLY<)S.*>.B31@U;^1`COV2
MMFW<NGFW2>,F.-O8,6;7OIU;SFX7;L(\#B.WAO3CU:_+*<@&K5K(,&[@](Q#
M!@T:"LC*GT^_OOW[^/.#-3XE?!DC:;!1AD+Z%6B12AMUE%)((W'%($IMK=11
M3#/5=%-..TTF@UY!P6#@AV`MU=13&5DUGXGRM<752EZ!Z.*+,,8%@P)[Y6"#
M`C:IEU,,[>TE5WPP!BGDD$06:>212"9YD1EOO`&DDE!&*>645%9IY9589JGE
MEEQVZ>678(8IYIADEFGFF6BFJ>::;+;IYIMPQBGGG'36:>>=>.:IYYY\]NGG
MGX`&*NB@A!9JJ)YB](D@1PZ>U&B#*468484RT11###7<8!8(&-)4PX=^DN@4
B5%*E6.J*746JTHN'2LFDDZW&*NNLM-9JZZVXYJKKKKR&!0``
MGX`&*NB@A!9J*)YB](D@1PZ>U&B#*44(PX0RT13#9S>8!8*%--70H9\B.@65
A5">2FF)7D:K4XJ%2,NDDJ[#&*NNLM-9JZZVXYJKKKF$!
`
end

View File

@ -1126,7 +1126,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_READONLY;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_READONLY;
#endif
assertEqualInt(flag, set & flag);
@ -1138,7 +1138,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_HIDDEN;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_HIDDEN;
#endif
assertEqualInt(flag, set & flag);
@ -1150,7 +1150,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_SYSTEM;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_SYSTEM;
#endif
assertEqualInt(flag, set & flag);
@ -1162,7 +1162,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_READONLY | UF_HIDDEN;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN;
#endif
assertEqualInt(flag, set & flag);
@ -1174,7 +1174,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_READONLY;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_READONLY;
#endif
assertEqualInt(flag, set & flag);
@ -1186,7 +1186,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_HIDDEN;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_HIDDEN;
#endif
assertEqualInt(flag, set & flag);
@ -1198,7 +1198,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_SYSTEM;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_SYSTEM;
#endif
assertEqualInt(flag, set & flag);
@ -1210,7 +1210,7 @@ DEFINE_TEST(test_read_format_rar5_fileattr)
archive_entry_fflags(ae, &set, &clear);
#if defined(__FreeBSD__)
flag = UF_READONLY | UF_HIDDEN;
#elif defined(_WIN32) && !defined(CYGWIN)
#elif defined(_WIN32) && !defined(__CYGWIN__)
flag = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN;
#endif
assertEqualInt(flag, set & flag);

View File

@ -0,0 +1,85 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 Zhaofeng Li
* All rights reserved.
*/
#include "test.h"
DEFINE_TEST(test_read_format_tar_mac_metadata)
{
/*
This test tar file is crafted with two files in a specific order:
1. A ._-prefixed file with pax header containing the path attribute.
2. A file with a pax header but without the path attribute.
It's designed to trigger the case encountered in:
<https://github.com/libarchive/libarchive/pull/2636>
GNU tar is required to reproduce this tar file:
```sh
NAME1="._101_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
NAME2="goodname"
OUT="test_read_format_tar_mac_metadata_1.tar"
echo "content of badname" >"${NAME1}"
echo "content of goodname" >"${NAME2}"
rm -f "${OUT}"
gnutar \
--mtime="@0" \
--owner=0 --group=0 --numeric-owner \
--pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0,ctime:=0,foo:=bar \
--format=pax \
-cf "${OUT}" \
"${NAME1}" \
"${NAME2}"
uuencode "${OUT}" "${OUT}" >"${OUT}.uu"
sha256sum "${OUT}"
sha256sum "${OUT}.uu"
```
*/
const char *refname = "test_read_format_tar_mac_metadata_1.tar";
char *p;
size_t s;
struct archive *a;
struct archive_entry *ae;
/*
* This is not a valid AppleDouble metadata file. It is merely to test that
* the correct bytes are read.
*/
const unsigned char appledouble[] = {
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x62,
0x61, 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x0a
};
extract_reference_file(refname);
p = slurpfile(&s, "%s", refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_tar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_set_option(a, "tar", "mac-ext", "1"));
assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
/* Correct name and metadata bytes */
assertEqualString("goodname", archive_entry_pathname(ae));
const void *metadata = archive_entry_mac_metadata(ae, &s);
if (assert(metadata != NULL)) {
assertEqualMem(metadata, appledouble,
sizeof(appledouble));
}
/* ... and nothing else */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
}

View File

@ -0,0 +1,231 @@
begin 644 test_read_format_tar_mac_metadata_1.tar
M+B]087A(96%D97)S+RY?,3`Q7V%A86%A86%A86%A86%A86%A86%A86%A86%A
M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A
M86%A86%A86%A83`P,#`V-#0`,#`P,#`P,``P,#`P,#`P`#`P,#`P,#`P,C(P
M`#`P,#`P,#`P,#`P`#`S,#,Q,0`@>```````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````!U<W1A<@`P,```````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M```````````````````````Q,3$@<&%T:#TN7S$P,5]A86%A86%A86%A86%A
M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A
M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A80HQ,2!F;V\]
M8F%R"C$Q(&-T:6UE/3`*,3$@871I;64],`H`````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````````````````````````````"Y?,3`Q7V%A86%A
M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A
M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86$P
M,#`P-C0T`#`P,#`P,#``,#`P,#`P,``P,#`P,#`P,#`R,P`P,#`P,#`P,#`P
M,``P,S`S-S8`(#``````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````=7-T87(`,#``````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````8V]N=&5N="!O9B!B861N86UE"@``````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M```````````````````````````````N+U!A>$AE861E<G,O9V]O9&YA;64`
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````,#`P,#8T-``P,#`P
M,#`P`#`P,#`P,#``,#`P,#`P,#`P-#$`,#`P,#`P,#`P,#``,#$Q-S0U`"!X
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````'5S=&%R`#`P````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````#$Q(&9O
M;SUB87(*,3$@8W1I;64],`HQ,2!A=&EM93TP"@``````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````9V]O9&YA;64`````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````````````#`P,#`V-#0`,#`P,#`P,``P,#`P,#`P
M`#`P,#`P,#`P,#(T`#`P,#`P,#`P,#`P`#`P-S0U-0`@,```````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````````````````````!U
M<W1A<@`P,```````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````!C;VYT96YT(&]F(&=O;V1N
M86UE"@``````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
9````````````````````````````````````
`
end

View File

@ -0,0 +1,68 @@
/*-
* Copyright (c) 2025 Tobias Stoeckmann
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
/*
* Read a pax formatted tar archive that has a negative modification time.
*/
DEFINE_TEST(test_read_format_tar_pax_negative_time)
{
char name[] = "test_read_format_tar_pax_negative_time.tar";
struct archive_entry *ae;
struct archive *a;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
/* Read first entry. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("empty", archive_entry_pathname(ae));
assertEqualInt(-2146608000, archive_entry_atime(ae));
assertEqualInt(0, archive_entry_atime_nsec(ae));
assertEqualInt(1748089464, archive_entry_ctime(ae));
assertEqualInt(951928467, archive_entry_ctime_nsec(ae));
assertEqualInt(-2146608000, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_mtime_nsec(ae));
assertEqualInt(0, archive_entry_uid(ae));
assertEqualString("root", archive_entry_uname(ae));
assertEqualInt(0, archive_entry_gid(ae));
assertEqualString("root", archive_entry_gname(ae));
assertEqualInt(0100644, archive_entry_mode(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
/* Verify the end-of-archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify that the format detection worked. */
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,60 @@
begin 644 test_read_format_tar_pax_negative_time.tar
M4&%X2&5A9&5R+V5M<'1Y````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````#`P,#8T-"``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,3$P
M(#`P,#`P,#`P,#`P(#`Q-#`Q-P`@>```````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````!U<W1A<@`P,')O;W0`
M````````````````````````````````````<F]O=```````````````````
M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M```````````````````````S,"!C=&EM93TQ-S0X,#@Y-#8T+CDU,3DR.#0V
M-PHR,2!A=&EM93TM,C$T-C8P.#`P,`HR,2!M=&EM93TM,C$T-C8P.#`P,`H`
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````````````````````````````&5M<'1Y````````
M````````````````````````````````````````````````````````````
M```````````````````````````````````````````````````````````P
M,#`V-#0@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`P,"#_________@`U<
M@"`P,34Q-C8`(#``````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````=7-T87(`,#!R;V]T````````````````
M`````````````````````')O;W0`````````````````````````````````
M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
H````````````````````````````````````````````````````````
`
end

View File

@ -0,0 +1,65 @@
/*-
* Copyright (c) 2025 Tobias Stoeckmann
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
/*
* Read a pax formatted tar archive that contains an invalid attribute,
* because it does not end in a newline. Additionally, value is empty.
* The pax reader should stop and tar reader should continue with warning.
*/
DEFINE_TEST(test_read_pax_empty_val_no_nl)
{
char name[] = "test_read_pax_empty_val_no_nl.tar";
struct archive_entry *ae;
struct archive *a;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
/* Read first entry. */
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
assertEqualString("empty", archive_entry_pathname(ae));
assertEqualInt(1748163748, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_uid(ae));
assertEqualString("root", archive_entry_uname(ae));
assertEqualInt(0, archive_entry_gid(ae));
assertEqualString("root", archive_entry_gname(ae));
assertEqualInt(0100600, archive_entry_mode(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
/* Verify the end-of-archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify that the format detection worked. */
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,60 @@
begin 600 test_read_pax_empty_val_no_nl.tar
M4&%X2&5A9&5R+V5M<'1Y````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````#`P,#8P,"``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,#`T
M(#$U,#$T-34V,C0T(#`Q-#`U-@`@>```````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````!U<W1A<@`P,')O;W0`
M````````````````````````````````````<F]O=```````````````````
M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M```````````````````````T('@]````````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````H`````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````````````````````````````&5M<'1Y````````
M````````````````````````````````````````````````````````````
M```````````````````````````````````````````````````````````P
M,#`V,#`@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`P,"`Q-3`Q-#4U-C(T
M-"`P,3(Q,#$`(#``````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````=7-T87(`,#!R;V]T````````````````
M`````````````````````')O;W0`````````````````````````````````
M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
H````````````````````````````````````````````````````````
`
end

View File

@ -43,54 +43,8 @@ static const char *tvf_out =
"-rw-r--r-- 0 1000 1000 0 Jan 1 1980 f\n";
#endif
static void
set_lc_time(const char * str)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!SetEnvironmentVariable("LC_TIME", str)) {
fprintf(stderr, "SetEnvironmentVariable failed with %d\n",
(int)GetLastError());
}
#else
if (setenv("LC_TIME", str, 1) == -1)
fprintf(stderr, "setenv: %s\n", strerror(errno));
#endif
}
static int
run_tvf(void)
{
char * orig_lc_time;
char * lc_time;
int exact_tvf_check;
orig_lc_time = getenv("LC_TIME");
/* Try to set LC_TIME to known (English) dates. */
set_lc_time("en_US.UTF-8");
/* Check if we've got the right LC_TIME; if not, don't check output. */
lc_time = getenv("LC_TIME");
if ((lc_time != NULL) && strcmp(lc_time, "en_US.UTF-8") == 0)
exact_tvf_check = 1;
else
exact_tvf_check = 0;
assertEqualInt(0,
systemf("%s tvf test_list_item.tar >tvf.out 2>tvf.err", testprog));
/* Restore the original date formatting. */
if (orig_lc_time != NULL)
set_lc_time(orig_lc_time);
return (exact_tvf_check);
}
DEFINE_TEST(test_list_item)
{
int exact_tvf_check;
extract_reference_file("test_list_item.tar");
/* Run 'tf' and check output. */
@ -100,16 +54,10 @@ DEFINE_TEST(test_list_item)
assertTextFileContents(tf_out, "tf.out");
assertEmptyFile("tf.err");
/* Run 'tvf'. */
exact_tvf_check = run_tvf();
/* Check 'tvf' output. */
/* Run 'tvf' and check output. */
assertEqualInt(0,
systemf("%s tvf test_list_item.tar >tvf.out 2>tvf.err", testprog));
failure("'t' mode with 'v' should write more results to stdout");
assertTextFileContents(tvf_out, "tvf.out");
assertEmptyFile("tvf.err");
if (exact_tvf_check)
assertTextFileContents(tvf_out, "tvf.out");
else {
/* The 'skipping' macro requires braces. */
skipping("Can't check exact tvf output");
}
}

View File

@ -17,7 +17,7 @@ DEFINE_TEST(test_option_C_mtree)
p0 = NULL;
char *content = "./foo type=file uname=root gname=root mode=0755\n";
char *filename = "output.tar";
#if defined(_WIN32) && !defined(CYGWIN)
#if defined(_WIN32) && !defined(__CYGWIN__)
char *p;
#endif
@ -32,7 +32,7 @@ DEFINE_TEST(test_option_C_mtree)
assertMakeDir("bar", 0775);
assertMakeFile("bar/foo", 0777, "abc");
#if defined(_WIN32) && !defined(CYGWIN)
#if defined(_WIN32) && !defined(__CYGWIN__)
p = absolute_path;
while(*p != '\0') {
if (*p == '/')

View File

@ -2456,7 +2456,7 @@ void assertVersion(const char *prog, const char *base)
/* Skip arbitrary third-party version numbers. */
while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' ||
isalnum((unsigned char)*q))) {
*q == '_' || isalnum((unsigned char)*q))) {
++q;
--s;
}
@ -3554,6 +3554,59 @@ test_summarize(int failed, int skips_num)
memset(failed_lines, 0, sizeof(failed_lines));
}
/*
* Set or unset environment variable.
*/
static void
set_environment(const char *key, const char *value)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!SetEnvironmentVariable(key, value)) {
fprintf(stderr, "SetEnvironmentVariable failed with %d\n",
(int)GetLastError());
}
#else
if (value == NULL) {
if (unsetenv(key) == -1)
fprintf(stderr, "unsetenv: %s\n", strerror(errno));
} else {
if (setenv(key, value, 1) == -1)
fprintf(stderr, "setenv: %s\n", strerror(errno));
}
#endif
}
/*
* Enforce C locale for (sub)processes.
*/
static void
set_c_locale()
{
static const char *lcs[] = {
"LC_ADDRESS",
"LC_ALL",
"LC_COLLATE",
"LC_CTYPE",
"LC_IDENTIFICATION",
"LC_MEASUREMENT",
"LC_MESSAGES",
"LC_MONETARY",
"LC_NAME",
"LC_NUMERIC",
"LC_PAPER",
"LC_TELEPHONE",
"LC_TIME",
NULL
};
size_t i;
setlocale(LC_ALL, "C");
set_environment("LANG", "C");
for (i = 0; lcs[i] != NULL; i++)
set_environment(lcs[i], NULL);
}
/*
* Actually run a single test, with appropriate setup and cleanup.
*/
@ -3629,7 +3682,7 @@ test_run(int i, const char *tmpdir)
exit(1);
}
/* Explicitly reset the locale before each test. */
setlocale(LC_ALL, "C");
set_c_locale();
/* Record the umask before we run the test. */
umask(oldumask = umask(0));
/*
@ -3643,7 +3696,7 @@ test_run(int i, const char *tmpdir)
/* Restore umask */
umask(oldumask);
/* Reset locale. */
setlocale(LC_ALL, "C");
set_c_locale();
/* Reset directory. */
if (!assertChdir(tmpdir)) {
fprintf(stderr, "ERROR: Couldn't chdir to temp dir %s\n",