93 changes: 79 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``<PackageName>_ROOT`` variables.
endif()
#
PROJECT(libarchive C)
#
Expand Down Expand Up @@ -84,6 +87,11 @@ SET(CMAKE_REQUIRED_DEFINITIONS)
SET(CMAKE_REQUIRED_INCLUDES)
SET(CMAKE_REQUIRED_LIBRARIES)
SET(CMAKE_REQUIRED_FLAGS)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." ON)
else ()
OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." OFF)
endif ()

# Especially for early development, we want to be a little
# aggressive about diagnosing build problems; this can get
Expand All @@ -93,10 +101,12 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$")
#################################################################
# Set compile flags for all build types.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
if (ENABLE_WERROR)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif ()
#################################################################
# Set compile flags for debug build.
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
Expand All @@ -108,11 +118,13 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^Clang$")
#################################################################
# Set compile flags for all build types.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
if (ENABLE_WERROR)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif ()
#################################################################
# Set compile flags for debug build.
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
Expand All @@ -125,15 +137,21 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
#################################################################
# Set compile flags for all build types.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qflag=e:e -qformat=sec")
if (ENABLE_WERROR)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qhalt=w")
endif ()
#################################################################
# Set compile flags for debug build.
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qhalt=w")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qflag=w:w")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qinfo=pro:use")
ENDIF(CMAKE_C_COMPILER_ID MATCHES "^XL$")
IF (MSVC)
if (ENABLE_WERROR)
# /WX option is the same as gcc's -Werror option.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
endif ()
#################################################################
# Set compile flags for debug build.
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
Expand Down Expand Up @@ -165,8 +183,6 @@ IF (MSVC)
# Enable level 4 C4706: The test value in a conditional expression was the
# result of an assignment.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4706")
# /WX option is the same as gcc's -Werror option.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /WX")
# /Oi option enables built-in functions.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi")
#################################################################
Expand All @@ -179,9 +195,11 @@ include(CTest)

OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
OPTION(ENABLE_LIBB2 "Enable the use of the system LIBB2 library if found" ON)
OPTION(ENABLE_LZ4 "Enable the use of the system LZ4 library if found" ON)
OPTION(ENABLE_LZO "Enable the use of the system LZO library if found" OFF)
OPTION(ENABLE_LZMA "Enable the use of the system LZMA library if found" ON)
OPTION(ENABLE_ZSTD "Enable the use of the system zstd library if found" ON)

OPTION(ENABLE_ZLIB "Enable the use of the system ZLIB library if found" ON)
OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON)
Expand Down Expand Up @@ -457,12 +475,13 @@ MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
IF(ENABLE_LZMA)
FIND_PACKAGE(LibLZMA)
ELSE()
SET(LIBZMA_FOUND FALSE) # Override cached value
SET(LIBLZMA_FOUND FALSE) # Override cached value
ENDIF()

IF(LIBLZMA_FOUND)
SET(HAVE_LIBLZMA 1)
SET(HAVE_LZMA_H 1)
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIRS})
Expand All @@ -476,9 +495,13 @@ IF(LIBLZMA_FOUND)
IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
ADD_DEFINITIONS(-DLZMA_API_STATIC)
ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
CMAKE_POP_CHECK_STATE()
ELSE(LIBLZMA_FOUND)
# LZMA not found and will not be used.
ENDIF(LIBLZMA_FOUND)
MARK_AS_ADVANCED(CLEAR LIBLZMA_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LIBLZMA_LIBRARY)

#
# Find LZO2
#
Expand Down Expand Up @@ -508,6 +531,35 @@ ENDIF(LZO2_FOUND)
MARK_AS_ADVANCED(CLEAR LZO2_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LZO2_LIBRARY)
#
# Find libb2
#
IF(ENABLE_LIBB2)
IF (LIBB2_INCLUDE_DIR)
# Already in cache, be silent
SET(LIBB2_FIND_QUIETLY TRUE)
ENDIF (LIBB2_INCLUDE_DIR)

FIND_PATH(LIBB2_INCLUDE_DIR blake2.h)
FIND_LIBRARY(LIBB2_LIBRARY NAMES b2 libb2)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBB2 DEFAULT_MSG LIBB2_LIBRARY LIBB2_INCLUDE_DIR)
ELSE(ENABLE_LIBB2)
SET(LIBB2_FOUND FALSE) # Override cached value
ENDIF(ENABLE_LIBB2)
IF(LIBB2_FOUND)
SET(HAVE_LIBB2 1)
SET(HAVE_BLAKE2_H 1)
SET(ARCHIVE_BLAKE2 FALSE)
LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
CHECK_FUNCTION_EXISTS(blake2sp_init HAVE_LIBB2)
CMAKE_POP_CHECK_STATE()
ELSE(LIBB2_FOUND)
SET(ARCHIVE_BLAKE2 TRUE)
ENDIF(LIBB2_FOUND)
#
# Find LZ4
#
IF(ENABLE_LZ4)
Expand Down Expand Up @@ -541,29 +593,36 @@ MARK_AS_ADVANCED(CLEAR LZ4_LIBRARY)
#
# Find Zstd
#
IF (ZSTD_INCLUDE_DIR)
# Already in cache, be silent
SET(ZSTD_FIND_QUIETLY TRUE)
ENDIF (ZSTD_INCLUDE_DIR)
IF(ENABLE_ZSTD)
IF (ZSTD_INCLUDE_DIR)
# Already in cache, be silent
SET(ZSTD_FIND_QUIETLY TRUE)
ENDIF (ZSTD_INCLUDE_DIR)

FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
ELSE(ENABLE_ZSTD)
SET(ZSTD_FOUND FALSE) # Override cached value
ENDIF(ENABLE_ZSTD)
IF(ZSTD_FOUND)
SET(HAVE_ZSTD_H 1)
INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD)
#
# TODO: test for static library.
#
CMAKE_POP_CHECK_STATE()
ENDIF(ZSTD_FOUND)
MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY)


#
# Check headers
#
Expand Down Expand Up @@ -1291,6 +1350,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT)
CHECK_FUNCTION_EXISTS_GLIBC(unsetenv HAVE_UNSETENV)
CHECK_FUNCTION_EXISTS_GLIBC(utime HAVE_UTIME)
CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES)
Expand Down Expand Up @@ -1572,6 +1632,11 @@ IF(ENABLE_XATTR)
CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR)
IF(HAVE_LIBATTR)
SET(CMAKE_REQUIRED_LIBRARIES "attr")
ELSE()
CHECK_LIBRARY_EXISTS(gnu "setxattr" "" HAVE_LIBATTR_GNU)
IF(HAVE_LIBATTR_GNU)
SET(CMAKE_REQUIRED_LIBRARIES "gnu")
ENDIF()
ENDIF(HAVE_LIBATTR)
CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
CHECK_SYMBOL_EXISTS(XATTR_NOFOLLOW "sys/xattr.h" HAVE_DECL_XATTR_NOFOLLOW)
Expand Down
9 changes: 8 additions & 1 deletion COPYING
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ the actual statements in the files are controlling.
* The following source files are in the public domain:
libarchive/archive_getdate.c

* The following source files are triple-licensed with the ability to choose
from CC0 1.0 Universal, OpenSSL or Apache 2.0 licenses:
libarchive/archive_blake2.h
libarchive/archive_blake2_impl.h
libarchive/archive_blake2s_ref.c
libarchive/archive_blake2sp_ref.c

* The build files---including Makefiles, configure scripts,
and auxiliary scripts used as part of the compile process---have
widely varying licensing terms. Please check individual files before
Expand All @@ -34,7 +41,7 @@ do use the license below. The varying licensing of the build scripts
seems to be an unavoidable mess.


Copyright (c) 2003-2009 <author(s)>
Copyright (c) 2003-2018 <author(s)>
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
69 changes: 67 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ libarchive_la_SOURCES= \
libarchive/archive_ppmd_private.h \
libarchive/archive_ppmd7.c \
libarchive/archive_ppmd7_private.h \
libarchive/archive_ppmd8.c \
libarchive/archive_ppmd8_private.h \
libarchive/archive_private.h \
libarchive/archive_random.c \
libarchive/archive_random_private.h \
Expand Down Expand Up @@ -179,6 +181,7 @@ libarchive_la_SOURCES= \
libarchive/archive_read_support_format_lha.c \
libarchive/archive_read_support_format_mtree.c \
libarchive/archive_read_support_format_rar.c \
libarchive/archive_read_support_format_rar5.c \
libarchive/archive_read_support_format_raw.c \
libarchive/archive_read_support_format_tar.c \
libarchive/archive_read_support_format_warc.c \
Expand Down Expand Up @@ -251,6 +254,14 @@ libarchive_la_SOURCES+= \
libarchive/filter_fork_windows.c
endif

if INC_BLAKE2
libarchive_la_SOURCES+= \
libarchive/archive_blake2.h \
libarchive/archive_blake2_impl.h \
libarchive/archive_blake2s_ref.c \
libarchive/archive_blake2sp_ref.c
endif

if INC_LINUX_ACL
libarchive_la_SOURCES+= libarchive/archive_disk_acl_linux.c
else
Expand All @@ -277,6 +288,7 @@ libarchive_man_MANS= \
libarchive/archive_entry.3 \
libarchive/archive_entry_acl.3 \
libarchive/archive_entry_linkify.3 \
libarchive/archive_entry_misc.3 \
libarchive/archive_entry_paths.3 \
libarchive/archive_entry_perms.3 \
libarchive/archive_entry_stat.3 \
Expand Down Expand Up @@ -393,7 +405,6 @@ libarchive_test_SOURCES= \
libarchive/test/test_compat_lzma.c \
libarchive/test/test_compat_lzop.c \
libarchive/test/test_compat_mac.c \
libarchive/test/test_compat_pax_libarchive_2x.c \
libarchive/test/test_compat_perl_archive_tar.c \
libarchive/test/test_compat_plexus_archiver_tar.c \
libarchive/test/test_compat_solaris_tar_acl.c \
Expand Down Expand Up @@ -485,11 +496,13 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_rar_encryption_partially.c \
libarchive/test/test_read_format_rar_encryption_header.c \
libarchive/test/test_read_format_rar_invalid1.c \
libarchive/test/test_read_format_rar5.c \
libarchive/test/test_read_format_raw.c \
libarchive/test/test_read_format_tar.c \
libarchive/test/test_read_format_tar_concatenated.c \
libarchive/test/test_read_format_tar_empty_pax.c \
libarchive/test/test_read_format_tar_empty_filename.c \
libarchive/test/test_read_format_tar_empty_with_gnulabel.c \
libarchive/test/test_read_format_tar_filename.c \
libarchive/test/test_read_format_tbz.c \
libarchive/test/test_read_format_tgz.c \
Expand All @@ -500,10 +513,12 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_warc.c \
libarchive/test/test_read_format_xar.c \
libarchive/test/test_read_format_zip.c \
libarchive/test/test_read_format_zip_7075_utf8_paths.c \
libarchive/test/test_read_format_zip_comment_stored.c \
libarchive/test/test_read_format_zip_encryption_data.c \
libarchive/test/test_read_format_zip_encryption_partially.c \
libarchive/test/test_read_format_zip_encryption_header.c \
libarchive/test/test_read_format_zip_extra_padding.c \
libarchive/test/test_read_format_zip_filename.c \
libarchive/test/test_read_format_zip_high_compression.c \
libarchive/test/test_read_format_zip_jar.c \
Expand Down Expand Up @@ -663,7 +678,6 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_compat_lzop_3.tar.lzo.uu \
libarchive/test/test_compat_mac-1.tar.Z.uu \
libarchive/test/test_compat_mac-2.tar.Z.uu \
libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu \
libarchive/test/test_compat_perl_archive_tar.tar.uu \
libarchive/test/test_compat_plexus_archiver_tar.tar.uu \
libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu \
Expand Down Expand Up @@ -711,6 +725,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_filter_lzop.tar.lzo.uu \
libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu \
libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu \
libarchive/test/test_read_format_mtree_noprint.mtree.uu \
libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu \
Expand Down Expand Up @@ -810,27 +825,68 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu \
libarchive/test/test_read_format_rar_noeof.rar.uu \
libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \
libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu \
libarchive/test/test_read_format_rar_sfx.exe.uu \
libarchive/test/test_read_format_rar_subblock.rar.uu \
libarchive/test/test_read_format_rar_unicode.rar.uu \
libarchive/test/test_read_format_rar_windows.rar.uu \
libarchive/test/test_read_format_rar5_arm.rar.uu \
libarchive/test/test_read_format_rar5_blake2.rar.uu \
libarchive/test/test_read_format_rar5_compressed.rar.uu \
libarchive/test/test_read_format_rar5_distance_overflow.rar.uu \
libarchive/test/test_read_format_rar5_extra_field_version.rar.uu \
libarchive/test/test_read_format_rar5_fileattr.rar.uu \
libarchive/test/test_read_format_rar5_hardlink.rar.uu \
libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu \
libarchive/test/test_read_format_rar5_leftshift1.rar.uu \
libarchive/test/test_read_format_rar5_leftshift2.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part02.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part03.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part04.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part05.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part06.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part07.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive.part08.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part01.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part02.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part03.rar.uu \
libarchive/test/test_read_format_rar5_multiarchive_solid.part04.rar.uu \
libarchive/test/test_read_format_rar5_multiple_files.rar.uu \
libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu \
libarchive/test/test_read_format_rar5_nonempty_dir_stream.rar.uu \
libarchive/test/test_read_format_rar5_owner.rar.uu \
libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu \
libarchive/test/test_read_format_rar5_solid.rar.uu \
libarchive/test/test_read_format_rar5_stored.rar.uu \
libarchive/test/test_read_format_rar5_stored_manyfiles.rar.uu \
libarchive/test/test_read_format_rar5_symlink.rar.uu \
libarchive/test/test_read_format_rar5_truncated_huff.rar.uu \
libarchive/test/test_read_format_rar5_win32.rar.uu \
libarchive/test/test_read_format_raw.bufr.uu \
libarchive/test/test_read_format_raw.data.gz.uu \
libarchive/test/test_read_format_raw.data.Z.uu \
libarchive/test/test_read_format_raw.data.uu \
libarchive/test/test_read_format_tar_concatenated.tar.uu \
libarchive/test/test_read_format_tar_empty_filename.tar.uu \
libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu \
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_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 \
libarchive/test/test_read_format_warc.warc.uu \
libarchive/test/test_read_format_zip.zip.uu \
libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \
libarchive/test/test_read_format_zip_bz2_hang.zip.uu \
libarchive/test/test_read_format_zip_bzip2.zipx.uu \
libarchive/test/test_read_format_zip_bzip2_multi.zipx.uu \
libarchive/test/test_read_format_zip_comment_stored_1.zip.uu \
libarchive/test/test_read_format_zip_comment_stored_2.zip.uu \
libarchive/test/test_read_format_zip_encryption_data.zip.uu \
libarchive/test/test_read_format_zip_encryption_header.zip.uu \
libarchive/test/test_read_format_zip_encryption_partially.zip.uu \
libarchive/test/test_read_format_zip_extra_padding.zip.uu \
libarchive/test/test_read_format_zip_filename_cp866.zip.uu \
libarchive/test/test_read_format_zip_filename_cp932.zip.uu \
libarchive/test/test_read_format_zip_filename_koi8r.zip.uu \
Expand All @@ -839,6 +895,9 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \
libarchive/test/test_read_format_zip_high_compression.zip.uu \
libarchive/test/test_read_format_zip_length_at_end.zip.uu \
libarchive/test/test_read_format_zip_lzma.zipx.uu \
libarchive/test/test_read_format_zip_lzma_alone_leak.zipx.uu \
libarchive/test/test_read_format_zip_lzma_multi.zipx.uu \
libarchive/test/test_read_format_zip_jar.jar.uu \
libarchive/test/test_read_format_zip_mac_metadata.zip.uu \
libarchive/test/test_read_format_zip_malformed1.zip.uu \
Expand All @@ -848,6 +907,10 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_zip_padded1.zip.uu \
libarchive/test/test_read_format_zip_padded2.zip.uu \
libarchive/test/test_read_format_zip_padded3.zip.uu \
libarchive/test/test_read_format_zip_ppmd8.zipx.uu \
libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu \
libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu \
libarchive/test/test_read_format_zip_ppmd8_multi.zipx.uu \
libarchive/test/test_read_format_zip_sfx.uu \
libarchive/test/test_read_format_zip_symlink.zip.uu \
libarchive/test/test_read_format_zip_traditional_encryption_data.zip.uu \
Expand All @@ -857,6 +920,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_zip_winzip_aes256_large.zip.uu \
libarchive/test/test_read_format_zip_winzip_aes256_stored.zip.uu \
libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.zip.uu \
libarchive/test/test_read_format_zip_xz_multi.zipx.uu \
libarchive/test/test_read_format_zip_zip64a.zip.uu \
libarchive/test/test_read_format_zip_zip64b.zip.uu \
libarchive/test/test_read_large_splitted_rar_aa.uu \
Expand Down Expand Up @@ -985,6 +1049,7 @@ bsdtar_test_SOURCES= \
tar/test/test_option_b.c \
tar/test/test_option_b64encode.c \
tar/test/test_option_exclude.c \
tar/test/test_option_exclude_vcs.c \
tar/test/test_option_fflags.c \
tar/test/test_option_gid_gname.c \
tar/test/test_option_grzip.c \
Expand Down
16 changes: 16 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
Jun 11, 2019: libarchive 3.4.0 released

May 18, 2019: Fixes for reading Android APK and JAR archives

Apr 16, 2019: Support for non-recursive list and extract

Apr 14, 2019: New tar option: --exclude-vcs

Mar 27, 2019: Support for file and directory symlinks on Windows

Mar 12, 2019: Important fixes for storing file attributes and flags

Jan 20, 2019: Support for xz, lzma, ppmd8 and bzip2 decompression in ZIP files

Oct 06, 2018: RAR 5.0 reader

Sep 03, 2018: libarchive 3.3.3 released

Jul 19, 2018: Avoid super-linear slowdown on malformed mtree files
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,16 @@ Currently, the library automatically detects and reads the following fomats:
* POSIX pax interchange format
* POSIX octet-oriented cpio
* SVR4 ASCII cpio
* POSIX octet-oriented cpio
* Binary cpio (big-endian or little-endian)
* ISO9660 CD-ROM images (with optional Rockridge or Joliet extensions)
* ZIP archives (with uncompressed or "deflate" compressed entries, including support for encrypted Zip archives)
* ZIPX archives (with support for bzip2, ppmd8, lzma and xz compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
* 7-Zip archives
* Microsoft CAB format
* LHA and LZH archives
* RAR archives (with some limitations due to RAR's proprietary status)
* RAR and RAR 5.0 archives (with some limitations due to RAR's proprietary status)
* XAR archives

The library also detects and handles any of the following before evaluating the archive:
Expand Down
69 changes: 51 additions & 18 deletions build/ci_build.sh → build/ci/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@
# Automated build and test of libarchive on CI systems
#
# Variables that can be passed via environment:
# BUILD_SYSTEM=
# BUILDDIR=
# SRCDIR=
# CONFIGURE_ARGS=
# MAKE_ARGS=
#
# BS= # build system (autotools or cmake)
# BUILDDIR= # build directory
# SRCDIR= # source directory
# CONFIGURE_ARGS= # configure arguments
# MAKE_ARGS= # make arguments
# DEBUG= # set -g -fsanitize=address flags

ACTIONS=
BUILD_SYSTEM="${BUILD_SYSTEM:-autotools}"
if [ -n "${BUILD_SYSTEM}" ]; then
BS="${BUILD_SYSTEM}"
fi

BS="${BS:-autotools}"
MAKE="${MAKE:-make}"
CMAKE="${CMAKE:-cmake}"
CURDIR=`pwd`
SRCDIR="${SRCDIR:-`pwd`}"
RET=0

usage () {
echo "Usage: $0 [-b autotools|cmake] [-a autogen|configure|build|test ] [ -a ... ] [ -d builddir ] [-s srcdir ]"
echo "Usage: $0 [-b autotools|cmake] [-a autogen|configure|build|test|install|distcheck ] [ -a ... ] [ -d builddir ] [-s srcdir ]"
}
inputerror () {
echo $1
Expand All @@ -34,12 +38,14 @@ while getopts a:b:d:s: opt; do
configure) ;;
build) ;;
test) ;;
install) ;;
distcheck) ;;
*) inputerror "Invalid action (-a)" ;;
esac
ACTIONS="${ACTIONS} ${OPTARG}"
;;
b) BUILD_SYSTEM="${OPTARG}"
case "${BUILD_SYSTEM}" in
b) BS="${OPTARG}"
case "${BS}" in
autotools) ;;
cmake) ;;
*) inputerror "Invalid build system (-b)" ;;
Expand All @@ -56,21 +62,38 @@ while getopts a:b:d:s: opt; do
;;
esac
done
if [ -z "${MAKE_ARGS}" ]; then
if [ "${BS}" = "autotools" ]; then
MAKE_ARGS="V=1"
elif [ "${BS}" = "cmake" ]; then
MAKE_ARGS="VERBOSE=1"
fi
fi
if [ -n "${DEBUG}" ]; then
if [ -n "${CFLAGS}" ]; then
export CFLAGS="${CFLAGS} -g -fsanitize=address"
else
export CFLAGS="-g -fsanitize=address"
fi
if [ "${BS}" = "cmake" ]; then
CONFIGURE_ARGS="${CONFIGURE_ARGS} -DCMAKE_C_CFLAGS=-g -fsanitize=address"
fi
fi
if [ -z "${ACTIONS}" ]; then
ACTIONS="autogen configure build test"
ACTIONS="autogen configure build test install"
fi
if [ -z "${BUILD_SYSTEM}" ]; then
inputerror "Missing type (-t) parameter"
if [ -z "${BS}" ]; then
inputerror "Missing build system (-b) parameter"
fi
if [ -z "${BUILDDIR}" ]; then
BUILDDIR="${CURDIR}/build_ci/${BUILD_SYSTEM}"
BUILDDIR="${CURDIR}/build_ci/${BS}"
fi
mkdir -p "${BUILDDIR}"
for action in ${ACTIONS}; do
cd "${BUILDDIR}"
case "${action}" in
autogen)
case "${BUILD_SYSTEM}" in
case "${BS}" in
autotools)
cd "${SRCDIR}"
sh build/autogen.sh
Expand All @@ -79,7 +102,7 @@ for action in ${ACTIONS}; do
esac
;;
configure)
case "${BUILD_SYSTEM}" in
case "${BS}" in
autotools) "${SRCDIR}/configure" ${CONFIGURE_ARGS} ;;
cmake) ${CMAKE} ${CONFIGURE_ARGS} "${SRCDIR}" ;;
esac
Expand All @@ -90,15 +113,25 @@ for action in ${ACTIONS}; do
RET="$?"
;;
test)
case "${BUILD_SYSTEM}" in
case "${BS}" in
autotools)
${MAKE} ${MAKE_ARGS} check LOG_DRIVER="${SRCDIR}/build/ci_test_driver"
${MAKE} ${MAKE_ARGS} check LOG_DRIVER="${SRCDIR}/build/ci/test_driver"
;;
cmake)
${MAKE} ${MAKE_ARGS} test
;;
esac
RET="$?"
find ${TMPDIR:-/tmp} -path '*_test.*' -name '*.log' -print -exec cat {} \;
;;
install)
${MAKE} ${MAKE_ARGS} install DESTDIR="${BUILDDIR}/destdir"
RET="$?"
cd ${BUILDDIR}/destdir && ls -lR .
;;
distcheck)
${MAKE} ${MAKE_ARGS} distcheck
RET="$?"
;;
esac
if [ "${RET}" != "0" ]; then
Expand Down
4 changes: 4 additions & 0 deletions build/ci/cirrus_ci/Dockerfile.cygwin
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM cirrusci/windowsservercore:2019

RUN choco install -y --no-progress cygwin
RUN C:\tools\cygwin\cygwinsetup.exe -q -P make,autoconf,automake,cmake,gcc-core,binutils,libtool,pkg-config,bison,sharutils,zlib-devel,libbz2-devel,liblzma-devel,liblz4-devel,libiconv-devel,libxml2-devel,libzstd-devel,libssl-devel
3 changes: 3 additions & 0 deletions build/ci/cirrus_ci/Dockerfile.fc29
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM fedora:29

RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel
3 changes: 3 additions & 0 deletions build/ci/cirrus_ci/Dockerfile.fc29.distcheck
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM fedora:29

RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel groff ghostscript
8 changes: 8 additions & 0 deletions build/ci/cirrus_ci/Dockerfile.mingw
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM cirrusci/windowsservercore:2019

RUN choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=User' cmake
RUN choco install -y --no-progress mingw
RUN curl -o zlib-1.2.11.tar.gz https://www.zlib.net/zlib-1.2.11.tar.gz
RUN tar -x -f zlib-1.2.11.tar.gz
RUN cd zlib-1.2.11 && cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE="Release" . && mingw32-make && mingw32-make install
RUN del /f /q /s zlib-1.2.11 zlib-1.2.11.tar.gz
9 changes: 9 additions & 0 deletions build/ci/cirrus_ci/Dockerfile.msvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM cirrusci/windowsservercore:2019

RUN choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=User' cmake
RUN choco install -y --no-progress visualstudio2017community
RUN choco install -y --no-progress visualstudio2017-workload-vctools
RUN curl -o zlib-1.2.11.tar.gz https://www.zlib.net/zlib-1.2.11.tar.gz
RUN tar -x -f zlib-1.2.11.tar.gz
RUN cd zlib-1.2.11 && cmake -G "Visual Studio 15 2017" . && cmake --build . --target ALL_BUILD --config Release && cmake --build . --target INSTALL --config Release
RUN del /f /q /s zlib-1.2.11 zlib-1.2.11.tar.gz
12 changes: 12 additions & 0 deletions build/ci/cirrus_ci/Dockerfile.windows
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM cirrusci/windowsservercore:2019

RUN choco install -y --no-progress mingw
RUN choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=User' cmake
RUN choco install -y --no-progress visualstudio2017community
RUN choco install -y --no-progress visualstudio2017-workload-vctools
RUN curl -o zlib-1.2.11.tar.gz https://www.zlib.net/zlib-1.2.11.tar.gz
RUN tar -x -f zlib-1.2.11.tar.gz
RUN cd zlib-1.2.11 && cmake -G "Visual Studio 15 2017" . && cmake --build . --target ALL_BUILD --config Release && cmake --build . --target INSTALL --config Release
RUN del /f /q /s zlib-1.2.11 zlib-1.2.11.tar.gz
RUN choco install -y --no-progress cygwin
RUN C:\tools\cygwin\cygwinsetup.exe -q -P make,autoconf,automake,cmake,gcc-core,binutils,libtool,pkg-config,bison,sharutils,zlib-devel,libbz2-devel,liblzma-devel,liblz4-devel,libiconv-devel,libxml2-devel,libzstd-devel,libssl-devel
122 changes: 122 additions & 0 deletions build/ci/cirrus_ci/ci.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
@ECHO OFF
SET ZLIB_VERSION=1.2.11
IF NOT "%BE%"=="cygwin-gcc" (
IF NOT "%BE%"=="mingw-gcc" (
IF NOT "%BE%"=="msvc" (
ECHO Environment variable BE must be cygwin-gcc, mingw-gcc or msvc
EXIT /b 1
)
)
)

IF "%1%"=="prepare" (
IF "%BE%"=="cygwin-gcc" (
@ECHO ON
choco install -y --no-progress cygwin || EXIT /b 1
C:\tools\cygwin\cygwinsetup.exe -q -P make,autoconf,automake,cmake,gcc-core,binutils,libtool,pkg-config,bison,sharutils,zlib-devel,libbz2-devel,liblzma-devel,liblz4-devel,libiconv-devel,libxml2-devel,libzstd-devel,libssl-devel || EXIT /b 1
@EXIT /b 0
) ELSE IF "%BE%"=="mingw-gcc" (
@ECHO ON
choco install -y --no-progress mingw || EXIT /b 1
choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=System' cmake || EXIT /b 1
@EXIT /b 0
) ELSE IF "%BE%"=="msvc" (
@ECHO ON
choco install -y --no-progress visualstudio2017community || EXIT /b 1
choco install -y --no-progress visualstudio2017-workload-vctools || EXIT /b 1
choco install -y --no-progress --installargs 'ADD_CMAKE_TO_PATH=System' cmake || EXIT /b 1
)
) ELSE IF "%1"=="deplibs" (
IF "%BE%"=="cygwin-gcc" (
ECHO Skipping on this platform
EXIT /b 0
)
IF NOT EXIST build_ci\libs (
MKDIR build_ci\libs
)
CD build_ci\libs
IF NOT EXIST zlib-%ZLIB_VERSION%.tar.gz (
curl -o zlib-%ZLIB_VERSION%.tar.gz https://www.zlib.net/zlib-%ZLIB_VERSION%.tar.gz
)
IF NOT EXIST zlib-%ZLIB_VERSION% (
tar -x -z -f zlib-%ZLIB_VERSION%.tar.gz
)
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD zlib-%ZLIB_VERSION%
IF "%BE%"=="mingw-gcc" (
cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE="Release" . || EXIT /b 1
mingw32-make || EXIT /b 1
mingw32-make test || EXIT /b 1
mingw32-make install || EXIT /b 1
) ELSE IF "%BE%"=="msvc" (
cmake -G "Visual Studio 15 2017" . || EXIT /b 1
cmake --build . --target ALL_BUILD --config Release || EXIT /b 1
cmake --build . --target RUN_TESTS --config Release || EXIT /b 1
cmake --build . --target INSTALL --config Release || EXIT /b 1
)
) ELSE IF "%1%"=="configure" (
IF "%BE%"=="cygwin-gcc" (
SET BS=cmake
SET CONFIGURE_ARGS=-DENABLE_ACL=OFF
C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a configure" || EXIT /b 1
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
MKDIR build_ci\cmake
CD build_ci\cmake
cmake -G "MinGW Makefiles" ..\.. || EXIT /b 1
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
MKDIR build_ci\cmake
CD build_ci\cmake
cmake -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPE="Release" ..\.. || EXIT /b 1
)
) ELSE IF "%1%"=="build" (
IF "%BE%"=="cygwin-gcc" (
SET BS=cmake
C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a build"
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD build_ci\cmake
mingw32-make || EXIT /b 1
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD build_ci\cmake
cmake --build . --target ALL_BUILD --config Release
)
) ELSE IF "%1%"=="test" (
IF "%BE%"=="cygwin-gcc" (
ECHO "Skipping tests on this platform"
EXIT /b 0
REM SET BS=cmake
REM SET SKIP_TEST_SPARSE=1
REM C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a test"
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
COPY "C:\Program Files (x86)\zlib\bin\libzlib.dll" build_ci\cmake\bin\
CD build_ci\cmake
SET SKIP_TEST_SPARSE=1
mingw32-make test
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
ECHO "Skipping tests on this platform"
EXIT /b 0
REM CD build_ci\cmake
REM cmake --build . --target RUN_TESTS --config Release
)
) ELSE IF "%1%"=="install" (
IF "%BE%"=="cygwin-gcc" (
SET BS=cmake
C:\tools\cygwin\bin\bash.exe --login -c "cd '%cd%'; ./build/ci/build.sh -a install"
) ELSE IF "%BE%"=="mingw-gcc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
CD build_ci\cmake
mingw32-make install DESTDIR=%cd%\destdir
) ELSE IF "%BE%"=="msvc" (
SET PATH=%PATH%;C:\Program Files\cmake\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin
cmake --build . --target INSTALL --config Release
)
) ELSE (
ECHO "Usage: %0% prepare|deplibs|configure|build|test|install"
@EXIT /b 0
)
@EXIT /b 0
56 changes: 56 additions & 0 deletions build/ci/cirrus_ci/ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/sh
UNAME=`uname`
if [ "$1" = "prepare" ]
then
if [ "${UNAME}" = "FreeBSD" ]
then
set -x -e
sed -i.bak -e 's,pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly,pkg+http://pkg.FreeBSD.org/\${ABI}/latest,' /etc/pkg/FreeBSD.conf
mount -u -o acls /
mkdir /tmp_acl_nfsv4
MD=`mdconfig -a -t swap -s 128M`
newfs /dev/$MD
tunefs -N enable /dev/$MD
mount /dev/$MD /tmp_acl_nfsv4
chmod 1777 /tmp_acl_nfsv4
pkg install -y autoconf automake cmake libiconv libtool pkgconf expat libxml2 liblz4 zstd
elif [ "${UNAME}" = "Darwin" ]
then
set -x -e
brew update > /dev/null
for pkg in autoconf automake libtool pkg-config cmake xz lz4 zstd
do
brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg
done
elif [ "${UNAME}" = "Linux" ]
then
if [ -f "/etc/debian_version" ]
then
apt-get -y update
apt-get -y install build-essential locales automake libtool bison sharutils pkgconf libacl1-dev libbz2-dev libzip-dev zlib1g-dev liblzma-dev liblz4-dev libzstd-dev libssl-dev lrzip cmake
elif [ -f "/etc/fedora-release" ]
then
dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel
fi
fi
elif [ "$1" = "test" ]
then
if [ "${UNAME}" = "FreeBSD" ]
then
set -e
echo "Additional NFSv4 ACL tests"
CURDIR=`pwd`
if [ "${BS}" = "cmake" ]
then
BIN_SUBDIR="bin"
else
BIN_SUBDIR=.
fi
BUILDDIR="${CURDIR}/build_ci/${BS}"
cd "$BUILDDIR"
TMPDIR=/tmp_acl_nfsv4 ${BIN_SUBDIR}/libarchive_test -r "${CURDIR}/libarchive/test" -v test_acl_platform_nfs4
fi
else
echo "Usage $0 prepare | test_nfsv4_acls"
exit 1
fi
File renamed without changes.
33 changes: 33 additions & 0 deletions build/ci/travis_ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh
set -e
UNAME=`uname`
CURDIR=`pwd`
SRCDIR="${SRCDIR:-`pwd`}"
if [ -z "${BUILDDIR}" ]; then
BUILDDIR="${CURDIR}/build_ci/${BS}"
fi
mkdir -p "${BUILDDIR}"
cd "${BUILDDIR}"
case "$UNAME" in
MSYS*)
if [ "${BS}" = "msbuild" ]; then
set -x
cmake -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPE="Release" "${SRCDIR}"
cmake --build . --target ALL_BUILD
# Until fixed, we don't run tests on Windows (lots of fails + timeout)
#export SKIP_TEST_FUZZ=1
#cmake --build . --target RUN_TESTS
set +x
elif [ "${BS}" = "mingw" ]; then
set -x
cmake -G "MSYS Makefiles" -D CMAKE_C_COMPILER="${CC}" -D CMAKE_MAKE_PROGRAM="mingw32-make" -D CMAKE_BUILD_TYPE="Release" "${SRCDIR}"
mingw32-make
#export SKIP_TEST_FUZZ=1
#mingw32-make test
set +x
else
echo "Unknown or unspecified build type: ${BS}"
exit 1
fi
;;
esac
9 changes: 9 additions & 0 deletions build/cmake/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,12 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `bz2' library (-lbz2). */
#cmakedefine HAVE_LIBBZ2 1

/* Define to 1 if you have the `b2' library (-lb2). */
#cmakedefine HAVE_LIBB2 1

/* Define to 1 if you have the <blake2.h> header file. */
#cmakedefine HAVE_BLAKE2_H 1

/* Define to 1 if you have the `charset' library (-lcharset). */
#cmakedefine HAVE_LIBCHARSET 1

Expand Down Expand Up @@ -1105,6 +1111,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1

/* Define to 1 if you have the `unlinkat' function. */
#cmakedefine HAVE_UNLINKAT 1

/* Define to 1 if you have the `unsetenv' function. */
#cmakedefine HAVE_UNSETENV 1

Expand Down
2 changes: 1 addition & 1 deletion build/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3003003
3004000
23 changes: 14 additions & 9 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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.3.3])
m4_define([LIBARCHIVE_VERSION_N],[3003003])
m4_define([LIBARCHIVE_VERSION_S],[3.4.0])
m4_define([LIBARCHIVE_VERSION_N],[3004000])

dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
Expand Down Expand Up @@ -340,6 +340,16 @@ if test "x$with_bz2lib" != "xno"; then
esac
fi

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)
fi

AM_CONDITIONAL([INC_BLAKE2], [test "x$ac_cv_lib_b2_blake2sp_init" != "xyes"])

AC_ARG_WITH([iconv],
AS_HELP_STRING([--without-iconv], [Don't try to link against iconv]))

Expand Down Expand Up @@ -626,7 +636,7 @@ AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat])
AC_CHECK_FUNCS([readpassphrase])
AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork])
AC_CHECK_FUNCS([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 _localtime64_s _mkgmtime64])
Expand Down Expand Up @@ -1153,12 +1163,7 @@ if test "x$with_openssl" != "xno"; then
CRYPTO_CHECK(SHA256, OPENSSL, sha256)
CRYPTO_CHECK(SHA384, OPENSSL, sha384)
CRYPTO_CHECK(SHA512, OPENSSL, sha512)
if test "x$found_OPENSSL" != "xyes"; then
LIBS=$saved_LIBS
else
AC_CHECK_FUNCS([PKCS5_PBKDF2_HMAC_SHA1])
fi
AC_CHECK_LIB(crypto,EVP_CIPHER_CTX_init)
AC_CHECK_FUNCS([PKCS5_PBKDF2_HMAC_SHA1])
fi

# Probe libmd AFTER OpenSSL/libcrypto.
Expand Down
2 changes: 1 addition & 1 deletion contrib/android/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ libarchive_src_files := libarchive/archive_acl.c \
libarchive/archive_string.c \
libarchive/archive_string_sprintf.c \
libarchive/archive_util.c \
libarchive/archive_version_details.c \
libarchive/archive_virtual.c \
libarchive/archive_write.c \
libarchive/archive_write_disk_acl.c \
libarchive/archive_write_disk_posix.c \
libarchive/archive_write_disk_set_standard_lookup.c \
libarchive/archive_write_open_fd.c \
Expand Down
218 changes: 218 additions & 0 deletions contrib/archivetest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/*-
* Copyright (c) 2019 Martin Matuska
* 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.
*/

/*
* Archivetest verifies reading archives with libarchive
*
* It may be used to reproduce failures in testcases discovered by OSS-Fuzz
* https://github.com/google/oss-fuzz/blob/master/projects/libarchive
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <archive.h>
#include <archive_entry.h>

const char *errnostr(int errno)
{
char *estr;
switch(errno) {
case ARCHIVE_EOF:
estr = "ARCHIVE_EOF";
break;
case ARCHIVE_OK:
estr = "ARCHIVE_OK";
break;
case ARCHIVE_WARN:
estr = "ARCHIVE_WARN";
break;
case ARCHIVE_RETRY:
estr = "ARCHIVE_RETRY";
break;
case ARCHIVE_FAILED:
estr = "ARCHIVE_FAILED";
break;
case ARCHIVE_FATAL:
estr = "ARCHIVE_FATAL";
break;
default:
estr = "Unknown";
break;
}
return (estr);
}

void usage(const char *prog)
{
fprintf(stderr, "Usage: %s [-f filename] [-h] [-q] [-s]\n", prog);
}

void printhelp()
{
fprintf(stdout, "archivetest: verify reading archives with "
"libarchive\n\n"
"Options:\n"
" -f filename Filename to verify\n"
" -h Show this help\n"
" -q Quiet mode\n"
" -s Verify only headers (skip data)\n\n"
"If no filename is specified, data is read from standard input.\n"
"\n%s\n", archive_version_details());
}

int v_print(int verbose, const char *format, ...)
{
int r = 0;

if (verbose) {
va_list args;

va_start(args, format);
r = vfprintf(stdout, format, args);
va_end(args);
}
return (r);
}

int main(int argc, char *argv[])
{
struct archive *a;
struct archive_entry *entry;
char *filename;
const char *p;
char buffer[4096];
int c;
int v, skip_data;
int r = ARCHIVE_OK;
int format_printed;

filename = NULL;
skip_data = 0;
v = 1;

while ((c = getopt (argc, argv, "f:hqs")) != -1) {
switch (c) {
case 'f':
filename = optarg;
break;
case 'h':
printhelp();
exit(0);
case 'q':
v = 0;
break;
case 's':
skip_data = 1;
break;
case '?':
if (optopt == 'f')
fprintf(stderr, "Option -%c requires "
"an argument.\n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option '-%c'"
".\n", optopt);
else
fprintf(stderr, "Unknown option "
"character '\\x%x'.\n", optopt);
usage(argv[0]);
default:
exit(1);
}
}

a = archive_read_new();

archive_read_support_filter_all(a);
archive_read_support_format_all(a);

v_print(v, "Data source: ");

if (filename == NULL) {
v_print(v, "standard input\n");
r = archive_read_open_fd(a, STDIN_FILENO, 4096);
} else {
v_print(v, "filename: %s\n", filename);
r = archive_read_open_filename(a, filename, 4096);
}

if (r != ARCHIVE_OK) {
archive_read_free(a);
fprintf(stderr, "Invalid or unsupported data source\n");
exit(1);
}

format_printed = 0;
c = 1;

while (1) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_FATAL) {
v_print(v, "Entry %d: fatal error reading "
"header\n", c);
break;
}
if (!format_printed) {
v_print(v, "Filter: %s\nFormat: %s\n",
archive_filter_name(a, 0), archive_format_name(a));
format_printed = 1;
}
if (r == ARCHIVE_RETRY)
continue;
if (r == ARCHIVE_EOF)
break;
p = archive_entry_pathname(entry);
v_print(v, "Entry %d: %s, pathname", c, errnostr(r));
if (p == NULL || p[0] == '\0')
v_print(v, " unreadable");
else
v_print(v, ": %s", p);
v_print(v, ", data: ");
if (skip_data) {
v_print(v, "skipping");
} else {
while ((r = archive_read_data(a, buffer, 4096) > 0))
;
if (r == ARCHIVE_FATAL) {
v_print(v, "ERROR\nError string: %s\n",
archive_error_string(a));
break;
}
v_print(v, "OK");
}
v_print(v, "\n");
c++;
}

v_print(v, "Last return code: %s (%d)\n", errnostr(r), r);
if (r == ARCHIVE_EOF || r == ARCHIVE_OK) {
archive_read_free(a);
exit(0);
}
v_print(v, "Error string: %s\n", archive_error_string(a));
archive_read_free(a);
exit(2);
}
249 changes: 180 additions & 69 deletions contrib/libarchive.spec
Original file line number Diff line number Diff line change
@@ -1,105 +1,216 @@
Summary: Library to create and read several different archive formats
Name: libarchive
Version: 3.1.2
Release: 1
Name: {{{ git_name }}}
Version: {{{ git_version lead=3 follow=4 }}}
Release: 1%{?dist}
Summary: A library for handling streaming archive formats

License: BSD
Group: Libraries
Source0: http://libarchive.org/downloads/%{name}-%{version}.tar.gz
URL: http:/libarchive.org/
Requires: glibc
Requires: zlib
Requires: bzip2
URL: http://www.libarchive.org/
Source: {{{ git_pack }}}

VCS: {{{ git_vcs }}}

BuildRequires: automake
BuildRequires: bison
BuildRequires: bzip2-devel
BuildRequires: e2fsprogs-devel
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: gawk
BuildRequires: libacl-devel
BuildRequires: libattr-devel
BuildRequires: libtool
BuildRequires: libxml2-devel
BuildRequires: libzstd-devel
BuildRequires: lz4-devel
BuildRequires: lzo-devel
BuildRequires: openssl-devel
BuildRequires: sharutils
BuildRequires: xz-devel
BuildRequires: zlib-devel
BuildRequires: bzip2
BuildRoot: %{_tmppath}/%{name}-%{version}-build

%description
Libarchive is a programming library that can create and read several
different streaming archive formats, including most popular TAR
variants and several CPIO formats. It can also write SHAR archives.
Libarchive is a programming library that can create and read several different
streaming archive formats, including most popular tar variants, several cpio
formats, and both BSD and GNU ar variants. It can also write shar archives and
read ISO9660 CDROM images and ZIP archives.


%package devel
Summary: Header files for libarchive library
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
Summary: Development files for %{name}
Requires: %{name}%{?_isa} = %{version}-%{release}

%description devel
Header files for libarchive library.

%package static
Summary: Static libarchive library
Group: Development/Libraries
Requires: %{name}-devel = %{version}-%{release}
The %{name}-devel package contains libraries and header files for
developing applications that use %{name}.

%description static
Static libarchive library.

%package -n bsdtar
Summary: bsdtar - tar(1) implementation based on libarchive
Group: Applications/Archiving
Requires: %{name} = %{version}-%{release}
Summary: Manipulate tape archives
Requires: %{name}%{?_isa} = %{version}-%{release}

%description -n bsdtar
bsdtar - tar(1) implementation based on libarchive.
The bsdtar package contains standalone bsdtar utility split off regular
libarchive packages.


%package -n bsdcpio
Summary: bsdcpio - cpio(1) implementation based on libarchive
Group: Applications/Archiving
Requires: %{name} = %{version}-%{release}
Summary: Copy files to and from archives
Requires: %{name}%{?_isa} = %{version}-%{release}

%description -n bsdcpio
bsdcpio - cpio(1) implementation based on libarchive
The bsdcpio package contains standalone bsdcpio utility split off regular
libarchive packages.


%package -n bsdcat
Summary: Expand files to standard output
Requires: %{name}%{?_isa} = %{version}-%{release}

%description -n bsdcat
The bsdcat program typically takes a filename as an argument or reads standard
input when used in a pipe. In both cases decompressed data it written to
standard output.


%prep
%setup -q
{{{ git_setup_macro }}}
%autosetup -p1


%build
mkdir -p %{buildroot}
./configure \
--prefix=%{_prefix} \
--libexecdir=%{_libexecdir} \
--libdir=%{_libdir} \
--mandir=%{_mandir} \
--infodir=%{_infodir} \
--enable-shared=yes \
--enable-static=yes \
| tee %{buildroot}/config.log
make | tee %{buildroot}/make.log
build/autogen.sh
%configure --disable-static --without-nettle LT_SYS_LIBRARY_PATH=%_libdir
%make_build


%install
[ "%buildroot" != "/" ] && [ -d %buildroot ] && rm -rf %buildroot;
make DESTDIR=%buildroot install
make install DESTDIR=$RPM_BUILD_ROOT
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'

# rhbz#1294252
replace ()
{
filename=$1
file=`basename "$filename"`
binary=${file%%.*}
pattern=${binary##bsd}

awk "
# replace the topic
/^.Dt ${pattern^^} 1/ {
print \".Dt ${binary^^} 1\";
next;
}
# replace the first occurence of \"$pattern\" by \"$binary\"
!stop && /^.Nm $pattern/ {
print \".Nm $binary\" ;
stop = 1 ;
next;
}
# print remaining lines
1;
" "$filename" > "$filename.new"
mv "$filename".new "$filename"
}

for manpage in bsdtar.1 bsdcpio.1
do
installed_manpage=`find "$RPM_BUILD_ROOT" -name "$manpage"`
replace "$installed_manpage"
done


%check
%if %{with check}
logfiles ()
{
find -name '*_test.log' -or -name test-suite.log
}

tempdirs ()
{
cat `logfiles` \
| awk "match(\$0, /[^[:space:]]*`date -I`[^[:space:]]*/) { print substr(\$0, RSTART, RLENGTH); }" \
| sort | uniq
}

cat_logs ()
{
for i in `logfiles`
do
echo "=== $i ==="
cat "$i"
done
}

run_testsuite ()
{
rc=0
%make_build check -j1 || {
# error happened - try to extract in koji as much info as possible
cat_logs

for i in `tempdirs`; do
if test -d "$i" ; then
find $i -printf "%p\n ~> a: %a\n ~> c: %c\n ~> t: %t\n ~> %s B\n"
cat $i/*.log
fi
done
return 1
}
cat_logs
}

# On a ppc/ppc64 is some race condition causing 'make check' fail on ppc
# when both 32 and 64 builds are done in parallel on the same machine in
# koji. Try to run once again if failed.
%ifarch ppc
run_testsuite || run_testsuite
%else
run_testsuite
%endif
%endif

%clean
rm -fr %buildroot

%files
%{_libdir}/libarchive.so*

%files static
%{_libdir}/libarchive.a
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc NEWS README.md
%{_libdir}/libarchive.so.13*
%{_mandir}/*/cpio.*
%{_mandir}/*/mtree.*
%{_mandir}/*/tar.*

%files devel
%{_libdir}/pkgconfig/libarchive.pc
%{_libdir}/libarchive.la
%{_includedir}/*.h
%doc %{_mandir}/man3/*
%doc %{_mandir}/man5/*
%{_mandir}/*/archive*
%{_mandir}/*/libarchive*
%{_libdir}/libarchive.so
%{_libdir}/pkgconfig/libarchive.pc

%files -n bsdtar
%attr(755,root,root) %{_bindir}/bsdtar
%doc %{_mandir}/man1/bsdtar.1*
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc NEWS README.md
%{_bindir}/bsdtar
%{_mandir}/*/bsdtar*

%files -n bsdcpio
%attr(755,root,root) %{_bindir}/bsdcpio
%doc %{_mandir}/man1/bsdcpio.1*
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc NEWS README.md
%{_bindir}/bsdcpio
%{_mandir}/*/bsdcpio*

%files -n bsdcat
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc NEWS README.md
%{_bindir}/bsdcat
%{_mandir}/*/bsdcat*



%changelog
* Wed May 01 2013 Nikolai Lifanov <lifanov@mail.lifanov.com> - 3.1.2-1
- Initial package
- contrib/libarchive.spec by PLD team overhaul
- Added "bsdcpio" package
- Fixed build on x86_64 platform
* Thu Mar 28 2019 Pavel Raiskup <praiskup@redhat.com> - 3.3.3-7
- simplify libtool hacks

{{ git_changelog }}
3 changes: 1 addition & 2 deletions contrib/shar/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,8 +530,7 @@ tree_close(struct tree *t)
/* Release anything remaining in the stack. */
while (t->stack != NULL)
tree_pop(t);
if (t->buff)
free(t->buff);
free(t->buff);
/* chdir() back to where we started. */
if (t->initialDirFd >= 0) {
fchdir(t->initialDirFd);
Expand Down
19 changes: 14 additions & 5 deletions cpio/cpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ main(int argc, char *argv[])
struct cpio _cpio; /* Allocated on stack. */
struct cpio *cpio;
const char *errmsg;
char *tptr;
int uid, gid;
int opt;
int opt, t;

cpio = &_cpio;
memset(cpio, 0, sizeof(*cpio));
Expand Down Expand Up @@ -204,9 +205,15 @@ main(int argc, char *argv[])
cpio->add_filter = opt;
break;
case 'C': /* NetBSD/OpenBSD */
cpio->bytes_per_block = atoi(cpio->argument);
if (cpio->bytes_per_block <= 0)
lafe_errc(1, 0, "Invalid blocksize %s", cpio->argument);
errno = 0;
tptr = NULL;
t = (int)strtol(cpio->argument, &tptr, 10);
if (errno || t <= 0 || *(cpio->argument) == '\0' ||
tptr == NULL || *tptr != '\0') {
lafe_errc(1, 0, "Invalid blocksize: %s",
cpio->argument);
}
cpio->bytes_per_block = t;
break;
case 'c': /* POSIX 1997 */
cpio->format = "odc";
Expand Down Expand Up @@ -748,8 +755,10 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
}
if (cpio->option_rename)
destpath = cpio_rename(destpath);
if (destpath == NULL)
if (destpath == NULL) {
archive_entry_free(entry);
return (0);
}
archive_entry_copy_pathname(entry, destpath);

/*
Expand Down
4 changes: 2 additions & 2 deletions cpio/test/test_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ verify_files(const char *msg)

/* Symlink */
if (canSymlink())
assertIsSymlink("symlink", "file");
assertIsSymlink("symlink", "file", 0);

/* Another file with 1 link and different permissions. */
failure(msg);
Expand Down Expand Up @@ -173,7 +173,7 @@ DEFINE_TEST(test_basic)

/* Symlink to above file. */
if (canSymlink()) {
assertMakeSymlink("symlink", "file");
assertMakeSymlink("symlink", "file", 0);
fprintf(filelist, "symlink\n");
if (is_LargeInode("symlink")) {
strncat(result,
Expand Down
7 changes: 6 additions & 1 deletion cpio/test/test_format_newc.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ DEFINE_TEST(test_format_newc)

/* "symlink" */
if (canSymlink()) {
assertMakeSymlink("symlink", "file1");
assertMakeSymlink("symlink", "file1", 0);
fprintf(list, "symlink\n");
}

Expand Down Expand Up @@ -233,7 +233,12 @@ 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)
/* Mode: Group members bits and others bits do not work. */
assertEqualInt(0xa180, from_hex(e + 14, 8) & 0xffc0);
#else
assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
#endif
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
assertEqualMem(e + 38, "00000001", 8); /* nlink */
Expand Down
2 changes: 1 addition & 1 deletion cpio/test/test_gcpio_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ unpack_test(const char *from, const char *options, const char *se)

/* Symlink */
if (canSymlink())
assertIsSymlink("symlink", "file");
assertIsSymlink("symlink", "file", 0);

/* dir */
assertIsDir("dir", 0775);
Expand Down
14 changes: 9 additions & 5 deletions cpio/test/test_option_L_upper.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_L.c,v 1.2 2008/08/24 06:21
* tests won't run on Windows. */
#if defined(_WIN32) && !defined(__CYGWIN__)
#define CAT "type"
#define SEP "\\"
#else
#define CAT "cat"
#define SEP "/"
#endif

DEFINE_TEST(test_option_L_upper)
Expand All @@ -51,7 +53,7 @@ DEFINE_TEST(test_option_L_upper)
fprintf(filelist, "file\n");

/* Symlink to above file. */
assertMakeSymlink("symlink", "file");
assertMakeSymlink("symlink", "file", 0);
fprintf(filelist, "symlink\n");

fclose(filelist);
Expand All @@ -61,7 +63,7 @@ DEFINE_TEST(test_option_L_upper)
assertTextFileContents("1 block\n", "copy.err");

failure("Regular -p without -L should preserve symlinks.");
assertIsSymlink("copy/symlink", NULL);
assertIsSymlink("copy/symlink", NULL, 0);

r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
assertEqualInt(r, 0);
Expand All @@ -77,13 +79,14 @@ DEFINE_TEST(test_option_L_upper)

assertMakeDir("unpack", 0755);
assertChdir("unpack");
r = systemf(CAT " ../archive.out | %s -i >unpack.out 2>unpack.err", testprog);
r = systemf(CAT " .." SEP "archive.out | %s -i >unpack.out 2>unpack.err", testprog);

failure("Error invoking %s -i", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "unpack.err");
assertChdir("..");

assertIsSymlink("unpack/symlink", NULL);
assertIsSymlink("unpack/symlink", NULL, 0);

r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
failure("Error invoking %s -oL", testprog);
Expand All @@ -92,7 +95,8 @@ DEFINE_TEST(test_option_L_upper)

assertMakeDir("unpack-L", 0755);
assertChdir("unpack-L");
r = systemf(CAT " ../archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
r = systemf(CAT " .." SEP "archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);

failure("Error invoking %s -i < archive-L.out", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "unpack-L.err");
Expand Down
5 changes: 5 additions & 0 deletions cpio/test/test_option_a.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,13 @@ 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)
times.actime = 86400;
times.modtime = 86400;
#else
times.actime = 1;
times.modtime = 3;
#endif
assertEqualInt(0, utime(files[i].name, &times));

/* Record whatever atime the file ended up with. */
Expand Down
2 changes: 1 addition & 1 deletion cpio/test/test_option_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ DEFINE_TEST(test_option_c)

/* "symlink" */
if (canSymlink()) {
assertMakeSymlink("symlink", "file");
assertMakeSymlink("symlink", "file", 0);
fprintf(filelist, "symlink\n");
}

Expand Down
8 changes: 4 additions & 4 deletions cpio/test/test_option_t.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ DEFINE_TEST(test_option_t)
setlocale(LC_ALL, "");
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
strftime(date2, sizeof(date), "%b %d %Y", localtime(&mtime));
_snprintf(date, sizeof(date)-1, "%12s file", date2);
strftime(date2, sizeof(date2)-1, "%b %d %Y", localtime(&mtime));
_snprintf(date, sizeof(date)-1, "%12.12s file", date2);
#else
strftime(date2, sizeof(date), "%b %e %Y", localtime(&mtime));
snprintf(date, sizeof(date)-1, "%12s file", date2);
strftime(date2, sizeof(date2)-1, "%b %e %Y", localtime(&mtime));
snprintf(date, sizeof(date)-1, "%12.12s file", date2);
#endif
assertEqualMem(p + 42, date, strlen(date));
free(p);
Expand Down
10 changes: 10 additions & 0 deletions libarchive/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ SET(libarchive_SOURCES
archive_platform_acl.h
archive_platform_xattr.h
archive_ppmd_private.h
archive_ppmd8.c
archive_ppmd8_private.h
archive_ppmd7.c
archive_ppmd7_private.h
archive_private.h
Expand Down Expand Up @@ -100,6 +102,7 @@ SET(libarchive_SOURCES
archive_read_support_format_lha.c
archive_read_support_format_mtree.c
archive_read_support_format_rar.c
archive_read_support_format_rar5.c
archive_read_support_format_raw.c
archive_read_support_format_tar.c
archive_read_support_format_warc.c
Expand Down Expand Up @@ -167,6 +170,7 @@ SET(libarchive_MANS
archive_entry.3
archive_entry_acl.3
archive_entry_linkify.3
archive_entry_misc.3
archive_entry_paths.3
archive_entry_perms.3
archive_entry_stat.3
Expand Down Expand Up @@ -215,6 +219,11 @@ IF(WIN32 AND NOT CYGWIN)
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
ENDIF(WIN32 AND NOT CYGWIN)

IF(ARCHIVE_BLAKE2)
LIST(APPEND libarchive_SOURCES archive_blake2sp_ref.c)
LIST(APPEND libarchive_SOURCES archive_blake2s_ref.c)
ENDIF(ARCHIVE_BLAKE2)

IF(ARCHIVE_ACL_DARWIN)
LIST(APPEND libarchive_SOURCES archive_disk_acl_darwin.c)
ELSEIF(ARCHIVE_ACL_FREEBSD)
Expand All @@ -227,6 +236,7 @@ ENDIF()

# Libarchive is a shared library
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})

Expand Down
8 changes: 6 additions & 2 deletions libarchive/archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 3003003
#define ARCHIVE_VERSION_NUMBER 3004000

#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
Expand Down Expand Up @@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.3.3"
#define ARCHIVE_VERSION_ONLY_STRING "3.4.0"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);

Expand Down Expand Up @@ -340,6 +340,7 @@ typedef const char *archive_passphrase_callback(struct archive *,
#define ARCHIVE_FORMAT_RAR 0xD0000
#define ARCHIVE_FORMAT_7ZIP 0xE0000
#define ARCHIVE_FORMAT_WARC 0xF0000
#define ARCHIVE_FORMAT_RAR_V5 0x100000

/*
* Codes returned by archive_read_format_capabilities().
Expand Down Expand Up @@ -449,6 +450,7 @@ __LA_DECL int archive_read_support_format_iso9660(struct archive *);
__LA_DECL int archive_read_support_format_lha(struct archive *);
__LA_DECL int archive_read_support_format_mtree(struct archive *);
__LA_DECL int archive_read_support_format_rar(struct archive *);
__LA_DECL int archive_read_support_format_rar5(struct archive *);
__LA_DECL int archive_read_support_format_raw(struct archive *);
__LA_DECL int archive_read_support_format_tar(struct archive *);
__LA_DECL int archive_read_support_format_warc(struct archive *);
Expand Down Expand Up @@ -1093,6 +1095,8 @@ __LA_DECL int archive_match_excluded(struct archive *,
*/
__LA_DECL int archive_match_path_excluded(struct archive *,
struct archive_entry *);
/* Control recursive inclusion of directory content when directory is included. Default on. */
__LA_DECL int archive_match_set_inclusion_recursion(struct archive *, int);
/* Add exclusion pathname pattern. */
__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *);
__LA_DECL int archive_match_exclude_pattern_w(struct archive *,
Expand Down
88 changes: 57 additions & 31 deletions libarchive/archive_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,10 @@ archive_acl_clear(struct archive_acl *acl)
free(acl->acl_head);
acl->acl_head = ap;
}
if (acl->acl_text_w != NULL) {
free(acl->acl_text_w);
acl->acl_text_w = NULL;
}
if (acl->acl_text != NULL) {
free(acl->acl_text);
acl->acl_text = NULL;
}
free(acl->acl_text_w);
acl->acl_text_w = NULL;
free(acl->acl_text);
acl->acl_text = NULL;
acl->acl_p = NULL;
acl->acl_types = 0;
acl->acl_state = 0; /* Not counting. */
Expand Down Expand Up @@ -324,14 +320,10 @@ acl_new_entry(struct archive_acl *acl,
return (NULL);
}

if (acl->acl_text_w != NULL) {
free(acl->acl_text_w);
acl->acl_text_w = NULL;
}
if (acl->acl_text != NULL) {
free(acl->acl_text);
acl->acl_text = NULL;
}
free(acl->acl_text_w);
acl->acl_text_w = NULL;
free(acl->acl_text);
acl->acl_text = NULL;

/*
* If there's a matching entry already in the list, overwrite it.
Expand Down Expand Up @@ -753,8 +745,10 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
wname, ap->permset, id);
count++;
} else if (r < 0 && errno == ENOMEM)
} else if (r < 0 && errno == ENOMEM) {
free(ws);
return (NULL);
}
}

/* Add terminating character */
Expand Down Expand Up @@ -975,8 +969,10 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
prefix = NULL;
r = archive_mstring_get_mbs_l(
&ap->name, &name, &len, sc);
if (r != 0)
if (r != 0) {
free(s);
return (NULL);
}
if (count > 0)
*p++ = separator;
if (name == NULL ||
Expand Down Expand Up @@ -1581,17 +1577,29 @@ next_field_w(const wchar_t **wp, const wchar_t **start,

/* Scan for the separator. */
while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
**wp != L'\n') {
**wp != L'\n' && **wp != L'#') {
(*wp)++;
}
*sep = **wp;

/* Trim trailing whitespace to locate end of field. */
*end = *wp - 1;
while (**end == L' ' || **end == L'\t' || **end == L'\n') {
(*end)--;
/* Locate end of field, trim trailing whitespace if necessary */
if (*wp == *start) {
*end = *wp;
} else {
*end = *wp - 1;
while (**end == L' ' || **end == L'\t' || **end == L'\n') {
(*end)--;
}
(*end)++;
}

/* Handle in-field comments */
if (*sep == L'#') {
while (**wp != L'\0' && **wp != L',' && **wp != L'\n') {
(*wp)++;
}
*sep = **wp;
}
(*end)++;

/* Adjust scanner location. */
if (**wp != L'\0')
Expand Down Expand Up @@ -1642,7 +1650,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
ret = ARCHIVE_OK;
types = 0;

while (text != NULL && *text != '\0') {
while (text != NULL && *text != '\0') {
/*
* Parse the fields out of the next entry,
* advance 'text' to start of next entry.
Expand Down Expand Up @@ -1707,6 +1715,11 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
st = field[n].start + 1;
len = field[n].end - field[n].start;

if (len == 0) {
ret = ARCHIVE_WARN;
continue;
}

switch (*s) {
case 'u':
if (len == 1 || (len == 4
Expand Down Expand Up @@ -2053,17 +2066,30 @@ next_field(const char **p, const char **start,
*start = *p;

/* Scan for the separator. */
while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n') {
while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
**p != '#') {
(*p)++;
}
*sep = **p;

/* Trim trailing whitespace to locate end of field. */
*end = *p - 1;
while (**end == ' ' || **end == '\t' || **end == '\n') {
(*end)--;
/* Locate end of field, trim trailing whitespace if necessary */
if (*p == *start) {
*end = *p;
} else {
*end = *p - 1;
while (**end == ' ' || **end == '\t' || **end == '\n') {
(*end)--;
}
(*end)++;
}

/* Handle in-field comments */
if (*sep == '#') {
while (**p != '\0' && **p != ',' && **p != '\n') {
(*p)++;
}
*sep = **p;
}
(*end)++;

/* Adjust scanner location. */
if (**p != '\0')
Expand Down
194 changes: 194 additions & 0 deletions libarchive/archive_blake2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_H
#define BLAKE2_H

#include <stddef.h>
#include <stdint.h>

#if defined(_MSC_VER)
#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
#else
#define BLAKE2_PACKED(x) x __attribute__((packed))
#endif

#if defined(__cplusplus)
extern "C" {
#endif

enum blake2s_constant
{
BLAKE2S_BLOCKBYTES = 64,
BLAKE2S_OUTBYTES = 32,
BLAKE2S_KEYBYTES = 32,
BLAKE2S_SALTBYTES = 8,
BLAKE2S_PERSONALBYTES = 8
};

enum blake2b_constant
{
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16
};

typedef struct blake2s_state__
{
uint32_t h[8];
uint32_t t[2];
uint32_t f[2];
uint8_t buf[BLAKE2S_BLOCKBYTES];
size_t buflen;
size_t outlen;
uint8_t last_node;
} blake2s_state;

typedef struct blake2b_state__
{
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[BLAKE2B_BLOCKBYTES];
size_t buflen;
size_t outlen;
uint8_t last_node;
} blake2b_state;

typedef struct blake2sp_state__
{
blake2s_state S[8][1];
blake2s_state R[1];
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
size_t buflen;
size_t outlen;
} blake2sp_state;

typedef struct blake2bp_state__
{
blake2b_state S[4][1];
blake2b_state R[1];
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
size_t buflen;
size_t outlen;
} blake2bp_state;

BLAKE2_PACKED(struct blake2s_param__
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint32_t node_offset; /* 12 */
uint16_t xof_length; /* 14 */
uint8_t node_depth; /* 15 */
uint8_t inner_length; /* 16 */
/* uint8_t reserved[0]; */
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
});

typedef struct blake2s_param__ blake2s_param;

BLAKE2_PACKED(struct blake2b_param__
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint32_t node_offset; /* 12 */
uint32_t xof_length; /* 16 */
uint8_t node_depth; /* 17 */
uint8_t inner_length; /* 18 */
uint8_t reserved[14]; /* 32 */
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
});

typedef struct blake2b_param__ blake2b_param;

typedef struct blake2xs_state__
{
blake2s_state S[1];
blake2s_param P[1];
} blake2xs_state;

typedef struct blake2xb_state__
{
blake2b_state S[1];
blake2b_param P[1];
} blake2xb_state;

/* Padded structs result in a compile-time error */
enum {
BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),
BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)
};

/* Streaming API */
int blake2s_init( blake2s_state *S, size_t outlen );
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
int blake2s_update( blake2s_state *S, const void *in, size_t inlen );
int blake2s_final( blake2s_state *S, void *out, size_t outlen );

int blake2b_init( blake2b_state *S, size_t outlen );
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
int blake2b_update( blake2b_state *S, const void *in, size_t inlen );
int blake2b_final( blake2b_state *S, void *out, size_t outlen );

int blake2sp_init( blake2sp_state *S, size_t outlen );
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );
int blake2sp_final( blake2sp_state *S, void *out, size_t outlen );

int blake2bp_init( blake2bp_state *S, size_t outlen );
int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );
int blake2bp_final( blake2bp_state *S, void *out, size_t outlen );

/* Variable output length API */
int blake2xs_init( blake2xs_state *S, const size_t outlen );
int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );
int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );
int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);

int blake2xb_init( blake2xb_state *S, const size_t outlen );
int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );
int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );
int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);

/* Simple API */
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );

int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );

int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );

/* This is simply an alias for blake2b */
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );

#if defined(__cplusplus)
}
#endif

#endif
160 changes: 160 additions & 0 deletions libarchive/archive_blake2_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_IMPL_H
#define BLAKE2_IMPL_H

#include <stdint.h>
#include <string.h>

#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
#if defined(_MSC_VER)
#define BLAKE2_INLINE __inline
#elif defined(__GNUC__)
#define BLAKE2_INLINE __inline__
#else
#define BLAKE2_INLINE
#endif
#else
#define BLAKE2_INLINE inline
#endif

static BLAKE2_INLINE uint32_t load32( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint32_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return (( uint32_t )( p[0] ) << 0) |
(( uint32_t )( p[1] ) << 8) |
(( uint32_t )( p[2] ) << 16) |
(( uint32_t )( p[3] ) << 24) ;
#endif
}

static BLAKE2_INLINE uint64_t load64( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint64_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return (( uint64_t )( p[0] ) << 0) |
(( uint64_t )( p[1] ) << 8) |
(( uint64_t )( p[2] ) << 16) |
(( uint64_t )( p[3] ) << 24) |
(( uint64_t )( p[4] ) << 32) |
(( uint64_t )( p[5] ) << 40) |
(( uint64_t )( p[6] ) << 48) |
(( uint64_t )( p[7] ) << 56) ;
#endif
}

static BLAKE2_INLINE uint16_t load16( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint16_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return ( uint16_t )((( uint32_t )( p[0] ) << 0) |
(( uint32_t )( p[1] ) << 8));
#endif
}

static BLAKE2_INLINE void store16( void *dst, uint16_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w;
#endif
}

static BLAKE2_INLINE void store32( void *dst, uint32_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
#endif
}

static BLAKE2_INLINE void store64( void *dst, uint64_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
p[4] = (uint8_t)(w >> 32);
p[5] = (uint8_t)(w >> 40);
p[6] = (uint8_t)(w >> 48);
p[7] = (uint8_t)(w >> 56);
#endif
}

static BLAKE2_INLINE uint64_t load48( const void *src )
{
const uint8_t *p = ( const uint8_t * )src;
return (( uint64_t )( p[0] ) << 0) |
(( uint64_t )( p[1] ) << 8) |
(( uint64_t )( p[2] ) << 16) |
(( uint64_t )( p[3] ) << 24) |
(( uint64_t )( p[4] ) << 32) |
(( uint64_t )( p[5] ) << 40) ;
}

static BLAKE2_INLINE void store48( void *dst, uint64_t w )
{
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
p[4] = (uint8_t)(w >> 32);
p[5] = (uint8_t)(w >> 40);
}

static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 32 - c ) );
}

static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 64 - c ) );
}

/* prevents compiler optimizing out memset() */
static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
{
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
memset_v(v, 0, n);
}

#endif
367 changes: 367 additions & 0 deletions libarchive/archive_blake2s_ref.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,367 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/

#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include "archive_blake2.h"
#include "archive_blake2_impl.h"

static const uint32_t blake2s_IV[8] =
{
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
};

static const uint8_t blake2s_sigma[10][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
};

static void blake2s_set_lastnode( blake2s_state *S )
{
S->f[1] = (uint32_t)-1;
}

/* Some helper functions, not necessarily useful */
static int blake2s_is_lastblock( const blake2s_state *S )
{
return S->f[0] != 0;
}

static void blake2s_set_lastblock( blake2s_state *S )
{
if( S->last_node ) blake2s_set_lastnode( S );

S->f[0] = (uint32_t)-1;
}

static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
{
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
}

static void blake2s_init0( blake2s_state *S )
{
size_t i;
memset( S, 0, sizeof( blake2s_state ) );

for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
}

/* init2 xors IV with input parameter block */
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
{
const unsigned char *p = ( const unsigned char * )( P );
size_t i;

blake2s_init0( S );

/* IV XOR ParamBlock */
for( i = 0; i < 8; ++i )
S->h[i] ^= load32( &p[i * 4] );

S->outlen = P->digest_length;
return 0;
}


/* Sequential blake2s initialization */
int blake2s_init( blake2s_state *S, size_t outlen )
{
blake2s_param P[1];

/* Move interval verification here? */
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;

P->digest_length = (uint8_t)outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store16( &P->xof_length, 0 );
P->node_depth = 0;
P->inner_length = 0;
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
return blake2s_init_param( S, P );
}

int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
{
blake2s_param P[1];

if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;

if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;

P->digest_length = (uint8_t)outlen;
P->key_length = (uint8_t)keylen;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store16( &P->xof_length, 0 );
P->node_depth = 0;
P->inner_length = 0;
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );

if( blake2s_init_param( S, P ) < 0 ) return -1;

{
uint8_t block[BLAKE2S_BLOCKBYTES];
memset( block, 0, BLAKE2S_BLOCKBYTES );
memcpy( block, key, keylen );
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
}
return 0;
}

#define G(r,i,a,b,c,d) \
do { \
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
d = rotr32(d ^ a, 16); \
c = c + d; \
b = rotr32(b ^ c, 12); \
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
d = rotr32(d ^ a, 8); \
c = c + d; \
b = rotr32(b ^ c, 7); \
} while(0)

#define ROUND(r) \
do { \
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
} while(0)

static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )
{
uint32_t m[16];
uint32_t v[16];
size_t i;

for( i = 0; i < 16; ++i ) {
m[i] = load32( in + i * sizeof( m[i] ) );
}

for( i = 0; i < 8; ++i ) {
v[i] = S->h[i];
}

v[ 8] = blake2s_IV[0];
v[ 9] = blake2s_IV[1];
v[10] = blake2s_IV[2];
v[11] = blake2s_IV[3];
v[12] = S->t[0] ^ blake2s_IV[4];
v[13] = S->t[1] ^ blake2s_IV[5];
v[14] = S->f[0] ^ blake2s_IV[6];
v[15] = S->f[1] ^ blake2s_IV[7];

ROUND( 0 );
ROUND( 1 );
ROUND( 2 );
ROUND( 3 );
ROUND( 4 );
ROUND( 5 );
ROUND( 6 );
ROUND( 7 );
ROUND( 8 );
ROUND( 9 );

for( i = 0; i < 8; ++i ) {
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
}
}

#undef G
#undef ROUND

int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )
{
const unsigned char * in = (const unsigned char *)pin;
if( inlen > 0 )
{
size_t left = S->buflen;
size_t fill = BLAKE2S_BLOCKBYTES - left;
if( inlen > fill )
{
S->buflen = 0;
memcpy( S->buf + left, in, fill ); /* Fill buffer */
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
blake2s_compress( S, S->buf ); /* Compress */
in += fill; inlen -= fill;
while(inlen > BLAKE2S_BLOCKBYTES) {
blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
blake2s_compress( S, in );
in += BLAKE2S_BLOCKBYTES;
inlen -= BLAKE2S_BLOCKBYTES;
}
}
memcpy( S->buf + S->buflen, in, inlen );
S->buflen += inlen;
}
return 0;
}

int blake2s_final( blake2s_state *S, void *out, size_t outlen )
{
uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
size_t i;

if( out == NULL || outlen < S->outlen )
return -1;

if( blake2s_is_lastblock( S ) )
return -1;

blake2s_increment_counter( S, ( uint32_t )S->buflen );
blake2s_set_lastblock( S );
memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
blake2s_compress( S, S->buf );

for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );

memcpy( out, buffer, outlen );
secure_zero_memory(buffer, sizeof(buffer));
return 0;
}

int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
{
blake2s_state S[1];

/* Verify parameters */
if ( NULL == in && inlen > 0 ) return -1;

if ( NULL == out ) return -1;

if ( NULL == key && keylen > 0) return -1;

if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;

if( keylen > BLAKE2S_KEYBYTES ) return -1;

if( keylen > 0 )
{
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
}
else
{
if( blake2s_init( S, outlen ) < 0 ) return -1;
}

blake2s_update( S, ( const uint8_t * )in, inlen );
blake2s_final( S, out, outlen );
return 0;
}

#if defined(SUPERCOP)
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
{
return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 );
}
#endif

#if defined(BLAKE2S_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( void )
{
uint8_t key[BLAKE2S_KEYBYTES];
uint8_t buf[BLAKE2_KAT_LENGTH];
size_t i, step;

for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
key[i] = ( uint8_t )i;

for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;

/* Test simple API */
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2S_OUTBYTES];
blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );

if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
{
goto fail;
}
}

/* Test streaming API */
for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
uint8_t hash[BLAKE2S_OUTBYTES];
blake2s_state S;
uint8_t * p = buf;
size_t mlen = i;
int err = 0;

if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
goto fail;
}

while (mlen >= step) {
if ( (err = blake2s_update(&S, p, step)) < 0 ) {
goto fail;
}
mlen -= step;
p += step;
}
if ( (err = blake2s_update(&S, p, mlen)) < 0) {
goto fail;
}
if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
goto fail;
}

if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {
goto fail;
}
}
}

puts( "ok" );
return 0;
fail:
puts("error");
return -1;
}
#endif
359 changes: 359 additions & 0 deletions libarchive/archive_blake2sp_ref.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,359 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#if defined(_OPENMP)
#include <omp.h>
#endif

#include "archive_blake2.h"
#include "archive_blake2_impl.h"

#define PARALLELISM_DEGREE 8

/*
blake2sp_init_param defaults to setting the expecting output length
from the digest_length parameter block field.
In some cases, however, we do not want this, as the output length
of these instances is given by inner_length instead.
*/
static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P )
{
int err = blake2s_init_param(S, P);
S->outlen = P->inner_length;
return err;
}

static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint32_t offset )
{
blake2s_param P[1];
P->digest_length = (uint8_t)outlen;
P->key_length = (uint8_t)keylen;
P->fanout = PARALLELISM_DEGREE;
P->depth = 2;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, offset );
store16( &P->xof_length, 0 );
P->node_depth = 0;
P->inner_length = BLAKE2S_OUTBYTES;
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
return blake2sp_init_leaf_param( S, P );
}

static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen )
{
blake2s_param P[1];
P->digest_length = (uint8_t)outlen;
P->key_length = (uint8_t)keylen;
P->fanout = PARALLELISM_DEGREE;
P->depth = 2;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store16( &P->xof_length, 0 );
P->node_depth = 1;
P->inner_length = BLAKE2S_OUTBYTES;
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
return blake2s_init_param( S, P );
}


int blake2sp_init( blake2sp_state *S, size_t outlen )
{
size_t i;

if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;

memset( S->buf, 0, sizeof( S->buf ) );
S->buflen = 0;
S->outlen = outlen;

if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
return -1;

for( i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S->S[i], outlen, 0, (uint32_t)i ) < 0 ) return -1;

S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
return 0;
}

int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
{
size_t i;

if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;

if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;

memset( S->buf, 0, sizeof( S->buf ) );
S->buflen = 0;
S->outlen = outlen;

if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
return -1;

for( i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S->S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;

S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
{
uint8_t block[BLAKE2S_BLOCKBYTES];
memset( block, 0, BLAKE2S_BLOCKBYTES );
memcpy( block, key, keylen );

for( i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );

secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
}
return 0;
}


int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen )
{
const unsigned char * in = (const unsigned char *)pin;
size_t left = S->buflen;
size_t fill = sizeof( S->buf ) - left;
size_t i;

if( left && inlen >= fill )
{
memcpy( S->buf + left, in, fill );

for( i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );

in += fill;
inlen -= fill;
left = 0;
}

#if defined(_OPENMP)
#pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
#else
for( i = 0; i < PARALLELISM_DEGREE; ++i )
#endif
{
#if defined(_OPENMP)
size_t i = omp_get_thread_num();
#endif
size_t inlen__ = inlen;
const unsigned char *in__ = ( const unsigned char * )in;
in__ += i * BLAKE2S_BLOCKBYTES;

while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
{
blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES );
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
}
}

in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;

if( inlen > 0 )
memcpy( S->buf + left, in, inlen );

S->buflen = left + inlen;
return 0;
}


int blake2sp_final( blake2sp_state *S, void *out, size_t outlen )
{
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
size_t i;

if(out == NULL || outlen < S->outlen) {
return -1;
}

for( i = 0; i < PARALLELISM_DEGREE; ++i )
{
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
{
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;

if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;

blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
}

blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
}

for( i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );

return blake2s_final( S->R, out, S->outlen );
}


int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
{
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
blake2s_state S[PARALLELISM_DEGREE][1];
blake2s_state FS[1];
size_t i;

/* Verify parameters */
if ( NULL == in && inlen > 0 ) return -1;

if ( NULL == out ) return -1;

if ( NULL == key && keylen > 0) return -1;

if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;

if( keylen > BLAKE2S_KEYBYTES ) return -1;

for( i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;

S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */

if( keylen > 0 )
{
uint8_t block[BLAKE2S_BLOCKBYTES];
memset( block, 0, BLAKE2S_BLOCKBYTES );
memcpy( block, key, keylen );

for( i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );

secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
}

#if defined(_OPENMP)
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
#else

for( i = 0; i < PARALLELISM_DEGREE; ++i )
#endif
{
#if defined(_OPENMP)
size_t i = omp_get_thread_num();
#endif
size_t inlen__ = inlen;
const unsigned char *in__ = ( const unsigned char * )in;
in__ += i * BLAKE2S_BLOCKBYTES;

while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
{
blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES );
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
}

if( inlen__ > i * BLAKE2S_BLOCKBYTES )
{
const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES;
const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
blake2s_update( S[i], in__, len );
}

blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES );
}

if( blake2sp_init_root( FS, outlen, keylen ) < 0 )
return -1;

FS->last_node = 1;

for( i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );

return blake2s_final( FS, out, outlen );
}



#if defined(BLAKE2SP_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( void )
{
uint8_t key[BLAKE2S_KEYBYTES];
uint8_t buf[BLAKE2_KAT_LENGTH];
size_t i, step;

for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
key[i] = ( uint8_t )i;

for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;

/* Test simple API */
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2S_OUTBYTES];
blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );

if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
{
goto fail;
}
}

/* Test streaming API */
for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
uint8_t hash[BLAKE2S_OUTBYTES];
blake2sp_state S;
uint8_t * p = buf;
size_t mlen = i;
int err = 0;

if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
goto fail;
}

while (mlen >= step) {
if ( (err = blake2sp_update(&S, p, step)) < 0 ) {
goto fail;
}
mlen -= step;
p += step;
}
if ( (err = blake2sp_update(&S, p, mlen)) < 0) {
goto fail;
}
if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
goto fail;
}

if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) {
goto fail;
}
}
}

puts( "ok" );
return 0;
fail:
puts("error");
return -1;
}
#endif
Loading