Compare commits

..

24 Commits

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

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

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

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

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

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

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

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

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

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

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

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

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

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

View File

@ -1,4 +1,3 @@
---
env:
CIRRUS_CLONE_DEPTH: 1
ARCH: amd64
@ -10,33 +9,22 @@ FreeBSD_task:
env:
BS: cmake
matrix:
- name: 15.0-STABLE (UFS)
freebsd_instance:
image_family: freebsd-15-0-amd64-ufs-snap
- name: 15.0-RELEASE (UFS)
freebsd_instance:
image_family: freebsd-15-0-amd64-ufs
- name: 15.0-RELEASE (ZFS)
freebsd_instance:
image_family: freebsd-15-0-amd64-zfs
- name: 14.3-RELEASE
freebsd_instance:
image_family: freebsd-14-3
- name: 13.5-RELEASE
freebsd_instance:
image_family: freebsd-13-5
freebsd_instance:
image_family: freebsd-14-2
freebsd_instance:
image_family: freebsd-13-5
prepare_script:
- ./build/ci/cirrus_ci/ci.sh prepare
configure_script:
- env CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a autogen
- env MAKE=gmake CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a configure
- env CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a configure
build_script:
- env MAKE=gmake MAKE_ARGS="-j 2" ./build/ci/build.sh -a build
- env MAKE_ARGS="-j 2" ./build/ci/build.sh -a build
test_script:
- env MAKE=gmake SKIP_TEST_RESTORE_ATIME=1 MAKE_ARGS="-j 2" ./build/ci/build.sh -a test
- env SKIP_TEST_RESTORE_ATIME=1 MAKE_ARGS="-j 2" ./build/ci/build.sh -a test
- ./build/ci/cirrus_ci/ci.sh test
install_script:
- env MAKE=gmake MAKE_ARGS="-j 2" ./build/ci/build.sh -a install
- env MAKE_ARGS="-j 2" ./build/ci/build.sh -a install
Windows_Cygwin_task:
windows_container:

View File

@ -12,7 +12,7 @@ jobs:
matrix:
bs: [autotools, cmake]
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install dependencies
run: ./build/ci/github_actions/install-macos-dependencies.sh
- name: Autogen
@ -47,7 +47,7 @@ jobs:
run: ./build/ci/build.sh -a artifact
env:
BS: ${{ matrix.bs }}
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: libarchive-macos-${{ matrix.bs }}-${{ github.sha }}
path: libarchive.tar.xz
@ -59,7 +59,7 @@ jobs:
bs: [autotools, cmake]
crypto: [mbedtls, nettle, openssl]
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Update apt cache
run: sudo apt-get update
- name: Install dependencies
@ -93,14 +93,14 @@ jobs:
run: ./build/ci/build.sh -a artifact
env:
BS: ${{ matrix.bs }}
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: libarchive-ubuntu-${{ matrix.bs }}-${{ matrix.crypto }}-${{ github.sha }}
path: libarchive.tar.xz
Ubuntu-distcheck:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Update package definitions
run: sudo apt-get update
- name: Install dependencies
@ -115,7 +115,7 @@ jobs:
SKIP_OPEN_FD_ERR_TEST: 1
- name: Dist-Artifact
run: ./build/ci/build.sh -a dist-artifact
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: libarchive-${{ github.sha }}
path: libarchive-dist.tar
@ -127,7 +127,7 @@ jobs:
matrix:
be: [mingw-gcc, msvc]
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install mingw
if: ${{ matrix.be=='mingw-gcc' }}
run: choco install mingw
@ -163,7 +163,7 @@ jobs:
shell: cmd
env:
BE: ${{ matrix.be }}
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: libarchive-windows-${{ matrix.be }}-${{ github.sha }}
path: libarchive.zip

View File

@ -21,7 +21,7 @@ jobs:
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts

View File

@ -26,18 +26,18 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
category: "/language:${{ matrix.language }}"

View File

@ -29,12 +29,12 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
@ -52,7 +52,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@ -60,6 +60,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
sarif_file: results.sarif

View File

@ -3,9 +3,6 @@ cmake_minimum_required(VERSION 3.17 FATAL_ERROR)
PROJECT(libarchive C)
#
# Include standard installation directories
include(GNUInstallDirs)
#
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
@ -19,7 +16,7 @@ endif()
# MinSizeRel : Release Min Size build
# None : No build type
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
# value type is "UNINITIALIZED".
@ -139,12 +136,7 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
# either of the following two, yet neither is supported as of 3.0.2
# - check_linker_flag - does not exist
# - try_compile - does not support linker flags
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "SunOS")
# SunOS linker doesn't support --gc-sections
ELSE()
IF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
# Place the functions and data into separate sections, allowing the linker
# to garbage collect the unused ones.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
@ -153,7 +145,10 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
# Printing the discarded section is "too much", so enable on demand.
#SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections")
#SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections")
ENDIF()
ELSE()
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
ENDIF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
@ -260,10 +255,6 @@ OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
OPTION(ENABLE_COVERAGE "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)" FALSE)
OPTION(ENABLE_INSTALL "Enable installing of libraries" ON)
IF(WIN32 AND MSVC)
OPTION(MSVC_USE_STATIC_CRT "Use static CRT" OFF)
ENDIF()
SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
SET(WINDOWS_VERSION "WIN10" CACHE STRING "Set Windows version to use (Windows only)")
@ -780,22 +771,12 @@ IF(ENABLE_CNG)
LA_CHECK_INCLUDE_FILE("bcrypt.h" HAVE_BCRYPT_H)
IF(HAVE_BCRYPT_H)
LIST(APPEND ADDITIONAL_LIBS "bcrypt")
# bcrypt supports these algorithms on all available versions
SET(ARCHIVE_CRYPTO_MD5 1)
SET(ARCHIVE_CRYPTO_MD5_WIN 1)
SET(ARCHIVE_CRYPTO_SHA1 1)
SET(ARCHIVE_CRYPTO_SHA1_WIN 1)
SET(ARCHIVE_CRYPTO_SHA256 1)
SET(ARCHIVE_CRYPTO_SHA256_WIN 1)
SET(ARCHIVE_CRYPTO_SHA384 1)
SET(ARCHIVE_CRYPTO_SHA384_WIN 1)
SET(ARCHIVE_CRYPTO_SHA512 1)
SET(ARCHIVE_CRYPTO_SHA512_WIN 1)
ENDIF(HAVE_BCRYPT_H)
ELSE(ENABLE_CNG)
UNSET(HAVE_BCRYPT_H CACHE)
ENDIF(ENABLE_CNG)
# Following files need windows.h, so we should test it after windows.h test.
LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H)
LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
#
@ -1004,6 +985,85 @@ main(int argc, char **argv)
ENDFOREACH(ALGORITHM ${ALGORITHMS})
ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
#
# CRYPTO functions on Windows is defined at archive_windows.c, thus we do not
# need the test what the functions can be mapped to archive_{crypto name}_init,
# archive_{crypto name}_update and archive_{crypto name}_final.
# The functions on Windows use CALG_{crypto name} macro to create a crypt object
# and then we need to know what CALG_{crypto name} macros is available to show
# ARCHIVE_CRYPTO_{crypto name}_WIN macros because Windows 2000 and earlier version
# of Windows XP do not support SHA256, SHA384 and SHA512.
#
MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
IF(WIN32 AND NOT CYGWIN)
FOREACH(CRYPTO ${CRYPTO_LIST})
IF(NOT ARCHIVE_CRYPTO_${CRYPTO})
IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
STRING(TOUPPER "${CRYPTO}" crypto)
SET(ALGID "")
IF ("${CRYPTO}" MATCHES "^MD5$")
SET(ALGID "CALG_MD5")
ENDIF ("${CRYPTO}" MATCHES "^MD5$")
IF ("${CRYPTO}" MATCHES "^SHA1$")
SET(ALGID "CALG_SHA1")
ENDIF ("${CRYPTO}" MATCHES "^SHA1$")
IF ("${CRYPTO}" MATCHES "^SHA256$")
SET(ALGID "CALG_SHA_256")
ENDIF ("${CRYPTO}" MATCHES "^SHA256$")
IF ("${CRYPTO}" MATCHES "^SHA384$")
SET(ALGID "CALG_SHA_384")
ENDIF ("${CRYPTO}" MATCHES "^SHA384$")
IF ("${CRYPTO}" MATCHES "^SHA512$")
SET(ALGID "CALG_SHA_512")
ENDIF ("${CRYPTO}" MATCHES "^SHA512$")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h)
FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h"
CONFDEFS_H)
SET(SOURCE "${CONFDEFS_H}
#define ${crypto}_COMPILE_TEST
#include <windows.h>
#include <wincrypt.h>
int
main(int argc, char **argv)
{
return ${ALGID};
}
")
SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_win.c")
FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
${CMAKE_BINARY_DIR}
${SOURCE_FILE}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
OUTPUT_VARIABLE OUTPUT)
IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
MESSAGE(STATUS
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found")
SET(ARCHIVE_CRYPTO_${CRYPTO} 1)
ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
MESSAGE(STATUS
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found")
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
ENDIF(NOT ARCHIVE_CRYPTO_${CRYPTO})
ENDFOREACH(CRYPTO)
ENDIF(WIN32 AND NOT CYGWIN)
ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
#
# Find iconv
# POSIX defines the second arg as const char **
@ -1018,8 +1078,8 @@ MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
CMAKE_C_COMPILER_ID MATCHES "^Clang$")
#
# During checking iconv proto type, we should use -Werror to avoid the
# success of iconv detection with a warning, which would be a false
# positive. So this is needed for all build modes, even in release mode.
# success of iconv detection with a warning which success is a miss
# detection. So this needs for all build mode(even it's a release mode).
#
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
@ -1412,8 +1472,6 @@ CHECK_FUNCTION_EXISTS_GLIBC(arc4random_buf HAVE_ARC4RANDOM_BUF)
CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
CHECK_FUNCTION_EXISTS_GLIBC(closefrom HAVE_CLOSEFROM)
CHECK_FUNCTION_EXISTS_GLIBC(close_range HAVE_CLOSE_RANGE)
CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
@ -1431,19 +1489,15 @@ CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE)
CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
CHECK_FUNCTION_EXISTS_GLIBC(getegid HAVE_GETEGID)
CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getresgid HAVE_GETRESGID)
CHECK_FUNCTION_EXISTS_GLIBC(getresuid HAVE_GETRESUID)
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(issetugid HAVE_ISSETUGID)
CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN)
@ -1462,7 +1516,6 @@ CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT)
CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
CHECK_FUNCTION_EXISTS_GLIBC(posix_spawn HAVE_POSIX_SPAWN)
CHECK_FUNCTION_EXISTS_GLIBC(posix_spawnp HAVE_POSIX_SPAWNP)
CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
CHECK_FUNCTION_EXISTS_GLIBC(readpassphrase HAVE_READPASSPHRASE)
@ -1526,6 +1579,12 @@ CHECK_C_SOURCE_COMPILES(
"#include <sys/types.h>\n#include <sys/mount.h>\nint main(void) { struct statfs s; return sizeof(s);}"
HAVE_STRUCT_STATFS)
# Make sure we have the POSIX version of readdir_r, not the
# older 2-argument version.
CHECK_C_SOURCE_COMPILES(
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
HAVE_READDIR_R)
# dirfd can be either a function or a macro.
CHECK_C_SOURCE_COMPILES(
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); return dirfd(d);}"
@ -2117,6 +2176,8 @@ CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL)
# Libmd has to be probed after OpenSSL.
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD)
CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
# Check visibility annotations
SET(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fvisibility=hidden -Werror")

View File

@ -96,73 +96,60 @@ distclean-local:
include_HEADERS= libarchive/archive.h libarchive/archive_entry.h
noinst_HEADERS= \
libarchive/archive_acl_private.h \
libarchive/archive_cmdline_private.h \
libarchive/archive_crc32.h \
libarchive/archive_cryptor_private.h \
libarchive/archive_digest_private.h \
libarchive/archive_endian.h \
libarchive/archive_entry.h \
libarchive/archive_entry_locale.h \
libarchive/archive_entry_private.h \
libarchive/archive_hmac_private.h \
libarchive/archive_openssl_evp_private.h \
libarchive/archive_openssl_hmac_private.h \
libarchive/archive_options_private.h \
libarchive/archive_pack_dev.h \
libarchive/archive_pathmatch.h \
libarchive/archive_platform.h \
libarchive/archive_platform_acl.h \
libarchive/archive_platform_stat.h \
libarchive/archive_platform_xattr.h \
libarchive/archive_ppmd7_private.h \
libarchive/archive_ppmd8_private.h \
libarchive/archive_ppmd_private.h \
libarchive/archive_private.h \
libarchive/archive_random_private.h \
libarchive/archive_rb.h \
libarchive/archive_read_disk_private.h \
libarchive/archive_read_private.h \
libarchive/archive_string.h \
libarchive/archive_string_composition.h \
libarchive/archive_time_private.h \
libarchive/archive_write_disk_private.h \
libarchive/archive_write_private.h \
libarchive/archive_write_set_format_private.h \
libarchive/archive_xxhash.h \
libarchive/config_freebsd.h \
libarchive/filter_fork.h
libarchive_la_SOURCES= \
libarchive/archive_acl.c \
libarchive/archive_acl_private.h \
libarchive/archive_check_magic.c \
libarchive/archive_cmdline.c \
libarchive/archive_cmdline_private.h \
libarchive/archive_crc32.h \
libarchive/archive_cryptor.c \
libarchive/archive_cryptor_private.h \
libarchive/archive_digest.c \
libarchive/archive_digest_private.h \
libarchive/archive_endian.h \
libarchive/archive_entry.c \
libarchive/archive_entry.h \
libarchive/archive_entry_copy_stat.c \
libarchive/archive_entry_link_resolver.c \
libarchive/archive_entry_locale.h \
libarchive/archive_entry_private.h \
libarchive/archive_entry_sparse.c \
libarchive/archive_entry_stat.c \
libarchive/archive_entry_strmode.c \
libarchive/archive_entry_xattr.c \
libarchive/archive_hmac.c \
libarchive/archive_hmac_private.h \
libarchive/archive_match.c \
libarchive/archive_openssl_evp_private.h \
libarchive/archive_openssl_hmac_private.h \
libarchive/archive_options.c \
libarchive/archive_options_private.h \
libarchive/archive_pack_dev.h \
libarchive/archive_pack_dev.c \
libarchive/archive_parse_date.c \
libarchive/archive_pathmatch.c \
libarchive/archive_pathmatch.h \
libarchive/archive_platform.h \
libarchive/archive_platform_acl.h \
libarchive/archive_platform_xattr.h \
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 \
libarchive/archive_rb.c \
libarchive/archive_rb.h \
libarchive/archive_read.c \
libarchive/archive_read_add_passphrase.c \
libarchive/archive_read_append_filter.c \
libarchive/archive_read_data_into_fd.c \
libarchive/archive_read_disk_entry_from_file.c \
libarchive/archive_read_disk_posix.c \
libarchive/archive_read_disk_private.h \
libarchive/archive_read_disk_set_standard_lookup.c \
libarchive/archive_read_extract.c \
libarchive/archive_read_extract2.c \
@ -170,11 +157,12 @@ libarchive_la_SOURCES= \
libarchive/archive_read_open_file.c \
libarchive/archive_read_open_filename.c \
libarchive/archive_read_open_memory.c \
libarchive/archive_read_private.h \
libarchive/archive_read_set_format.c \
libarchive/archive_read_set_options.c \
libarchive/archive_read_support_filter_all.c \
libarchive/archive_read_support_filter_by_code.c \
libarchive/archive_read_support_filter_bzip2.c \
libarchive/archive_read_support_filter_by_code.c \
libarchive/archive_read_support_filter_compress.c \
libarchive/archive_read_support_filter_grzip.c \
libarchive/archive_read_support_filter_gzip.c \
@ -205,12 +193,23 @@ libarchive_la_SOURCES= \
libarchive/archive_read_support_format_xar.c \
libarchive/archive_read_support_format_zip.c \
libarchive/archive_string.c \
libarchive/archive_string.h \
libarchive/archive_string_composition.h \
libarchive/archive_string_sprintf.c \
libarchive/archive_time.c \
libarchive/archive_time_private.h \
libarchive/archive_util.c \
libarchive/archive_version_details.c \
libarchive/archive_virtual.c \
libarchive/archive_write.c \
libarchive/archive_write_disk_posix.c \
libarchive/archive_write_disk_private.h \
libarchive/archive_write_disk_set_standard_lookup.c \
libarchive/archive_write_open_fd.c \
libarchive/archive_write_open_file.c \
libarchive/archive_write_open_filename.c \
libarchive/archive_write_open_memory.c \
libarchive/archive_write_private.h \
libarchive/archive_write_add_filter.c \
libarchive/archive_write_add_filter_b64encode.c \
libarchive/archive_write_add_filter_by_name.c \
@ -226,12 +225,6 @@ libarchive_la_SOURCES= \
libarchive/archive_write_add_filter_uuencode.c \
libarchive/archive_write_add_filter_xz.c \
libarchive/archive_write_add_filter_zstd.c \
libarchive/archive_write_disk_posix.c \
libarchive/archive_write_disk_set_standard_lookup.c \
libarchive/archive_write_open_fd.c \
libarchive/archive_write_open_file.c \
libarchive/archive_write_open_filename.c \
libarchive/archive_write_open_memory.c \
libarchive/archive_write_set_format.c \
libarchive/archive_write_set_format_7zip.c \
libarchive/archive_write_set_format_ar.c \
@ -241,54 +234,59 @@ libarchive_la_SOURCES= \
libarchive/archive_write_set_format_cpio_newc.c \
libarchive/archive_write_set_format_cpio_odc.c \
libarchive/archive_write_set_format_filter_by_ext.c \
libarchive/archive_write_set_format_gnutar.c \
libarchive/archive_write_set_format_iso9660.c \
libarchive/archive_write_set_format_mtree.c \
libarchive/archive_write_set_format_pax.c \
libarchive/archive_write_set_format_private.h \
libarchive/archive_write_set_format_raw.c \
libarchive/archive_write_set_format_shar.c \
libarchive/archive_write_set_format_ustar.c \
libarchive/archive_write_set_format_v7tar.c \
libarchive/archive_write_set_format_gnutar.c \
libarchive/archive_write_set_format_warc.c \
libarchive/archive_write_set_format_xar.c \
libarchive/archive_write_set_format_zip.c \
libarchive/archive_write_set_options.c \
libarchive/archive_write_set_passphrase.c \
libarchive/archive_xxhash.h \
libarchive/config_freebsd.h \
libarchive/filter_fork_posix.c \
libarchive/filter_fork.h \
libarchive/xxhash.c
if INC_WINDOWS_FILES
noinst_HEADERS+= \
libarchive/archive_windows.h
libarchive_la_SOURCES+= \
libarchive/archive_entry_copy_bhfi.c \
libarchive/archive_read_disk_windows.c \
libarchive/archive_windows.h \
libarchive/archive_windows.c \
libarchive/archive_write_disk_windows.c \
libarchive/filter_fork_windows.c
endif
if INC_BLAKE2
noinst_HEADERS+= \
libarchive/archive_blake2.h \
libarchive/archive_blake2_impl.h
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
endif
else
if INC_SUNOS_ACL
libarchive_la_SOURCES+= libarchive/archive_disk_acl_sunos.c
endif
else
if INC_DARWIN_ACL
libarchive_la_SOURCES+= libarchive/archive_disk_acl_darwin.c
endif
else
if INC_FREEBSD_ACL
libarchive_la_SOURCES+= libarchive/archive_disk_acl_freebsd.c
endif
endif
endif
endif
# -no-undefined marks that libarchive doesn't rely on symbols
# defined in the application. This is mandatory for cygwin.
@ -352,24 +350,22 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = build/pkgconfig/libarchive.pc
# Sources needed by all test programs
noinst_HEADERS+= \
test_utils/test_common.h \
test_utils/test_utils.h
test_utils_SOURCES= \
test_utils/test_utils.c \
test_utils/test_utils.h \
test_utils/test_main.c \
test_utils/test_utils.c
test_utils/test_common.h
#
#
# libarchive_test program
#
#
noinst_HEADERS+= \
libarchive/test/test.h
libarchive_test_SOURCES= \
$(libarchive_la_SOURCES) \
$(test_utils_SOURCES) \
libarchive/test/read_open_memory.c \
libarchive/test/test.h \
libarchive/test/test_7zip_filename_encoding.c \
libarchive/test/test_acl_nfs4.c \
libarchive/test/test_acl_pax.c \
@ -469,7 +465,6 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_7zip_encryption_data.c \
libarchive/test/test_read_format_7zip_encryption_partially.c \
libarchive/test/test_read_format_7zip_encryption_header.c \
libarchive/test/test_read_format_7zip_issue2765.c \
libarchive/test/test_read_format_7zip_malformed.c \
libarchive/test/test_read_format_7zip_packinfo_digests.c \
libarchive/test/test_read_format_ar.c \
@ -530,7 +525,6 @@ libarchive_test_SOURCES= \
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_V_negative_size.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 \
@ -676,6 +670,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_write_read_format_zip.c \
libarchive/test/test_xattr_platform.c \
libarchive/test/test_zip_filename_encoding.c
libarchive_test_CPPFLAGS= \
-I$(top_srcdir)/libarchive \
-I$(top_srcdir)/libarchive/test \
@ -688,9 +683,9 @@ libarchive_test_LDADD= $(LTLIBICONV)
# The "list.h" file just lists all of the tests defined in all of the sources.
# Building it automatically provides a sanity-check on libarchive_test_SOURCES
# above.
libarchive/test/list.h: $(libarchive_test_SOURCES)
libarchive/test/list.h: Makefile
$(MKDIR_P) libarchive/test
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
cat $(top_srcdir)/libarchive/test/test_*.c | grep '^DEFINE_TEST' > libarchive/test/list.h
libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test LRZIP=NOCONFIG
@ -710,7 +705,6 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_compat_lz4_2.tar.lz4.uu \
libarchive/test/test_compat_lz4_3.tar.lz4.uu \
libarchive/test/test_compat_lz4_B4.tar.lz4.uu \
libarchive/test/test_compat_lz4_skippable_frames_B4.tar.lz4.uu \
libarchive/test/test_compat_lz4_B4BD.tar.lz4.uu \
libarchive/test/test_compat_lz4_B4BDBX.tar.lz4.uu \
libarchive/test/test_compat_lz4_B5.tar.lz4.uu \
@ -817,7 +811,6 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_7zip_encryption_header.7z.uu \
libarchive/test/test_read_format_7zip_encryption_partially.7z.uu \
libarchive/test/test_read_format_7zip_extract_second.7z.uu \
libarchive/test/test_read_format_7zip_issue2765.7z.uu \
libarchive/test/test_read_format_7zip_lzma1.7z.uu \
libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \
libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \
@ -928,9 +921,6 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_rar4_encrypted_filenames.rar.uu \
libarchive/test/test_read_format_rar4_solid_encrypted.rar.uu \
libarchive/test/test_read_format_rar4_solid_encrypted_filenames.rar.uu \
libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu \
libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu \
libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu \
libarchive/test/test_read_format_rar5_encrypted.rar.uu \
libarchive/test/test_read_format_rar5_encrypted_filenames.rar.uu \
libarchive/test/test_read_format_rar5_solid_encrypted.rar.uu \
@ -962,7 +952,6 @@ libarchive_test_EXTRA_DIST=\
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_dirdata.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_sfx.exe.uu \
@ -971,7 +960,6 @@ libarchive_test_EXTRA_DIST=\
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_unicode.rar.uu \
libarchive/test/test_read_format_rar5_win32.rar.uu \
libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \
libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \
@ -984,7 +972,6 @@ libarchive_test_EXTRA_DIST=\
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_V_negative_size.tar.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 \
@ -1071,7 +1058,6 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_splitted_rar_seek_support_ab.uu \
libarchive/test/test_splitted_rar_seek_support_ac.uu \
libarchive/test/test_write_disk_appledouble.cpio.gz.uu \
libarchive/test/test_write_disk_appledouble_zip.zip.uu \
libarchive/test/test_write_disk_hfs_compression.tgz.uu \
libarchive/test/test_write_disk_mac_metadata.tar.gz.uu \
libarchive/test/test_write_disk_no_hfs_compression.tgz.uu \
@ -1081,15 +1067,14 @@ libarchive_test_EXTRA_DIST=\
#
# Common code for libarchive frontends (cpio, tar)
#
noinst_HEADERS+= \
libarchive_fe/lafe_err.h \
libarchive_fe/lafe_platform.h \
libarchive_fe/line_reader.h \
libarchive_fe/passphrase.h
libarchive_fe_la_SOURCES= \
libarchive_fe/lafe_err.c \
libarchive_fe/err.c \
libarchive_fe/err.h \
libarchive_fe/lafe_platform.h \
libarchive_fe/line_reader.c \
libarchive_fe/passphrase.c
libarchive_fe/line_reader.h \
libarchive_fe/passphrase.c \
libarchive_fe/passphrase.h
libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
#
@ -1098,23 +1083,21 @@ libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
#
#
noinst_HEADERS+= \
tar/bsdtar.h \
tar/bsdtar_platform.h
bsdtar_SOURCES= \
tar/bsdtar.c \
tar/cmdline.c \
tar/creation_set.c \
tar/read.c \
tar/subst.c \
tar/util.c \
tar/write.c
tar/bsdtar.c \
tar/bsdtar.h \
tar/bsdtar_platform.h \
tar/cmdline.c \
tar/creation_set.c \
tar/read.c \
tar/subst.c \
tar/util.c \
tar/write.c
if INC_WINDOWS_FILES
noinst_HEADERS+= \
tar/bsdtar_windows.h
bsdtar_SOURCES+= \
tar/bsdtar_windows.c
tar/bsdtar_windows.h \
tar/bsdtar_windows.c
endif
bsdtar_DEPENDENCIES= libarchive.la libarchive_fe.la
@ -1151,15 +1134,12 @@ endif
# bsdtar_test
#
noinst_HEADERS+= \
tar/test/test.h
bsdtar_test_SOURCES= \
$(test_utils_SOURCES) \
tar/test/test.h \
tar/test/test_0.c \
tar/test/test_basic.c \
tar/test/test_copy.c \
tar/test/test_crlf_mtree.c \
tar/test/test_empty_mtree.c \
tar/test/test_extract_tar_Z.c \
tar/test/test_extract_tar_bz2.c \
@ -1236,9 +1216,9 @@ bsdtar_test_CPPFLAGS=\
-I$(top_builddir)/tar/test \
$(PLATFORMCPPFLAGS)
tar/test/list.h: $(bsdtar_test_SOURCES)
tar/test/list.h: Makefile
$(MKDIR_P) tar/test
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
cat $(top_srcdir)/tar/test/test_*.c | grep '^DEFINE_TEST' > tar/test/list.h
if BUILD_BSDTAR
bsdtar_test_programs= bsdtar_test
@ -1279,18 +1259,16 @@ bsdtar_test_EXTRA_DIST= \
#
#
noinst_HEADERS+= \
cpio/cpio.h \
cpio/cpio_platform.h
bsdcpio_SOURCES= \
cpio/cmdline.c \
cpio/cpio.c
cpio/cmdline.c \
cpio/cpio.c \
cpio/cpio.h \
cpio/cpio_platform.h
if INC_WINDOWS_FILES
noinst_HEADERS+= \
cpio/cpio_windows.h
bsdcpio_SOURCES+= \
cpio/cpio_windows.c
cpio/cpio_windows.h \
cpio/cpio_windows.c
endif
bsdcpio_DEPENDENCIES = libarchive.la libarchive_fe.la
@ -1329,11 +1307,10 @@ endif
# bsdcpio_test
#
noinst_HEADERS+= \
cpio/test/test.h
bsdcpio_test_SOURCES= \
$(test_utils_SOURCES) \
cpio/cmdline.c \
cpio/test/test.h \
cpio/test/test_0.c \
cpio/test/test_basic.c \
cpio/test/test_cmdline.c \
@ -1392,9 +1369,9 @@ bsdcpio_test_CPPFLAGS= \
$(PLATFORMCPPFLAGS)
bsdcpio_test_LDADD=libarchive_fe.la
cpio/test/list.h: $(bsdcpio_test_SOURCES)
cpio/test/list.h: Makefile
$(MKDIR_P) cpio/test
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
cat $(top_srcdir)/cpio/test/test_*.c | grep '^DEFINE_TEST' > cpio/test/list.h
if BUILD_BSDCPIO
bsdcpio_test_programs= bsdcpio_test
@ -1439,15 +1416,13 @@ bsdcpio_test_EXTRA_DIST= \
#
#
noinst_HEADERS+= \
cat/bsdcat.h \
cat/bsdcat_platform.h
bsdcat_SOURCES= \
cat/bsdcat.c \
cat/cmdline.c
cat/bsdcat.c \
cat/bsdcat.h \
cat/bsdcat_platform.h \
cat/cmdline.c
if INC_WINDOWS_FILES
noinst_HEADERS+=
bsdcat_SOURCES+=
endif
@ -1484,10 +1459,9 @@ endif
# bsdcat_test
#
noinst_HEADERS+= \
cat/test/test.h
bsdcat_test_SOURCES= \
$(test_utils_SOURCES) \
cat/test/test.h \
cat/test/test_0.c \
cat/test/test_empty_gz.c \
cat/test/test_empty_lz4.c \
@ -1515,9 +1489,9 @@ bsdcat_test_CPPFLAGS= \
$(PLATFORMCPPFLAGS)
bsdcat_test_LDADD=libarchive_fe.la
cat/test/list.h: $(bsdcat_test_SOURCES)
cat/test/list.h: Makefile
$(MKDIR_P) cat/test
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
cat $(top_srcdir)/cat/test/test_*.c | grep '^DEFINE_TEST' > cat/test/list.h
if BUILD_BSDCAT
bsdcat_test_programs= bsdcat_test
@ -1548,18 +1522,16 @@ bsdcat_test_EXTRA_DIST= \
#
#
noinst_HEADERS+= \
unzip/bsdunzip.h \
unzip/bsdunzip_platform.h \
unzip/la_getline.h \
unzip/la_queue.h
bsdunzip_SOURCES= \
unzip/bsdunzip.c \
unzip/cmdline.c \
unzip/la_getline.c
unzip/bsdunzip.c \
unzip/bsdunzip.h \
unzip/bsdunzip_platform.h \
unzip/cmdline.c \
unzip/la_getline.c \
unzip/la_getline.h \
unzip/la_queue.h
if INC_WINDOWS_FILES
noinst_HEADERS+=
bsdunzip_SOURCES+=
endif
@ -1596,10 +1568,9 @@ endif
# bsdunzip_test
#
noinst_HEADERS+= \
unzip/test/test.h
bsdunzip_test_SOURCES= \
$(test_utils_SOURCES) \
unzip/test/test.h \
unzip/test/test_0.c \
unzip/test/test_basic.c \
unzip/test/test_doubledash.c \
@ -1630,9 +1601,9 @@ bsdunzip_test_CPPFLAGS= \
$(PLATFORMCPPFLAGS)
bsdunzip_test_LDADD=libarchive_fe.la
unzip/test/list.h: $(bsdunzip_test_SOURCES)
unzip/test/list.h: Makefile
$(MKDIR_P) unzip/test
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
cat $(top_srcdir)/unzip/test/test_*.c | grep '^DEFINE_TEST' > unzip/test/list.h
if BUILD_BSDUNZIP
bsdunzip_test_programs= bsdunzip_test

2
NEWS
View File

@ -1,3 +1,5 @@
Jun 01, 2026: libarchive 3.8.1 released
May 20, 2025: libarchive 3.8.0 released
Mar 30, 2025: libarchive 3.7.9 released

View File

@ -191,7 +191,7 @@ questions we are asked about libarchive:
libraries. This also reduces the size of statically-linked
binaries in environments where that matters.
* The library is generally _thread-safe_ depending on the platform:
* The library is generally _thread safe_ depending on the platform:
it does not define any global variables of its own. However, some
platforms do not provide fully thread-safe versions of key C library
functions. On those platforms, libarchive will use the non-thread-safe
@ -214,7 +214,7 @@ questions we are asked about libarchive:
multiple threads. Of course, those modules are completely
optional and you can use the rest of libarchive without them.
* The library is _not_ thread-aware, however. It does no locking
* The library is _not_ thread aware, however. It does no locking
or thread management of any kind. If you create a libarchive
object and need to access it from multiple threads, you will
need to provide your own locking.

View File

@ -16,4 +16,4 @@ Please provide the following information in your report:
- How to reproduce the issue
This project is maintained by volunteers on a reasonable-effort basis. As such, we ask
that you give us 90 days to work on a fix before public exposure.
that you give me 90 days to work on a fix before public exposure.

View File

@ -23,7 +23,7 @@ then
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 gmake
pkg install -y autoconf automake cmake libiconv libtool pkgconf expat libxml2 liblz4 zstd
elif [ "${UNAME}" = "Darwin" ]
then
set -x -e

View File

@ -5,9 +5,6 @@ set -eux
#brew update > /dev/null
#brew upgrade > /dev/null
# Workaround for cmake in local/pinned tap issue
brew uninstall cmake
# This does an upgrade if the package is already installed
brew install \
autoconf \

View File

@ -405,12 +405,6 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `chroot' function. */
#cmakedefine HAVE_CHROOT 1
/* Define to 1 if you have the `closefrom' function. */
#cmakedefine HAVE_CLOSEFROM 1
/* Define to 1 if you have the `close_range' function. */
#cmakedefine HAVE_CLOSE_RANGE 1
/* Define to 1 if you have the <copyfile.h> header file. */
#cmakedefine HAVE_COPYFILE_H 1
@ -976,6 +970,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
/* Define to 1 if you have the `readdir_r' function. */
#cmakedefine HAVE_READDIR_R 1
/* Define to 1 if you have the `readlink' function. */
#cmakedefine HAVE_READLINK 1

View File

@ -1 +1 @@
3009000
3008001

View File

@ -13,8 +13,8 @@ IF(ENABLE_CAT)
bsdcat.h
bsdcat_platform.h
cmdline.c
../libarchive_fe/lafe_err.c
../libarchive_fe/lafe_err.h
../libarchive_fe/err.c
../libarchive_fe/err.h
../libarchive_fe/lafe_platform.h
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)

View File

@ -7,9 +7,6 @@
#include "bsdcat_platform.h"
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@ -25,7 +22,7 @@
#include <archive_entry.h>
#include "bsdcat.h"
#include "lafe_err.h"
#include "err.h"
#define BYTES_PER_BLOCK (20*512)
@ -108,16 +105,6 @@ main(int argc, char **argv)
bsdcat = &bsdcat_storage;
memset(bsdcat, 0, sizeof(*bsdcat));
#if defined(HAVE_SIGACTION) && defined(SIGCHLD)
{ /* Do not ignore SIGCHLD. */
struct sigaction sa;
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGCHLD, &sa, NULL);
}
#endif
lafe_setprogname(*argv, "bsdcat");
bsdcat->argv = argv;

View File

@ -22,7 +22,7 @@
#endif
#include "bsdcat.h"
#include "lafe_err.h"
#include "err.h"
/*
* Short options for bsdcat. Please keep this sorted.

View File

@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release.
m4_define([LIBARCHIVE_VERSION_S],[3.9.0dev])
m4_define([LIBARCHIVE_VERSION_N],[3009000])
m4_define([LIBARCHIVE_VERSION_S],[3.8.1])
m4_define([LIBARCHIVE_VERSION_N],[3008001])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
@ -377,7 +377,7 @@ AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
AC_CHECK_TYPE([suseconds_t])
AC_CHECK_HEADERS([windows.h])
# check windows.h first; the other headers require it.
AC_CHECK_HEADERS([winioctl.h],[],[],
AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
[[#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
@ -821,20 +821,16 @@ AC_FUNC_VPRINTF
# To avoid necessity for including windows.h or special forward declaration
# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
AC_CHECK_FUNCS([arc4random_buf chflags chown chroot])
AC_CHECK_FUNCS([closefrom close_range ctime_r])
AC_CHECK_FUNCS([arc4random_buf chflags chown chroot ctime_r])
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fnmatch fork])
AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
AC_CHECK_FUNCS([futimens futimes futimesat])
AC_CHECK_FUNCS([getegid geteuid getline getpid getresgid getresuid])
AC_CHECK_FUNCS([getgrgid_r getgrnam_r getpwnam_r getpwuid_r])
AC_CHECK_FUNCS([getvfsbyname gmtime_r])
AC_CHECK_FUNCS([issetugid])
AC_CHECK_FUNCS([geteuid getline getpid getgrgid_r getgrnam_r])
AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
AC_CHECK_FUNCS([lchflags lchmod lchown link linkat localtime_r lstat lutimes])
AC_CHECK_FUNCS([mbrtowc memmove memset])
AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawn posix_spawnp])
AC_CHECK_FUNCS([readlink readlinkat])
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 strnlen strrchr symlink])
@ -885,6 +881,14 @@ AC_CHECK_TYPES(struct statfs,,,
#include <sys/mount.h>
])
# There are several variants of readdir_r around; we only
# accept the POSIX-compliant version.
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[#include <dirent.h>]],
[[DIR *dir; struct dirent e, *r;
return(readdir_r(dir, &e, &r));]])],
[AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])]
)
# dirfd can be either a function or a macro.
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[#include <dirent.h>

View File

@ -26,8 +26,6 @@ LOCAL_PATH := $(subst /contrib/android,,$(call my-dir))
libarchive_target_config := contrib/android/config/android.h
libarchive_src_files := libarchive/archive_acl.c \
libarchive/archive_blake2s_ref.c \
libarchive/archive_blake2sp_ref.c \
libarchive/archive_check_magic.c \
libarchive/archive_cmdline.c \
libarchive/archive_cryptor.c \
@ -46,7 +44,6 @@ libarchive_src_files := libarchive/archive_acl.c \
libarchive/archive_parse_date.c \
libarchive/archive_pathmatch.c \
libarchive/archive_ppmd7.c \
libarchive/archive_ppmd8.c \
libarchive/archive_random.c \
libarchive/archive_rb.c \
libarchive/archive_read.c \
@ -89,7 +86,6 @@ libarchive_src_files := libarchive/archive_acl.c \
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 \
@ -97,7 +93,6 @@ libarchive_src_files := libarchive/archive_acl.c \
libarchive/archive_read_support_format_zip.c \
libarchive/archive_string.c \
libarchive/archive_string_sprintf.c \
libarchive/archive_time.c \
libarchive/archive_util.c \
libarchive/archive_version_details.c \
libarchive/archive_virtual.c \
@ -128,9 +123,7 @@ libarchive_src_files := libarchive/archive_acl.c \
libarchive/archive_write_set_format_ar.c \
libarchive/archive_write_set_format_by_name.c \
libarchive/archive_write_set_format_cpio.c \
libarchive/archive_write_set_format_cpio_binary.c \
libarchive/archive_write_set_format_cpio_newc.c \
libarchive/archive_write_set_format_cpio_odc.c \
libarchive/archive_write_set_format_iso9660.c \
libarchive/archive_write_set_format_mtree.c \
libarchive/archive_write_set_format_pax.c \
@ -158,7 +151,7 @@ else
libarchive_host_src_files :=
endif
libarchive_fe_src_files := libarchive_fe/lafe_err.c \
libarchive_fe_src_files := libarchive_fe/err.c \
libarchive_fe/line_reader.c \
libarchive_fe/passphrase.c
@ -312,17 +305,4 @@ LOCAL_SRC_FILES := $(bsdcat_src_files)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libarchive $(LOCAL_PATH)/libarchive_fe $(LOCAL_PATH)/contrib/android/include
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := bsdtar-recovery
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_STEM := bsdtar
LOCAL_CFLAGS := -DBSDTAR_VERSION_STRING=ARCHIVE_VERSION_ONLY_STRING -DPLATFORM_CONFIG_H=\"$(libarchive_target_config)\"
LOCAL_STATIC_LIBRARIES := libarchive libarchive_fe libz
LOCAL_SRC_FILES := $(bsdtar_src_files)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libarchive $(LOCAL_PATH)/libarchive_fe $(LOCAL_PATH)/contrib/android/include
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
endif

View File

@ -26,8 +26,6 @@
#ifndef ARCHIVE_PLATFORM_H_ANDROID_INCLUDED
#define ARCHIVE_PLATFORM_H_ANDROID_INCLUDED
#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
#include <android/api-level.h>
#ifdef __ANDROID_API__
#if __ANDROID_API__ > 20
@ -42,8 +40,6 @@
#define HAVE_CHOWN 1
#define HAVE_CHROOT 1
#define HAVE_CLOSEFROM 0
#define HAVE_CLOSE_RANGE 0
#define HAVE_CTIME_R 1
#define HAVE_CTYPE_H 1
#define HAVE_DECL_EXTATTR_NAMESPACE_USER 0
@ -57,8 +53,6 @@
#define HAVE_DECL_UINTMAX_MAX 1
#define HAVE_DECL_UINT32_MAX 1
#define HAVE_DECL_UINT64_MAX 1
#define HAVE_DECL_INT32_MAX 1
#define HAVE_DECL_INT32_MIN 1
#define HAVE_DIRENT_H 1
#define HAVE_DIRFD 1
#define HAVE_DLFCN_H 1
@ -141,7 +135,7 @@
#define HAVE_STRING_H 1
#define HAVE_STRRCHR 1
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 0
#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
#define HAVE_STRUCT_TM_TM_GMTOFF 1
#define HAVE_SYMLINK 1
#define HAVE_SYS_CDEFS_H 1

View File

@ -28,8 +28,6 @@
#define HAVE_CHOWN 1
#define HAVE_CHROOT 1
#define HAVE_CLOSEFROM 1
#define HAVE_CLOSE_RANGE 1
#define HAVE_CTIME_R 1
#define HAVE_CTYPE_H 1
#define HAVE_DECL_EXTATTR_NAMESPACE_USER 0
@ -182,7 +180,7 @@
#define HAVE_WMEMCMP 1
#define HAVE_WMEMCPY 1
#define HAVE_ZLIB_H 1
#define ICONV_CONST
#define ICONV_CONST
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
#define SIZEOF_WCHAR_T 4
#define STDC_HEADERS 1

View File

@ -175,12 +175,6 @@
/* Define to 1 if you have the `chroot' function. */
/* #undef HAVE_CHROOT */
/* Define to 1 if you have the `closefrom' function. */
/* #undef HAVE_CLOSEFROM */
/* Define to 1 if you have the `close_range' function. */
/* #undef HAVE_CLOSE_RANGE */
/* Define to 1 if you have the <copyfile.h> header file. */
/* #undef HAVE_COPYFILE_H */
@ -626,6 +620,9 @@
/* Define to 1 if you have the <pwd.h> header file. */
/* #undef HAVE_PWD_H */
/* Define to 1 if you have a POSIX compatible readdir_r */
#define HAVE_READDIR_R 1
/* Define to 1 if you have the `readlink' function. */
/* #undef HAVE_READLINK */
@ -899,6 +896,9 @@
/* Define to 1 if you have the <wctype.h> header file. */
#define HAVE_WCTYPE_H 1
/* Define to 1 if you have the <wincrypt.h> header file. */
#define HAVE_WINCRYPT_H 1
/* Define to 1 if you have the <windows.h> header file. */
#define HAVE_WINDOWS_H 1

View File

@ -1,4 +1,4 @@
/*
/*
* Macros for file64 functions
*
* Android does not support the macro _FILE_OFFSET_BITS=64
@ -19,6 +19,7 @@
#include <sys/vfs.h>
//dirent.h
#define readdir_r readdir64_r
#define readdir readdir64
#define dirent dirent64
//fcntl.h

View File

@ -1,156 +0,0 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LIBARCHIVE_FUZZ_HELPERS_H_
#define LIBARCHIVE_FUZZ_HELPERS_H_
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <ftw.h>
#include <unistd.h>
#include "archive.h"
// Default maximum input size for fuzzers
static constexpr size_t kDefaultMaxInputSize = 256 * 1024; // 256KB
// Buffer structure for archive reading callbacks
struct Buffer {
const uint8_t* data;
size_t size;
size_t pos;
};
// Archive read callback function
static la_ssize_t reader_callback(struct archive* a, void* client_data,
const void** buffer) {
(void)a;
Buffer* buf = static_cast<Buffer*>(client_data);
if (buf->pos >= buf->size) {
return 0; // EOF
}
*buffer = buf->data + buf->pos;
size_t remaining = buf->size - buf->pos;
buf->pos = buf->size; // Consume all remaining data
return static_cast<la_ssize_t>(remaining);
}
// Helper class for consuming fuzz data in structured ways
class DataConsumer {
public:
DataConsumer(const uint8_t* data, size_t size)
: data_(data), size_(size), pos_(0) {}
bool empty() const { return pos_ >= size_; }
size_t remaining() const { return size_ - pos_; }
uint8_t consume_byte() {
if (pos_ >= size_) return 0;
return data_[pos_++];
}
uint16_t consume_u16() {
uint16_t val = 0;
if (pos_ + 2 <= size_) {
val = static_cast<uint16_t>(data_[pos_]) |
(static_cast<uint16_t>(data_[pos_ + 1]) << 8);
pos_ += 2;
}
return val;
}
uint32_t consume_u32() {
uint32_t val = 0;
if (pos_ + 4 <= size_) {
val = static_cast<uint32_t>(data_[pos_]) |
(static_cast<uint32_t>(data_[pos_ + 1]) << 8) |
(static_cast<uint32_t>(data_[pos_ + 2]) << 16) |
(static_cast<uint32_t>(data_[pos_ + 3]) << 24);
pos_ += 4;
}
return val;
}
int64_t consume_i64() {
int64_t val = 0;
if (pos_ + 8 <= size_) {
for (int i = 0; i < 8; i++) {
val |= static_cast<int64_t>(data_[pos_ + i]) << (8 * i);
}
pos_ += 8;
}
return val;
}
// Consume a null-terminated string up to max_len characters
// Returns pointer to internal buffer (valid until next consume_string call)
const char* consume_string(size_t max_len) {
if (max_len > sizeof(string_buf_) - 1) {
max_len = sizeof(string_buf_) - 1;
}
size_t avail = size_ - pos_;
size_t len = (avail < max_len) ? avail : max_len;
size_t actual_len = 0;
while (actual_len < len && pos_ < size_) {
char c = static_cast<char>(data_[pos_++]);
if (c == '\0') break;
string_buf_[actual_len++] = c;
}
string_buf_[actual_len] = '\0';
return string_buf_;
}
// Consume raw bytes into a buffer
size_t consume_bytes(void* out, size_t len) {
size_t avail = size_ - pos_;
size_t to_copy = (avail < len) ? avail : len;
if (to_copy > 0) {
memcpy(out, data_ + pos_, to_copy);
pos_ += to_copy;
}
return to_copy;
}
// Get remaining data as a buffer
const uint8_t* remaining_data() const {
return data_ + pos_;
}
private:
const uint8_t* data_;
size_t size_;
size_t pos_;
char string_buf_[512];
};
// Callback for nftw to remove files/directories
static int remove_callback(const char* fpath, const struct stat* sb,
int typeflag, struct FTW* ftwbuf) {
(void)sb;
(void)typeflag;
(void)ftwbuf;
return remove(fpath);
}
// Recursively remove a directory tree (safer than system("rm -rf ..."))
static int remove_directory_tree(const char* path) {
// nftw with FTW_DEPTH processes directory contents before the directory itself
return nftw(path, remove_callback, 64, FTW_DEPTH | FTW_PHYS);
}
#endif // LIBARCHIVE_FUZZ_HELPERS_H_

View File

@ -1,63 +0,0 @@
/*
* 7-Zip format specific fuzzer for libarchive
* Targets 7-Zip parsing and decompression code paths
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024; // 512KB
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
// Enable 7-Zip format specifically
archive_read_support_format_7zip(a);
// Enable all filters for 7z internal compression
archive_read_support_filter_all(a);
// Set passphrase for encrypted archives
archive_read_add_passphrase(a, "password");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
// Exercise entry metadata access
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_is_encrypted(entry);
archive_entry_is_data_encrypted(entry);
archive_entry_is_metadata_encrypted(entry);
// Read data
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,47 +0,0 @@
# 7-Zip format dictionary
# Magic bytes
"7z\xbc\xaf\x27\x1c"
"\x37\x7a\xbc\xaf\x27\x1c"
# Common property IDs
"\x00"
"\x01"
"\x02"
"\x03"
"\x04"
"\x05"
"\x06"
"\x07"
"\x08"
"\x09"
"\x0a"
"\x0b"
"\x0c"
"\x0d"
"\x0e"
"\x0f"
"\x10"
"\x11"
"\x17"
"\x19"
"\x21"
"\x23"
"\x24"
"\x25"
# Compression method IDs
"\x00\x00"
"\x00\x03"
"\x00\x04"
"\x00\x06"
"\x01\x01"
"\x03\x01\x01"
"\x04\x01\x08"
"\x04\x02\x02"
"\x21\x01"
"\x30\x01\x01"
# Encryption
"\x06\xf1\x07\x01"
"Password"
"password"

View File

@ -1,10 +0,0 @@
[libfuzzer]
max_len = 524288
timeout = 60
rss_limit_mb = 2048
[honggfuzz]
timeout = 60
[afl]
timeout = 60

View File

@ -1,54 +0,0 @@
/*
* AR (Unix archive) format fuzzer for libarchive
* Tests BSD and GNU ar formats
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_ar(a);
archive_read_support_filter_all(a);
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_uid(entry);
archive_entry_gid(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,20 +0,0 @@
# AR format dictionary
# AR magic
"!<arch>\x0a"
# File header terminator
"\x60\x0a"
# Special entries
"/"
"//"
"/SYM64/"
# Common permissions
"100644 "
"100755 "
# UID/GID fields
"0 "
"1000 "

View File

@ -1,51 +0,0 @@
/*
* CAB (Microsoft Cabinet) format fuzzer for libarchive
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_cab(a);
archive_read_support_filter_all(a);
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,23 +0,0 @@
# CAB (Microsoft Cabinet) format dictionary
# CAB signature
"MSCF"
"\x4d\x53\x43\x46"
# Version
"\x03\x01"
# Compression types
"\x00\x00"
"\x01\x00"
"\x02\x00"
"\x03\x00"
# Folder count patterns
"\x01\x00"
"\x02\x00"
# Header flags
"\x00\x00"
"\x01\x00"
"\x04\x00"

View File

@ -1,58 +0,0 @@
/*
* CPIO format fuzzer for libarchive
* Tests all CPIO variants: binary, odc, newc, crc
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_cpio(a);
archive_read_support_filter_all(a);
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_uid(entry);
archive_entry_gid(entry);
archive_entry_ino(entry);
archive_entry_nlink(entry);
archive_entry_rdev(entry);
archive_entry_hardlink(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,25 +0,0 @@
# CPIO format dictionary
# Binary magic (little endian)
"\xc7\x71"
# Binary magic (big endian)
"\x71\xc7"
# ASCII odc magic
"070707"
# ASCII newc magic
"070701"
# ASCII crc magic
"070702"
# Common trailer
"TRAILER!!!"
# Common field patterns
"00000000"
"00000001"
"000001ed"
"000003e8"

View File

@ -1,101 +0,0 @@
/*
* Encrypted archive fuzzer for libarchive
* Tests password/passphrase handling across formats
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
// Passphrase callback for testing
static const char *test_passphrases[] = {
"password",
"test",
"123456",
"",
"secret",
NULL
};
static int passphrase_idx = 0;
static const char* passphrase_callback(struct archive *a, void *client_data) {
(void)a;
(void)client_data;
const char *pass = test_passphrases[passphrase_idx];
if (pass != NULL) {
passphrase_idx++;
}
return pass;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
// Reset passphrase index
passphrase_idx = 0;
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
// Enable all formats that support encryption
archive_read_support_format_zip(a);
archive_read_support_format_7zip(a);
archive_read_support_format_rar(a);
archive_read_support_format_rar5(a);
archive_read_support_filter_all(a);
// Set up passphrase callback
archive_read_set_passphrase_callback(a, NULL, passphrase_callback);
// Also add some static passphrases
archive_read_add_passphrase(a, "password");
archive_read_add_passphrase(a, "test123");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
int entry_count = 0;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK && entry_count < 100) {
archive_entry_pathname(entry);
// Check encryption status
int is_encrypted = archive_entry_is_encrypted(entry);
int is_data_encrypted = archive_entry_is_data_encrypted(entry);
int is_meta_encrypted = archive_entry_is_metadata_encrypted(entry);
(void)is_encrypted;
(void)is_data_encrypted;
(void)is_meta_encrypted;
// Check if archive has encrypted entries
archive_read_has_encrypted_entries(a);
// Try to read data (may fail due to wrong password)
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
entry_count++;
}
archive_read_free(a);
return 0;
}

View File

@ -1,10 +0,0 @@
[libfuzzer]
max_len = 524288
timeout = 60
rss_limit_mb = 2048
[honggfuzz]
timeout = 60
[afl]
timeout = 60

View File

@ -1,105 +0,0 @@
/*
* Archive entry fuzzer for libarchive
* Targets archive_entry_* functions including ACL, linkify, and metadata
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 64 * 1024; // 64KB
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
DataConsumer consumer(buf, len);
struct archive_entry *entry = archive_entry_new();
if (entry == NULL) {
return 0;
}
// Set basic entry properties
archive_entry_set_pathname(entry, consumer.consume_string(256));
archive_entry_set_size(entry, consumer.consume_i64());
archive_entry_set_mode(entry, consumer.consume_u32());
archive_entry_set_uid(entry, consumer.consume_u32());
archive_entry_set_gid(entry, consumer.consume_u32());
archive_entry_set_mtime(entry, consumer.consume_i64(), 0);
archive_entry_set_atime(entry, consumer.consume_i64(), 0);
archive_entry_set_ctime(entry, consumer.consume_i64(), 0);
archive_entry_set_birthtime(entry, consumer.consume_i64(), 0);
// Set various string fields
archive_entry_set_uname(entry, consumer.consume_string(64));
archive_entry_set_gname(entry, consumer.consume_string(64));
archive_entry_set_symlink(entry, consumer.consume_string(256));
archive_entry_set_hardlink(entry, consumer.consume_string(256));
// Exercise ACL functions (low coverage targets)
int acl_type = consumer.consume_byte() & 0x0F;
int acl_permset = consumer.consume_u32();
int acl_tag = consumer.consume_byte() & 0x0F;
int acl_qual = consumer.consume_u32();
const char *acl_name = consumer.consume_string(64);
archive_entry_acl_add_entry(entry, acl_type, acl_permset, acl_tag, acl_qual, acl_name);
// Add more ACL entries based on remaining data
while (!consumer.empty() && consumer.remaining() > 10) {
acl_type = consumer.consume_byte() & 0x0F;
acl_permset = consumer.consume_u32();
acl_tag = consumer.consume_byte() & 0x0F;
acl_qual = consumer.consume_u32();
acl_name = consumer.consume_string(32);
archive_entry_acl_add_entry(entry, acl_type, acl_permset, acl_tag, acl_qual, acl_name);
}
// Exercise ACL text conversion functions (archive_acl_to_text_* are uncovered)
ssize_t text_len;
char *acl_text = archive_entry_acl_to_text(entry, &text_len, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
if (acl_text) {
// Parse the text back
archive_entry_acl_from_text(entry, acl_text, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
free(acl_text);
}
acl_text = archive_entry_acl_to_text(entry, &text_len, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
if (acl_text) {
free(acl_text);
}
acl_text = archive_entry_acl_to_text(entry, &text_len, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
if (acl_text) {
free(acl_text);
}
// Exercise wide character versions
wchar_t *acl_text_w = archive_entry_acl_to_text_w(entry, &text_len, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
if (acl_text_w) {
free(acl_text_w);
}
// Get pathname variants
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_pathname_utf8(entry);
// Clone the entry
struct archive_entry *entry2 = archive_entry_clone(entry);
if (entry2) {
archive_entry_free(entry2);
}
// Clear and reuse
archive_entry_clear(entry);
archive_entry_free(entry);
return 0;
}

View File

@ -1,65 +0,0 @@
/*
* Compression filter fuzzer for libarchive
* Tests decompression of gzip, bzip2, xz, lzma, zstd, lz4, etc.
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 256 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
// Enable raw format (just decompress, no archive format)
archive_read_support_format_raw(a);
// Enable all compression filters
archive_read_support_filter_all(a);
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(8192, 0);
struct archive_entry *entry;
if (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
// Get filter info
int filter_count = archive_filter_count(a);
for (int i = 0; i < filter_count; i++) {
archive_filter_name(a, i);
archive_filter_code(a, i);
archive_filter_bytes(a, i);
}
// Read all decompressed data
ssize_t total = 0;
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0) {
total += r;
// Limit total decompressed size to prevent zip bombs
if (total > 10 * 1024 * 1024) {
break;
}
}
}
archive_read_free(a);
return 0;
}

View File

@ -1,33 +0,0 @@
# Compression filter dictionary
# GZIP magic
"\x1f\x8b"
"\x1f\x8b\x08"
# BZIP2 magic
"BZh"
"BZ0"
# XZ magic
"\xfd7zXZ\x00"
# LZMA magic
"\x5d\x00\x00"
# ZSTD magic
"\x28\xb5\x2f\xfd"
# LZ4 magic
"\x04\x22\x4d\x18"
# Compress (.Z) magic
"\x1f\x9d"
# LZIP magic
"LZIP"
# LRZIP magic
"LRZI"
# LZO magic
"\x89LZO\x00\x0d\x0a\x1a\x0a"

View File

@ -1,10 +0,0 @@
[libfuzzer]
max_len = 262144
timeout = 30
rss_limit_mb = 2048
[honggfuzz]
timeout = 30
[afl]
timeout = 30

View File

@ -3,7 +3,20 @@
#include <vector>
#include "archive.h"
#include "fuzz_helpers.h"
struct Buffer {
const uint8_t *buf;
size_t len;
};
ssize_t reader_callback(struct archive *a, void *client_data,
const void **block) {
Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
*block = buffer->buf;
ssize_t len = buffer->len;
buffer->len = 0;
return len;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
int ret;
@ -13,7 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
Buffer buffer = {buf, len, 0};
Buffer buffer = {buf, len};
archive_read_open(a, &buffer, NULL, reader_callback, NULL);
std::vector<uint8_t> data_buffer(getpagesize(), 0);

View File

@ -1,76 +0,0 @@
# General libarchive dictionary covering multiple formats
# TAR magic
"ustar"
"ustar\x00"
"ustar \x00"
"\x00\x00"
# ZIP magic
"PK\x03\x04"
"PK\x05\x06"
"PK\x01\x02"
"PK\x07\x08"
# 7z magic
"7z\xbc\xaf\x27\x1c"
# RAR magic
"Rar!\x1a\x07\x00"
"Rar!\x1a\x07\x01\x00"
# XAR magic
"xar!"
# CPIO magic
"\xc7\x71"
"070701"
"070702"
"070707"
# CAB magic
"MSCF"
# LHA magic
"-lh"
"-lz"
# AR magic
"!<arch>\x0a"
# ISO9660 magic
"CD001"
# GZIP magic
"\x1f\x8b"
# BZIP2 magic
"BZ"
"BZh"
# XZ magic
"\xfd7zXZ\x00"
# LZMA magic
"\x5d\x00\x00"
# ZSTD magic
"\x28\xb5\x2f\xfd"
# LZ4 magic
"\x04\x22\x4d\x18"
# Common paths
"/"
"./"
"../"
"./test"
"test.txt"
"test/"
# Common attributes
"\x00\x00\x00\x00"
"\xff\xff\xff\xff"
# Passphrase
"password"

View File

@ -1,9 +0,0 @@
[libfuzzer]
max_len = 524288
timeout = 30
[honggfuzz]
timeout = 30
[afl]
timeout = 30

View File

@ -1,58 +0,0 @@
/*
* ISO9660 format fuzzer for libarchive
* Tests ISO, Joliet, and Rock Ridge extensions
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 1024 * 1024; // 1MB for ISO images
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_iso9660(a);
archive_read_support_filter_all(a);
// Set options to test various ISO extensions
archive_read_set_options(a, "iso9660:joliet,iso9660:rockridge");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_symlink(entry);
archive_entry_hardlink(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,36 +0,0 @@
# ISO9660 format dictionary
# Volume descriptor type
"\x00"
"\x01"
"\x02"
"\xff"
# Standard identifier
"CD001"
# Volume descriptor version
"\x01"
# Joliet escape sequences
"%/@"
"%/C"
"%/E"
# Rock Ridge signatures
"SP"
"RR"
"CE"
"PX"
"PN"
"SL"
"NM"
"CL"
"PL"
"RE"
"TF"
"SF"
# System use
"ER"
"ES"

View File

@ -1,10 +0,0 @@
[libfuzzer]
max_len = 1048576
timeout = 60
rss_limit_mb = 2048
[honggfuzz]
timeout = 60
[afl]
timeout = 60

View File

@ -1,54 +0,0 @@
/*
* LHA/LZH format fuzzer for libarchive
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_lha(a);
archive_read_support_filter_all(a);
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_uid(entry);
archive_entry_gid(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,26 +0,0 @@
# LHA/LZH format dictionary
# Compression methods
"-lh0-"
"-lh1-"
"-lh2-"
"-lh3-"
"-lh4-"
"-lh5-"
"-lh6-"
"-lh7-"
"-lhd-"
"-lzs-"
"-lz4-"
"-lz5-"
# OS type
"\x00"
"\x4d"
"\x55"
# Header levels
"\x00"
"\x01"
"\x02"
"\x03"

View File

@ -1,110 +0,0 @@
/*
* Archive entry link resolver fuzzer for libarchive
* Targets archive_entry_linkify (complexity: 775, zero coverage)
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 64 * 1024; // 64KB
// Simple data consumer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
DataConsumer consumer(buf, len);
// Create a link resolver
struct archive_entry_linkresolver *resolver = archive_entry_linkresolver_new();
if (resolver == NULL) {
return 0;
}
// Set the format strategy based on input
uint8_t strategy = consumer.consume_byte() % 5;
int format;
switch (strategy) {
case 0: format = ARCHIVE_FORMAT_TAR_GNUTAR; break;
case 1: format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE; break;
case 2: format = ARCHIVE_FORMAT_CPIO_POSIX; break;
case 3: format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC; break;
default: format = ARCHIVE_FORMAT_TAR_USTAR; break;
}
archive_entry_linkresolver_set_strategy(resolver, format);
// Create multiple entries to test linkify with hardlinks
struct archive_entry *entries[32];
int num_entries = 0;
while (!consumer.empty() && num_entries < 32 && consumer.remaining() > 20) {
struct archive_entry *entry = archive_entry_new();
if (entry == NULL) break;
// Set pathname
archive_entry_set_pathname(entry, consumer.consume_string(64));
// Set inode and device for hardlink detection
archive_entry_set_ino(entry, consumer.consume_i64());
archive_entry_set_dev(entry, consumer.consume_u32());
archive_entry_set_nlink(entry, (consumer.consume_byte() % 5) + 1);
// Set mode (regular file or directory)
uint8_t ftype = consumer.consume_byte() % 2;
mode_t mode = ftype ? (S_IFDIR | 0755) : (S_IFREG | 0644);
archive_entry_set_mode(entry, mode);
archive_entry_set_size(entry, consumer.consume_i64() & 0xFFFF);
archive_entry_set_uid(entry, consumer.consume_u32() & 0xFFFF);
archive_entry_set_gid(entry, consumer.consume_u32() & 0xFFFF);
entries[num_entries++] = entry;
}
// Now run all entries through the linkresolver
for (int i = 0; i < num_entries; i++) {
struct archive_entry *entry = entries[i];
struct archive_entry *spare = NULL;
// This is the main function we want to fuzz (zero coverage)
archive_entry_linkify(resolver, &entry, &spare);
// entry and spare may be modified by linkify
// We still need to free the original entries we allocated
if (spare != NULL) {
archive_entry_free(spare);
}
}
// Free remaining entries from the resolver
struct archive_entry *entry = NULL;
struct archive_entry *spare = NULL;
while (1) {
archive_entry_linkify(resolver, &entry, &spare);
if (entry == NULL)
break;
archive_entry_free(entry);
entry = NULL;
if (spare != NULL) {
archive_entry_free(spare);
spare = NULL;
}
}
// Free all our created entries
for (int i = 0; i < num_entries; i++) {
if (entries[i] != NULL) {
archive_entry_free(entries[i]);
}
}
archive_entry_linkresolver_free(resolver);
return 0;
}

View File

@ -1,96 +0,0 @@
/*
* Archive match fuzzer for libarchive
* Tests pattern matching, time matching, and owner matching
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 32 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
DataConsumer consumer(buf, len);
struct archive *match = archive_match_new();
if (match == NULL) {
return 0;
}
// Add various match patterns
while (!consumer.empty() && consumer.remaining() > 5) {
uint8_t match_type = consumer.consume_byte() % 6;
switch (match_type) {
case 0: {
// Pattern exclusion
const char *pattern = consumer.consume_string(64);
archive_match_exclude_pattern(match, pattern);
break;
}
case 1: {
// Pattern inclusion
const char *pattern = consumer.consume_string(64);
archive_match_include_pattern(match, pattern);
break;
}
case 2: {
// Time comparison (newer than)
int64_t sec = consumer.consume_i64();
int64_t nsec = consumer.consume_i64() % 1000000000;
archive_match_include_time(match, ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER,
sec, nsec);
break;
}
case 3: {
// Time comparison (older than)
int64_t sec = consumer.consume_i64();
int64_t nsec = consumer.consume_i64() % 1000000000;
archive_match_include_time(match, ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER,
sec, nsec);
break;
}
case 4: {
// UID inclusion
int64_t uid = consumer.consume_i64() & 0xFFFF;
archive_match_include_uid(match, uid);
break;
}
case 5: {
// GID inclusion
int64_t gid = consumer.consume_i64() & 0xFFFF;
archive_match_include_gid(match, gid);
break;
}
}
}
// Create a test entry and check if it matches
struct archive_entry *entry = archive_entry_new();
if (entry) {
archive_entry_set_pathname(entry, "test/file.txt");
archive_entry_set_mtime(entry, 1234567890, 0);
archive_entry_set_uid(entry, 1000);
archive_entry_set_gid(entry, 1000);
archive_entry_set_mode(entry, 0644 | 0100000); // Regular file
// Test matching
archive_match_path_excluded(match, entry);
archive_match_time_excluded(match, entry);
archive_match_owner_excluded(match, entry);
archive_match_excluded(match, entry);
archive_entry_free(entry);
}
archive_match_free(match);
return 0;
}

View File

@ -1,61 +0,0 @@
/*
* MTREE format fuzzer for libarchive
* Tests mtree manifest parsing
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 256 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_mtree(a);
archive_read_support_filter_all(a);
// Enable checkfs option to test more code paths
archive_read_set_options(a, "mtree:checkfs");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_uid(entry);
archive_entry_gid(entry);
archive_entry_uname(entry);
archive_entry_gname(entry);
archive_entry_symlink(entry);
archive_entry_fflags_text(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,47 +0,0 @@
# MTREE format dictionary
# Keywords
"/set"
"/unset"
".."
# File types
"type=file"
"type=dir"
"type=link"
"type=block"
"type=char"
"type=fifo"
"type=socket"
# Attributes
"mode="
"uid="
"gid="
"uname="
"gname="
"size="
"time="
"link="
"cksum="
"md5="
"md5digest="
"sha1="
"sha1digest="
"sha256="
"sha256digest="
"sha384="
"sha384digest="
"sha512="
"sha512digest="
"rmd160="
"rmd160digest="
"flags="
"nlink="
"inode="
"device="
"resdevice="
"contents="
"optional"
"ignore"
"nochange"

View File

@ -1,61 +0,0 @@
/*
* RAR5 format specific fuzzer for libarchive
* Targets RAR5 parsing code paths
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024; // 512KB
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
// Enable RAR5 format specifically
archive_read_support_format_rar5(a);
// Enable common filters
archive_read_support_filter_all(a);
// Set passphrase for encrypted archives
archive_read_add_passphrase(a, "password");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
// Exercise entry metadata access
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_is_encrypted(entry);
// Read data
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,37 +0,0 @@
# RAR5 format dictionary
# Magic bytes (RAR5 signature)
"Rar!\x1a\x07\x01\x00"
"\x52\x61\x72\x21\x1a\x07\x01\x00"
# Common header types
"\x01"
"\x02"
"\x03"
"\x04"
"\x05"
# Common flags
"\x00\x00"
"\x01\x00"
"\x02\x00"
"\x04\x00"
# Compression methods
"\x00"
"\x01"
"\x02"
"\x03"
"\x04"
"\x05"
# File attributes
"\x20\x00\x00\x00"
"\x10\x00\x00\x00"
# Encryption marker
"\x80"
"password"
"Password"
# End of archive
"\x1d\x77\x56\x51\x03\x05\x04\x00"

View File

@ -1,56 +0,0 @@
/*
* RAR v4 format fuzzer for libarchive
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_rar(a);
archive_read_support_filter_all(a);
// Add passphrase for encrypted RARs
archive_read_add_passphrase(a, "password");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_is_encrypted(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,76 +0,0 @@
/*
* Archive read disk fuzzer for libarchive
* Tests filesystem traversal and entry creation from paths
* Security-critical: path traversal, symlink handling
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 16 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
DataConsumer consumer(buf, len);
struct archive *a = archive_read_disk_new();
if (a == NULL) {
return 0;
}
// Configure disk reader behavior
uint8_t flags = consumer.consume_byte();
if (flags & 0x01) {
archive_read_disk_set_symlink_logical(a);
} else if (flags & 0x02) {
archive_read_disk_set_symlink_physical(a);
} else {
archive_read_disk_set_symlink_hybrid(a);
}
archive_read_disk_set_standard_lookup(a);
// Set behavior flags
int behavior = 0;
if (flags & 0x04) behavior |= ARCHIVE_READDISK_RESTORE_ATIME;
if (flags & 0x08) behavior |= ARCHIVE_READDISK_HONOR_NODUMP;
if (flags & 0x10) behavior |= ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS;
archive_read_disk_set_behavior(a, behavior);
// Create an entry and test entry_from_file with various paths
struct archive_entry *entry = archive_entry_new();
if (entry) {
// Test with /tmp (safe, always exists)
archive_entry_copy_pathname(entry, "/tmp");
archive_read_disk_entry_from_file(a, entry, -1, NULL);
// Get entry info
archive_entry_pathname(entry);
archive_entry_size(entry);
archive_entry_mode(entry);
archive_entry_uid(entry);
archive_entry_gid(entry);
// Test name lookups
archive_read_disk_gname(a, 0);
archive_read_disk_uname(a, 0);
archive_read_disk_gname(a, 1000);
archive_read_disk_uname(a, 1000);
archive_entry_free(entry);
}
archive_read_free(a);
return 0;
}

View File

@ -1,110 +0,0 @@
/*
* Archive roundtrip fuzzer for libarchive
* Writes an archive then reads it back - tests write/read consistency
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 64 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len < 10 || len > kMaxInputSize) {
return 0;
}
DataConsumer consumer(buf, len);
std::vector<uint8_t> archive_data;
archive_data.reserve(len * 2);
// Phase 1: Write an archive
struct archive *writer = archive_write_new();
if (writer == NULL) {
return 0;
}
// Select format
uint8_t format = consumer.consume_byte() % 5;
switch (format) {
case 0: archive_write_set_format_pax_restricted(writer); break;
case 1: archive_write_set_format_ustar(writer); break;
case 2: archive_write_set_format_cpio_newc(writer); break;
case 3: archive_write_set_format_zip(writer); break;
default: archive_write_set_format_gnutar(writer); break;
}
archive_write_add_filter_none(writer);
// Open to memory
size_t used = 0;
archive_data.resize(len * 4);
if (archive_write_open_memory(writer, archive_data.data(), archive_data.size(), &used) != ARCHIVE_OK) {
archive_write_free(writer);
return 0;
}
// Write entries
int entry_count = 0;
while (!consumer.empty() && entry_count < 5 && consumer.remaining() > 10) {
struct archive_entry *entry = archive_entry_new();
if (entry == NULL) break;
archive_entry_set_pathname(entry, consumer.consume_string(32));
archive_entry_set_mode(entry, S_IFREG | 0644);
archive_entry_set_uid(entry, consumer.consume_u32() & 0xFFFF);
archive_entry_set_gid(entry, consumer.consume_u32() & 0xFFFF);
uint8_t data_buf[256];
size_t data_len = consumer.consume_bytes(data_buf, 256);
archive_entry_set_size(entry, data_len);
if (archive_write_header(writer, entry) == ARCHIVE_OK && data_len > 0) {
archive_write_data(writer, data_buf, data_len);
}
archive_entry_free(entry);
entry_count++;
}
archive_write_close(writer);
archive_write_free(writer);
if (used == 0) {
return 0;
}
// Phase 2: Read the archive back
struct archive *reader = archive_read_new();
if (reader == NULL) {
return 0;
}
archive_read_support_format_all(reader);
archive_read_support_filter_all(reader);
if (archive_read_open_memory(reader, archive_data.data(), used) != ARCHIVE_OK) {
archive_read_free(reader);
return 0;
}
std::vector<uint8_t> read_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(reader, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_size(entry);
ssize_t r;
while ((r = archive_read_data(reader, read_buffer.data(), read_buffer.size())) > 0)
;
}
archive_read_free(reader);
return 0;
}

View File

@ -1,3 +0,0 @@
[libfuzzer]
max_len = 65536
timeout = 30

View File

@ -1,125 +0,0 @@
/*
* Archive seek/read fuzzer for libarchive
* Tests seeking within archives and reading at random positions
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 256 * 1024;
struct SeekableBuffer {
const uint8_t *buf;
size_t len;
size_t pos;
};
static ssize_t seek_read_callback(struct archive *a, void *client_data,
const void **block) {
(void)a;
SeekableBuffer *buffer = reinterpret_cast<SeekableBuffer *>(client_data);
if (buffer->pos >= buffer->len) {
*block = NULL;
return 0;
}
*block = buffer->buf + buffer->pos;
size_t avail = buffer->len - buffer->pos;
size_t to_read = (avail > 4096) ? 4096 : avail;
buffer->pos += to_read;
return to_read;
}
static la_int64_t seek_callback(struct archive *a, void *client_data,
la_int64_t offset, int whence) {
(void)a;
SeekableBuffer *buffer = reinterpret_cast<SeekableBuffer *>(client_data);
la_int64_t new_pos;
switch (whence) {
case SEEK_SET:
new_pos = offset;
break;
case SEEK_CUR:
new_pos = static_cast<la_int64_t>(buffer->pos) + offset;
break;
case SEEK_END:
new_pos = static_cast<la_int64_t>(buffer->len) + offset;
break;
default:
return ARCHIVE_FATAL;
}
if (new_pos < 0) new_pos = 0;
if (new_pos > static_cast<la_int64_t>(buffer->len))
new_pos = static_cast<la_int64_t>(buffer->len);
buffer->pos = static_cast<size_t>(new_pos);
return new_pos;
}
static la_int64_t skip_callback(struct archive *a, void *client_data,
la_int64_t request) {
(void)a;
SeekableBuffer *buffer = reinterpret_cast<SeekableBuffer *>(client_data);
size_t avail = buffer->len - buffer->pos;
la_int64_t to_skip = (request > static_cast<la_int64_t>(avail))
? static_cast<la_int64_t>(avail)
: request;
buffer->pos += static_cast<size_t>(to_skip);
return to_skip;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
// Enable formats that benefit from seeking
archive_read_support_format_zip_seekable(a);
archive_read_support_format_7zip(a);
archive_read_support_format_rar(a);
archive_read_support_format_rar5(a);
archive_read_support_format_iso9660(a);
archive_read_support_filter_all(a);
SeekableBuffer buffer = {buf, len, 0};
archive_read_set_read_callback(a, seek_read_callback);
archive_read_set_seek_callback(a, seek_callback);
archive_read_set_skip_callback(a, skip_callback);
archive_read_set_callback_data(a, &buffer);
if (archive_read_open1(a) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
int entry_count = 0;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK && entry_count < 50) {
archive_entry_pathname(entry);
archive_entry_size(entry);
// Read data which may trigger seeks
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
entry_count++;
}
archive_read_free(a);
return 0;
}

View File

@ -1,3 +0,0 @@
[libfuzzer]
max_len = 262144
timeout = 30

View File

@ -1,144 +0,0 @@
/*
* Archive string/encoding conversion fuzzer for libarchive
* Tests character encoding conversions which are often vulnerability sources
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 32 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive_entry *entry = archive_entry_new();
if (entry == NULL) {
return 0;
}
// Reserve some bytes for control
if (len < 4) {
archive_entry_free(entry);
return 0;
}
uint8_t test_type = buf[0];
const char *str = reinterpret_cast<const char*>(buf + 1);
size_t str_len = len - 1;
// Ensure null termination for string operations
char *safe_str = static_cast<char*>(malloc(str_len + 1));
if (safe_str == NULL) {
archive_entry_free(entry);
return 0;
}
memcpy(safe_str, str, str_len);
safe_str[str_len] = '\0';
// Test various string functions based on type
switch (test_type % 10) {
case 0:
// Pathname conversions
archive_entry_set_pathname(entry, safe_str);
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_pathname_utf8(entry);
break;
case 1:
// Symlink conversions
archive_entry_set_symlink(entry, safe_str);
archive_entry_symlink(entry);
archive_entry_symlink_w(entry);
archive_entry_symlink_utf8(entry);
break;
case 2:
// Hardlink conversions
archive_entry_set_hardlink(entry, safe_str);
archive_entry_hardlink(entry);
archive_entry_hardlink_w(entry);
archive_entry_hardlink_utf8(entry);
break;
case 3:
// Username conversions
archive_entry_set_uname(entry, safe_str);
archive_entry_uname(entry);
archive_entry_uname_w(entry);
archive_entry_uname_utf8(entry);
break;
case 4:
// Group name conversions
archive_entry_set_gname(entry, safe_str);
archive_entry_gname(entry);
archive_entry_gname_w(entry);
archive_entry_gname_utf8(entry);
break;
case 5:
// Copy functions
archive_entry_copy_pathname(entry, safe_str);
archive_entry_copy_symlink(entry, safe_str);
archive_entry_copy_hardlink(entry, safe_str);
break;
case 6:
// UTF-8 specific
archive_entry_update_pathname_utf8(entry, safe_str);
archive_entry_update_symlink_utf8(entry, safe_str);
archive_entry_update_hardlink_utf8(entry, safe_str);
break;
case 7:
// Fflags text
archive_entry_copy_fflags_text(entry, safe_str);
archive_entry_fflags_text(entry);
break;
case 8:
// ACL text parsing
archive_entry_acl_from_text(entry, safe_str, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
archive_entry_acl_from_text(entry, safe_str, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
archive_entry_acl_from_text(entry, safe_str, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
break;
case 9: {
// Wide character operations
size_t wlen = str_len;
wchar_t *wstr = static_cast<wchar_t*>(malloc((wlen + 1) * sizeof(wchar_t)));
if (wstr) {
mbstowcs(wstr, safe_str, wlen);
wstr[wlen] = L'\0';
archive_entry_copy_pathname_w(entry, wstr);
archive_entry_pathname_w(entry);
archive_entry_copy_symlink_w(entry, wstr);
archive_entry_symlink_w(entry);
free(wstr);
}
break;
}
}
// Clone and compare
struct archive_entry *entry2 = archive_entry_clone(entry);
if (entry2) {
archive_entry_free(entry2);
}
free(safe_str);
archive_entry_free(entry);
return 0;
}

View File

@ -1,86 +0,0 @@
/*
* TAR format fuzzer for libarchive
* Tests all TAR variants: ustar, pax, gnutar, v7, oldgnu
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_tar(a);
archive_read_support_format_gnutar(a);
archive_read_support_filter_all(a);
// Enable various TAR options
archive_read_set_options(a, "tar:read_concatenated_archives,tar:mac-ext");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
// Exercise all metadata accessors
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_atime(entry);
archive_entry_ctime(entry);
archive_entry_mode(entry);
archive_entry_uid(entry);
archive_entry_gid(entry);
archive_entry_uname(entry);
archive_entry_gname(entry);
archive_entry_symlink(entry);
archive_entry_hardlink(entry);
archive_entry_rdev(entry);
archive_entry_devmajor(entry);
archive_entry_devminor(entry);
// Test sparse file handling
archive_entry_sparse_reset(entry);
int64_t offset, length;
while (archive_entry_sparse_next(entry, &offset, &length) == ARCHIVE_OK) {
(void)offset;
(void)length;
}
// Test xattr handling
archive_entry_xattr_reset(entry);
const char *name;
const void *value;
size_t size;
while (archive_entry_xattr_next(entry, &name, &value, &size) == ARCHIVE_OK) {
(void)name;
(void)value;
(void)size;
}
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,51 +0,0 @@
# TAR format dictionary
# USTAR magic
"ustar"
"ustar\x00"
"ustar \x00"
# GNU tar magic
"GNUtar "
"GNUtar\x00"
# Common header field values
"00000000000"
"0000644"
"0000755"
"0000777"
# Type flags
"0"
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"g"
"x"
"L"
"K"
# PAX keywords
"path="
"linkpath="
"uname="
"gname="
"uid="
"gid="
"size="
"mtime="
"atime="
"ctime="
"SCHILY.xattr."
"LIBARCHIVE.xattr."
# Sparse headers
"GNU.sparse.major="
"GNU.sparse.minor="
"GNU.sparse.name="
"GNU.sparse.realsize="
"GNU.sparse.map="

View File

@ -1,50 +0,0 @@
/*
* WARC (Web Archive) format fuzzer for libarchive
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_warc(a);
archive_read_support_filter_all(a);
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,34 +0,0 @@
# WARC format dictionary
# Version
"WARC/1.0"
"WARC/1.1"
"WARC/0.17"
"WARC/0.18"
# Record types
"warcinfo"
"response"
"resource"
"request"
"metadata"
"revisit"
"conversion"
"continuation"
# Headers
"WARC-Type:"
"WARC-Record-ID:"
"WARC-Date:"
"WARC-Target-URI:"
"Content-Length:"
"Content-Type:"
"WARC-Block-Digest:"
"WARC-Payload-Digest:"
"WARC-Concurrent-To:"
"WARC-Refers-To:"
# Content types
"application/warc-fields"
"application/http;msgtype=request"
"application/http;msgtype=response"

View File

@ -1,125 +0,0 @@
/*
* Archive write disk fuzzer for libarchive
* Tests extraction to filesystem
* Security-critical: path traversal, permission handling, symlink attacks
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 64 * 1024;
static char g_temp_dir[256] = {0};
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
(void)argc;
(void)argv;
// Create a temporary directory for extraction
snprintf(g_temp_dir, sizeof(g_temp_dir), "/tmp/fuzz_extract_XXXXXX");
if (mkdtemp(g_temp_dir) == NULL) {
g_temp_dir[0] = '\0';
}
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
if (g_temp_dir[0] == '\0') {
return 0;
}
DataConsumer consumer(buf, len);
struct archive *disk = archive_write_disk_new();
if (disk == NULL) {
return 0;
}
// Configure write disk options
uint8_t opt_flags = consumer.consume_byte();
int flags = 0;
if (opt_flags & 0x01) flags |= ARCHIVE_EXTRACT_TIME;
if (opt_flags & 0x02) flags |= ARCHIVE_EXTRACT_PERM;
if (opt_flags & 0x04) flags |= ARCHIVE_EXTRACT_ACL;
if (opt_flags & 0x08) flags |= ARCHIVE_EXTRACT_FFLAGS;
if (opt_flags & 0x10) flags |= ARCHIVE_EXTRACT_OWNER;
if (opt_flags & 0x20) flags |= ARCHIVE_EXTRACT_XATTR;
if (opt_flags & 0x40) flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;
if (opt_flags & 0x80) flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
archive_write_disk_set_options(disk, flags);
archive_write_disk_set_standard_lookup(disk);
// Create entries to extract
int entry_count = 0;
while (!consumer.empty() && entry_count < 5 && consumer.remaining() > 20) {
struct archive_entry *entry = archive_entry_new();
if (entry == NULL) break;
// Build a safe path within our temp directory
char safe_path[512];
const char *name = consumer.consume_string(32);
snprintf(safe_path, sizeof(safe_path), "%s/%s", g_temp_dir, name);
// Sanitize path to prevent traversal
char *p = safe_path;
while (*p) {
if (p[0] == '.' && p[1] == '.') {
p[0] = '_';
p[1] = '_';
}
p++;
}
archive_entry_set_pathname(entry, safe_path);
uint8_t ftype = consumer.consume_byte() % 3;
mode_t mode;
switch (ftype) {
case 0: mode = S_IFREG | 0644; break;
case 1: mode = S_IFDIR | 0755; break;
default: mode = S_IFREG | 0644; break;
}
archive_entry_set_mode(entry, mode);
archive_entry_set_uid(entry, 1000);
archive_entry_set_gid(entry, 1000);
archive_entry_set_mtime(entry, consumer.consume_i64(), 0);
// Write the entry header
if (archive_write_header(disk, entry) == ARCHIVE_OK) {
if (S_ISREG(mode)) {
uint8_t data_buf[256];
size_t data_len = consumer.consume_bytes(data_buf, 256);
archive_entry_set_size(entry, data_len);
if (data_len > 0) {
archive_write_data(disk, data_buf, data_len);
}
}
archive_write_finish_entry(disk);
}
archive_entry_free(entry);
entry_count++;
}
archive_write_close(disk);
archive_write_free(disk);
// Clean up extracted files using nftw (safer than system())
remove_directory_tree(g_temp_dir);
// Recreate the temp directory for next iteration
mkdir(g_temp_dir, 0700);
return 0;
}

View File

@ -1,3 +0,0 @@
[libfuzzer]
max_len = 65536
timeout = 30

View File

@ -1,132 +0,0 @@
/*
* Archive write fuzzer for libarchive
* Tests archive creation and writing code paths
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 64 * 1024; // 64KB
// Simple data consumer
// Memory write callback
static std::vector<uint8_t> *g_output = nullptr;
static ssize_t write_callback(struct archive *a, void *client_data, const void *buffer, size_t length) {
(void)a;
(void)client_data;
if (g_output && length > 0) {
const uint8_t *buf = static_cast<const uint8_t*>(buffer);
g_output->insert(g_output->end(), buf, buf + length);
}
return length;
}
static int close_callback(struct archive *a, void *client_data) {
(void)a;
(void)client_data;
return ARCHIVE_OK;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
DataConsumer consumer(buf, len);
std::vector<uint8_t> output;
g_output = &output;
struct archive *a = archive_write_new();
if (a == NULL) {
return 0;
}
// Select format based on input
uint8_t format_choice = consumer.consume_byte() % 8;
switch (format_choice) {
case 0: archive_write_set_format_pax_restricted(a); break;
case 1: archive_write_set_format_gnutar(a); break;
case 2: archive_write_set_format_ustar(a); break;
case 3: archive_write_set_format_cpio_newc(a); break;
case 4: archive_write_set_format_zip(a); break;
case 5: archive_write_set_format_7zip(a); break;
case 6: archive_write_set_format_xar(a); break;
default: archive_write_set_format_pax(a); break;
}
// Select compression based on input
uint8_t filter_choice = consumer.consume_byte() % 6;
switch (filter_choice) {
case 0: archive_write_add_filter_gzip(a); break;
case 1: archive_write_add_filter_bzip2(a); break;
case 2: archive_write_add_filter_xz(a); break;
case 3: archive_write_add_filter_zstd(a); break;
case 4: archive_write_add_filter_none(a); break;
default: archive_write_add_filter_none(a); break;
}
// Open for writing to memory
if (archive_write_open(a, NULL, NULL, write_callback, close_callback) != ARCHIVE_OK) {
archive_write_free(a);
g_output = nullptr;
return 0;
}
// Create entries based on remaining input
int entry_count = 0;
while (!consumer.empty() && entry_count < 10 && consumer.remaining() > 20) {
struct archive_entry *entry = archive_entry_new();
if (entry == NULL) break;
// Set entry properties
archive_entry_set_pathname(entry, consumer.consume_string(64));
uint8_t ftype = consumer.consume_byte() % 4;
mode_t mode;
switch (ftype) {
case 0: mode = S_IFREG | 0644; break;
case 1: mode = S_IFDIR | 0755; break;
case 2: mode = S_IFLNK | 0777; break;
default: mode = S_IFREG | 0644; break;
}
archive_entry_set_mode(entry, mode);
archive_entry_set_uid(entry, consumer.consume_u32() & 0xFFFF);
archive_entry_set_gid(entry, consumer.consume_u32() & 0xFFFF);
archive_entry_set_mtime(entry, consumer.consume_i64(), 0);
// For regular files, write some data
if (S_ISREG(mode)) {
uint8_t data_buf[1024];
size_t data_len = consumer.consume_bytes(data_buf, 1024);
archive_entry_set_size(entry, data_len);
if (archive_write_header(a, entry) == ARCHIVE_OK && data_len > 0) {
archive_write_data(a, data_buf, data_len);
}
} else if (S_ISLNK(mode)) {
archive_entry_set_symlink(entry, consumer.consume_string(64));
archive_entry_set_size(entry, 0);
archive_write_header(a, entry);
} else {
archive_entry_set_size(entry, 0);
archive_write_header(a, entry);
}
archive_entry_free(entry);
entry_count++;
}
archive_write_close(a);
archive_write_free(a);
g_output = nullptr;
return 0;
}

View File

@ -1,60 +0,0 @@
/*
* XAR format specific fuzzer for libarchive
* Targets xar_read_header and XAR parsing code paths
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024; // 512KB
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
// Enable XAR format specifically
archive_read_support_format_xar(a);
// Enable common filters
archive_read_support_filter_all(a);
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
// Exercise entry metadata access
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_filetype(entry);
archive_entry_uid(entry);
archive_entry_gid(entry);
// Read data
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,44 +0,0 @@
# XAR format dictionary
# Magic bytes
"xar!"
"\x78\x61\x72\x21"
# XML elements commonly in XAR
"<xar>"
"</xar>"
"<toc>"
"</toc>"
"<file>"
"</file>"
"<name>"
"</name>"
"<data>"
"</data>"
"<encoding>"
"</encoding>"
"<archived-checksum>"
"<extracted-checksum>"
"<offset>"
"<length>"
"<size>"
"<mode>"
"<uid>"
"<gid>"
"<user>"
"<group>"
"<type>"
"<mtime>"
"<atime>"
"<ctime>"
# Compression types
"application/octet-stream"
"application/x-gzip"
"application/x-bzip2"
"application/x-lzma"
# Checksum types
"sha1"
"md5"
"sha256"
"sha512"

View File

@ -1,10 +0,0 @@
[libfuzzer]
max_len = 524288
timeout = 60
rss_limit_mb = 2048
[honggfuzz]
timeout = 60
[afl]
timeout = 60

View File

@ -1,68 +0,0 @@
/*
* ZIP format fuzzer for libarchive
* Tests ZIP with various compression methods and encryption
*/
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "archive.h"
#include "archive_entry.h"
#include "fuzz_helpers.h"
static constexpr size_t kMaxInputSize = 512 * 1024;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
if (len == 0 || len > kMaxInputSize) {
return 0;
}
struct archive *a = archive_read_new();
if (a == NULL) {
return 0;
}
archive_read_support_format_zip(a);
archive_read_support_filter_all(a);
// Add passphrase for encrypted ZIPs
archive_read_add_passphrase(a, "password");
archive_read_add_passphrase(a, "test");
archive_read_add_passphrase(a, "");
// Enable ZIP options
archive_read_set_options(a, "zip:ignorecrc32");
Buffer buffer = {buf, len, 0};
if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
archive_read_free(a);
return 0;
}
std::vector<uint8_t> data_buffer(4096, 0);
struct archive_entry *entry;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
archive_entry_pathname(entry);
archive_entry_pathname_w(entry);
archive_entry_size(entry);
archive_entry_mtime(entry);
archive_entry_mode(entry);
archive_entry_is_encrypted(entry);
archive_entry_is_data_encrypted(entry);
archive_entry_is_metadata_encrypted(entry);
// Check compression name
archive_format_name(a);
archive_filter_name(a, 0);
ssize_t r;
while ((r = archive_read_data(a, data_buffer.data(), data_buffer.size())) > 0)
;
}
archive_read_free(a);
return 0;
}

View File

@ -1,43 +0,0 @@
# ZIP format dictionary
# Signatures
"PK\x03\x04"
"PK\x01\x02"
"PK\x05\x06"
"PK\x06\x06"
"PK\x06\x07"
"PK\x07\x08"
# Version needed
"\x14\x00"
"\x0a\x00"
"\x2d\x00"
"\x3f\x00"
# Compression methods
"\x00\x00"
"\x08\x00"
"\x09\x00"
"\x0c\x00"
"\x0e\x00"
"\x5f\x00"
# General purpose flags
"\x00\x00"
"\x01\x00"
"\x08\x00"
"\x09\x00"
# Extra field IDs
"\x01\x00"
"\x07\x00"
"\x09\x00"
"\x0a\x00"
"\x15\x00"
"\x17\x00"
"\x55\x54"
"\x75\x78"
# Encryption
"\x01\x99"
"\x02\x99"

View File

@ -1,131 +1,16 @@
#!/bin/bash -eu
# Build the project
# build the project
./build/autogen.sh
./configure
make -j$(nproc) all
FUZZ_DIR=$SRC/libarchive/contrib/oss-fuzz
TEST_DIR=$SRC/libarchive/libarchive/test
# build seed
cp $SRC/libarchive/contrib/oss-fuzz/corpus.zip\
$OUT/libarchive_fuzzer_seed_corpus.zip
# Common libraries for linking
LIBS=".libs/libarchive.a -Wl,-Bstatic -lbz2 -llzo2 -lxml2 -llzma -lz -lcrypto -llz4 -licuuc -licudata -Wl,-Bdynamic"
# Function to build a fuzzer
build_fuzzer() {
local name=$1
local source=$2
echo "Building fuzzer: $name"
$CXX $CXXFLAGS -Ilibarchive \
"$source" \
-o "$OUT/$name" $LIB_FUZZING_ENGINE $LIBS
}
# Build all format-specific fuzzers
FUZZERS=(
"libarchive_fuzzer"
"libarchive_tar_fuzzer"
"libarchive_zip_fuzzer"
"libarchive_7zip_fuzzer"
"libarchive_rar_fuzzer"
"libarchive_rar5_fuzzer"
"libarchive_xar_fuzzer"
"libarchive_cab_fuzzer"
"libarchive_lha_fuzzer"
"libarchive_iso9660_fuzzer"
"libarchive_cpio_fuzzer"
"libarchive_warc_fuzzer"
"libarchive_mtree_fuzzer"
"libarchive_ar_fuzzer"
"libarchive_filter_fuzzer"
"libarchive_entry_fuzzer"
"libarchive_write_fuzzer"
"libarchive_linkify_fuzzer"
"libarchive_match_fuzzer"
"libarchive_encryption_fuzzer"
"libarchive_read_disk_fuzzer"
"libarchive_write_disk_fuzzer"
"libarchive_seek_fuzzer"
"libarchive_string_fuzzer"
"libarchive_roundtrip_fuzzer"
)
for fuzzer in "${FUZZERS[@]}"; do
if [ -f "$FUZZ_DIR/${fuzzer}.cc" ]; then
build_fuzzer "$fuzzer" "$FUZZ_DIR/${fuzzer}.cc"
fi
done
# Copy dictionaries and options
cp "$FUZZ_DIR"/*.dict "$OUT/" 2>/dev/null || true
cp "$FUZZ_DIR"/*.options "$OUT/" 2>/dev/null || true
# Build seed corpora
echo "Building seed corpora..."
# Main fuzzer corpus (existing)
cp "$FUZZ_DIR/corpus.zip" "$OUT/libarchive_fuzzer_seed_corpus.zip"
# Function to create corpus from test files
create_corpus() {
local name=$1
local pattern=$2
local dir="/tmp/${name}_corpus"
mkdir -p "$dir"
for f in $TEST_DIR/$pattern; do
if [ -f "$f" ]; then
base=$(basename "$f" .uu)
uudecode -o "$dir/$base" "$f" 2>/dev/null || true
fi
done
if [ "$(ls -A $dir 2>/dev/null)" ]; then
zip -j "$OUT/${name}_seed_corpus.zip" "$dir"/* 2>/dev/null || true
echo "Created corpus for $name with $(ls $dir | wc -l) files"
fi
rm -rf "$dir"
}
# Create format-specific corpora
create_corpus "libarchive_tar_fuzzer" "test_compat_*tar*.uu"
create_corpus "libarchive_zip_fuzzer" "test_*zip*.uu"
create_corpus "libarchive_7zip_fuzzer" "test_read_format_7zip*.uu"
create_corpus "libarchive_rar_fuzzer" "test_read_format_rar_*.uu"
create_corpus "libarchive_rar5_fuzzer" "test_read_format_rar5*.uu"
create_corpus "libarchive_xar_fuzzer" "test_read_format_xar*.uu"
create_corpus "libarchive_cab_fuzzer" "test_read_format_cab*.uu"
create_corpus "libarchive_lha_fuzzer" "test_read_format_lha*.uu"
create_corpus "libarchive_iso9660_fuzzer" "test_read_format_iso*.uu"
create_corpus "libarchive_cpio_fuzzer" "test_compat_cpio*.uu"
create_corpus "libarchive_warc_fuzzer" "test_read_format_warc*.uu"
create_corpus "libarchive_mtree_fuzzer" "test_read_format_mtree*.uu"
create_corpus "libarchive_ar_fuzzer" "test_read_format_ar*.uu"
# Filter corpus - use compressed test files
mkdir -p /tmp/filter_corpus
for f in $TEST_DIR/*.gz.uu $TEST_DIR/*.bz2.uu $TEST_DIR/*.xz.uu $TEST_DIR/*.lz4.uu $TEST_DIR/*.zst.uu $TEST_DIR/*.Z.uu; do
if [ -f "$f" ]; then
base=$(basename "$f" .uu)
uudecode -o "/tmp/filter_corpus/$base" "$f" 2>/dev/null || true
fi
done
if [ "$(ls -A /tmp/filter_corpus 2>/dev/null)" ]; then
zip -j "$OUT/libarchive_filter_fuzzer_seed_corpus.zip" /tmp/filter_corpus/* 2>/dev/null || true
fi
rm -rf /tmp/filter_corpus
# Encryption corpus - encrypted archives
mkdir -p /tmp/encryption_corpus
for f in $TEST_DIR/*encrypt*.uu $TEST_DIR/*password*.uu; do
if [ -f "$f" ]; then
base=$(basename "$f" .uu)
uudecode -o "/tmp/encryption_corpus/$base" "$f" 2>/dev/null || true
fi
done
if [ "$(ls -A /tmp/encryption_corpus 2>/dev/null)" ]; then
zip -j "$OUT/libarchive_encryption_fuzzer_seed_corpus.zip" /tmp/encryption_corpus/* 2>/dev/null || true
fi
rm -rf /tmp/encryption_corpus
echo "Build complete! Built ${#FUZZERS[@]} fuzzers."
# build fuzzer(s)
$CXX $CXXFLAGS -Ilibarchive \
$SRC/libarchive/contrib/oss-fuzz/libarchive_fuzzer.cc \
-o $OUT/libarchive_fuzzer $LIB_FUZZING_ENGINE \
.libs/libarchive.a -Wl,-Bstatic -lbz2 -llzo2 \
-lxml2 -llzma -lz -lcrypto -llz4 -licuuc \
-licudata -Wl,-Bdynamic

View File

@ -13,8 +13,8 @@ IF(ENABLE_CPIO)
cpio.c
cpio.h
cpio_platform.h
../libarchive_fe/lafe_err.c
../libarchive_fe/lafe_err.h
../libarchive_fe/err.c
../libarchive_fe/err.h
../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h

View File

@ -26,7 +26,7 @@
#endif
#include "cpio.h"
#include "lafe_err.h"
#include "err.h"
/*
* Short options for cpio. Please keep this sorted.

View File

@ -60,7 +60,7 @@
#endif
#include "cpio.h"
#include "lafe_err.h"
#include "err.h"
#include "line_reader.h"
#include "passphrase.h"
@ -124,21 +124,13 @@ main(int argc, char *argv[])
cpio->buff_size = sizeof(buff);
#if defined(HAVE_SIGACTION)
{
#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
{ /* Ignore SIGPIPE signals. */
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
#ifdef SIGPIPE
/* Ignore SIGPIPE signals. */
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
#endif
#ifdef SIGCHLD
/* Do not ignore SIGCHLD. */
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
#endif
}
#endif
@ -725,7 +717,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
if (cpio->uid_override >= 0)
archive_entry_set_uid(entry, cpio->uid_override);
if (cpio->uname_override != NULL)
if (cpio->gname_override != NULL)
archive_entry_set_uname(entry, cpio->uname_override);
if (cpio->gid_override >= 0)
archive_entry_set_gid(entry, cpio->gid_override);

View File

@ -24,7 +24,7 @@
#include <sddl.h>
#include "cpio.h"
#include "lafe_err.h"
#include "err.h"
#define EPOC_TIME (116444736000000000ULL)

View File

@ -9,7 +9,7 @@
IF(ENABLE_CPIO AND ENABLE_TEST)
SET(bsdcpio_test_SOURCES
../cmdline.c
../../libarchive_fe/lafe_err.c
../../libarchive_fe/err.c
../../test_utils/test_utils.c
../../test_utils/test_main.c
test.h

View File

@ -7,7 +7,7 @@
#include "test.h"
#include "../cpio.h"
#include "lafe_err.h"
#include "err.h"
#if !defined(_WIN32)
#define ROOT "root"

View File

@ -52,7 +52,6 @@ SET(libarchive_SOURCES
archive_pathmatch.h
archive_platform.h
archive_platform_acl.h
archive_platform_stat.h
archive_platform_xattr.h
archive_ppmd_private.h
archive_ppmd8.c
@ -254,9 +253,6 @@ IF(BUILD_SHARED_LIBS)
SOVERSION ${SOVERSION}
MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
MACHO_CURRENT_VERSION ${MACHO_CURRENT_VERSION})
IF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
SET_PROPERTY(TARGET archive PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
ENDIF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
ENDIF(BUILD_SHARED_LIBS)
# archive_static is a static library
@ -265,14 +261,15 @@ TARGET_INCLUDE_DIRECTORIES(archive_static PUBLIC .)
TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
IF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
SET_PROPERTY(TARGET archive_static PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
ENDIF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
# On Posix systems, libarchive.so and libarchive.a can co-exist.
IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(CMAKE_INSTALL_LIBDIR "lib")
endif()
IF(ENABLE_INSTALL)
# How to install the libraries
IF(BUILD_SHARED_LIBS)

View File

@ -34,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3009000
#define ARCHIVE_VERSION_NUMBER 3008001
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.9.0dev"
#define ARCHIVE_VERSION_ONLY_STRING "3.8.1"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@ -210,9 +210,7 @@ __LA_DECL const char * archive_openssl_version(void);
__LA_DECL const char * archive_libmd_version(void);
__LA_DECL const char * archive_commoncrypto_version(void);
__LA_DECL const char * archive_cng_version(void);
#if ARCHIVE_VERSION_NUMBER < 4000000
__LA_DECL const char * archive_wincrypt_version(void);
#endif
__LA_DECL const char * archive_librichacl_version(void);
__LA_DECL const char * archive_libacl_version(void);
__LA_DECL const char * archive_libattr_version(void);

View File

@ -270,19 +270,6 @@ acl_new_entry(struct archive_acl *acl,
{
struct archive_acl_entry *ap, *aq;
/* Reject an invalid type */
switch (type) {
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
break;
default:
return (NULL);
}
/* Type argument must be a valid NFS4 or POSIX.1e type.
* The type must agree with anything already set and
* the permset must be compatible. */
@ -835,9 +822,6 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
wname = NULL;
id = -1;
break;
default:
**wp = '\0';
break;
}
*wp += wcslen(*wp);
*(*wp)++ = L':';
@ -894,7 +878,6 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
wcscpy(*wp, L"alarm");
break;
default:
*(*wp) = L'\0';
break;
}
*wp += wcslen(*wp);
@ -1074,9 +1057,6 @@ append_entry(char **p, const char *prefix, int type,
name = NULL;
id = -1;
break;
default:
**p = '\0';
break;
}
*p += strlen(*p);
*(*p)++ = ':';
@ -1132,9 +1112,6 @@ append_entry(char **p, const char *prefix, int type,
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
strcpy(*p, "alarm");
break;
default:
*(*p) = '\0';
break;
}
*p += strlen(*p);
}

View File

@ -30,7 +30,6 @@
#endif
#include <stdio.h>
#include <errno.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@ -55,14 +54,8 @@ errmsg(const char *m)
while (s > 0) {
written = write(2, m, s);
if (written == 0)
if (written <= 0)
return;
if (written < 0)
{
if (errno == EINTR)
continue;
return;
}
m += written;
s -= written;
}

View File

@ -57,7 +57,7 @@ pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
return 0;
}
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
#ifdef _MSC_VER
#pragma comment(lib, "Bcrypt.lib")
#endif
@ -151,7 +151,7 @@ pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
(void)rounds; /* UNUSED */
(void)derived_key; /* UNUSED */
(void)derived_key_len; /* UNUSED */
return CRYPTOR_STUB_FUNCTION; /* UNSUPPORTED */
return -1; /* UNSUPPORTED */
}
#endif
@ -197,7 +197,7 @@ aes_ctr_release(archive_crypto_ctx *ctx)
return 0;
}
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
static int
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
@ -439,14 +439,14 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
(void)ctx; /* UNUSED */
(void)key; /* UNUSED */
(void)key_len; /* UNUSED */
return CRYPTOR_STUB_FUNCTION;
return -1;
}
static int
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
{
(void)ctx; /* UNUSED */
return CRYPTOR_STUB_FUNCTION;
return -1;
}
static int
@ -469,7 +469,7 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
(void)out; /* UNUSED */
(void)out_len; /* UNUSED */
aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
return CRYPTOR_STUB_FUNCTION;
return -1;
}
#else
@ -490,9 +490,9 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
size_t in_len, uint8_t * const out, size_t *out_len)
{
uint8_t *const ebuf = ctx->encr_buf;
size_t pos = ctx->encr_pos;
size_t max = (in_len < *out_len)? in_len: *out_len;
size_t i;
unsigned pos = ctx->encr_pos;
unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
unsigned i;
for (i = 0; i < max; ) {
if (pos == AES_BLOCK_SIZE) {

View File

@ -43,7 +43,7 @@ int __libarchive_cryptor_build_hack(void);
#ifdef __APPLE__
# include <AvailabilityMacros.h>
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 1
# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
# endif
#endif
@ -56,13 +56,13 @@ int __libarchive_cryptor_build_hack(void);
typedef struct {
CCCryptorRef ctx;
uint8_t key[AES_MAX_KEY_SIZE];
size_t key_len;
unsigned key_len;
uint8_t nonce[AES_BLOCK_SIZE];
uint8_t encr_buf[AES_BLOCK_SIZE];
size_t encr_pos;
unsigned encr_pos;
} archive_crypto_ctx;
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
#include <bcrypt.h>
#define ARCHIVE_CRYPTOR_USE_CNG 1
@ -144,6 +144,10 @@ typedef struct {
#else
#if defined(_WIN32) && !defined(__CYGWIN__) && !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
#define ARCHIVE_CRYPTOR_USE_WINCRYPT 1
#endif
#define AES_BLOCK_SIZE 16
#define AES_MAX_KEY_SIZE 32
typedef int archive_crypto_ctx;
@ -168,9 +172,6 @@ typedef int archive_crypto_ctx;
#define archive_encrypto_aes_ctr_release(ctx) \
__archive_cryptor.encrypto_aes_ctr_release(ctx)
/* Stub return value if no encryption support exists. */
#define CRYPTOR_STUB_FUNCTION -2
/* Minimal interface to cryptographic functionality for internal use in
* libarchive */
struct archive_cryptor

View File

@ -44,11 +44,16 @@
/*
* Message digest functions for Windows platform.
*/
#if defined(HAVE_BCRYPT_H)
#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
/*
* Initialize a Message digest.
*/
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
static int
win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
{
@ -67,6 +72,30 @@ win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
ctx->valid = 1;
return (ARCHIVE_OK);
}
#else
static int
win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
{
ctx->valid = 0;
if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
prov, CRYPT_VERIFYCONTEXT)) {
if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
return (ARCHIVE_FAILED);
if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
prov, CRYPT_NEWKEYSET))
return (ARCHIVE_FAILED);
}
if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
CryptReleaseContext(ctx->cryptProv, 0);
return (ARCHIVE_FAILED);
}
ctx->valid = 1;
return (ARCHIVE_OK);
}
#endif
/*
* Update a Message digest.
@ -78,26 +107,42 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
if (!ctx->valid)
return (ARCHIVE_FAILED);
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptHashData(ctx->hHash,
(PUCHAR)(uintptr_t)buf,
(ULONG)len, 0);
#else
CryptHashData(ctx->hash,
(unsigned char *)(uintptr_t)buf,
(DWORD)len, 0);
#endif
return (ARCHIVE_OK);
}
static int
win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
{
#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
DWORD siglen = (DWORD)bufsize;
#endif
if (!ctx->valid)
return (ARCHIVE_FAILED);
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
BCryptDestroyHash(ctx->hHash);
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
#else
CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
CryptDestroyHash(ctx->hash);
CryptReleaseContext(ctx->cryptProv, 0);
#endif
ctx->valid = 0;
return (ARCHIVE_OK);
}
#endif /* defined(HAVE_BCRYPT_H) */
#endif /* defined(ARCHIVE_CRYPTO_*_WIN) */
/* MD5 implementations */
@ -189,7 +234,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
static int
__archive_md5init(archive_md5_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
#endif
}
static int
@ -596,7 +645,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
static int
__archive_sha1init(archive_sha1_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
#endif
}
static int
@ -872,7 +925,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
static int
__archive_sha256init(archive_sha256_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
#endif
}
static int
@ -1120,7 +1177,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
static int
__archive_sha384init(archive_sha384_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
#endif
}
static int
@ -1392,7 +1453,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
static int
__archive_sha512init(archive_sha512_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
#endif
}
static int

View File

@ -165,7 +165,8 @@
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#if defined(HAVE_BCRYPT_H)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
#define ARCHIVE_CRYPTO_CNG 1
typedef struct {
@ -173,6 +174,15 @@ typedef struct {
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
} Digest_CTX;
#else
#include <windows.h>
#include <wincrypt.h>
#define ARCHIVE_CRYPTO_WINCRYPT 1
typedef struct {
int valid;
HCRYPTPROV cryptProv;
HCRYPTHASH hash;
} Digest_CTX;
#endif
#endif

View File

@ -124,6 +124,7 @@ static void
add_trivial_nfs4_acl(struct archive_entry *entry)
{
mode_t mode;
int i;
const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA;
@ -194,7 +195,7 @@ add_trivial_nfs4_acl(struct archive_entry *entry)
} else if ((mode & 0010) || (mode & 0001))
tacl_entry[1].permset |= eperm;
for (size_t i = 0; i < sizeof(tacl_entry) / sizeof(tacl_entry[0]); i++) {
for (i = 0; i < sizeof(tacl_entry) / sizeof(tacl_entry[0]); i++) {
if (tacl_entry[i].permset != 0) {
archive_entry_acl_add_entry(entry,
tacl_entry[i].type, tacl_entry[i].permset,

View File

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

View File

@ -64,7 +64,7 @@ Streaming Archive Library (libarchive, -larchive)
.Ft void
.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_hardlink_w "struct archive_entry *a" "const wchar_t *path"
.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
.Ft int
.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
.Ft void

View File

@ -207,7 +207,7 @@ for setting is recommended.
The function
.Fn archive_entry_size
returns the file size, if it has been set, and 0 otherwise.
.Fn archive_entry_size_is_set
.Fn archive_entry_size
can be used to query that status.
.Fn archive_entry_set_size
and

View File

@ -38,7 +38,6 @@
const struct stat *
archive_entry_stat(struct archive_entry *entry)
{
int64_t size;
struct stat *st;
if (entry->stat == NULL) {
entry->stat = calloc(1, sizeof(*st));
@ -75,10 +74,7 @@ archive_entry_stat(struct archive_entry *entry)
st->st_ino = (ino_t)archive_entry_ino64(entry);
st->st_nlink = archive_entry_nlink(entry);
st->st_rdev = archive_entry_rdev(entry);
size = archive_entry_size(entry);
st->st_size = (off_t)size;
if (st->st_size < 0 || (int64_t)st->st_size != size)
st->st_size = 0;
st->st_size = (off_t)archive_entry_size(entry);
st->st_mode = archive_entry_mode(entry);
/*

View File

@ -74,7 +74,7 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
memset(ctx, 0, sizeof(*ctx));
}
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
#ifndef BCRYPT_HASH_REUSABLE_FLAG
# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020

View File

@ -52,7 +52,7 @@ int __libarchive_hmac_build_hack(void);
typedef CCHmacContext archive_hmac_sha1_ctx;
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
#include <bcrypt.h>
typedef struct {

View File

@ -703,7 +703,9 @@ Convert(time_t Month, time_t Day, time_t Year,
Year += 1900;
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
? 29 : 28;
if (Year < EPOCH || (sizeof(time_t) <= 4 && Year >= 2038)
/* Checking for 2038 bogusly assumes that time_t is 32 bits. But
I'm too lazy to try to check for time_t overflow in another way. */
if (Year < EPOCH || Year >= 2038
|| Month < 1 || Month > 12
/* Lint fluff: "conversion from long may lose accuracy" */
|| Day < 1 || Day > DaysInMonth[(int)--Month]

View File

@ -183,6 +183,16 @@
#define CAN_RESTORE_METADATA_FD
#endif
/*
* glibc 2.24 deprecates readdir_r
* bionic c deprecates readdir_r too
*/
#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__))
#define USE_READDIR_R 1
#else
#undef USE_READDIR_R
#endif
/* Set up defaults for internal error codes. */
#ifndef ARCHIVE_ERRNO_FILE_FORMAT
#if HAVE_EFTYPE

View File

@ -1,45 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 Tobias Stoeckmann
* All rights reserved.
*/
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
#ifndef ARCHIVE_PLATFORM_STAT_H_INCLUDED
#define ARCHIVE_PLATFORM_STAT_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
/* We use _lseeki64() on Windows. */
typedef int64_t la_seek_t;
struct la_seek_stat {
int64_t st_mtime;
ino_t st_ino;
unsigned short st_mode;
uint32_t st_nlink;
gid_t st_gid;
la_seek_t st_size;
uid_t st_uid;
dev_t st_dev;
dev_t st_rdev;
};
typedef struct la_seek_stat la_seek_stat_t;
#define la_seek_fstat(fd, st) __la_seek_fstat((fd), (st))
#define la_seek_stat(fd, st) __la_seek_stat((fd), (st))
#else
typedef off_t la_seek_t;
typedef struct stat la_seek_stat_t;
#define la_seek_fstat(fd, st) fstat((fd), (st))
#define la_seek_stat(fd, st) stat((fd), (st))
#endif
#endif /* !ARCHIVE_PLATFORM_STAT_H_INCLUDED */

View File

@ -158,7 +158,6 @@ int __archive_check_magic(struct archive *, unsigned int magic,
__LA_NORETURN void __archive_errx(int retvalue, const char *msg);
void __archive_ensure_cloexec_flag(int fd);
int __archive_get_tempdir(struct archive_string *);
int __archive_mktemp(const char *tmpdir);
#if defined(_WIN32) && !defined(__CYGWIN__)
int __archive_mkstemp(wchar_t *templates);

View File

@ -57,13 +57,19 @@ static void la_arc4random_buf(void *, size_t);
#include "archive.h"
#include "archive_random_private.h"
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
#elif defined(HAVE_WINCRYPT_H)
#include <wincrypt.h>
#endif
#endif
#ifndef O_CLOEXEC
@ -79,6 +85,7 @@ int
archive_random(void *buf, size_t nbytes)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlg;
@ -91,6 +98,25 @@ archive_random(void *buf, size_t nbytes)
return ARCHIVE_FAILED;
return ARCHIVE_OK;
# else
HCRYPTPROV hProv;
BOOL success;
success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT);
if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) {
success = CryptAcquireContext(&hProv, NULL, NULL,
PROV_RSA_FULL, CRYPT_NEWKEYSET);
}
if (success) {
success = CryptGenRandom(hProv, (DWORD)nbytes, (BYTE*)buf);
CryptReleaseContext(hProv, 0);
if (success)
return ARCHIVE_OK;
}
/* TODO: Does this case really happen? */
return ARCHIVE_FAILED;
# endif
#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
la_arc4random_buf(buf, nbytes);
return ARCHIVE_OK;

View File

@ -575,7 +575,8 @@ choose_filters(struct archive_read *a)
return (ARCHIVE_OK);
}
filter = calloc(1, sizeof(*filter));
filter
= calloc(1, sizeof(*filter));
if (filter == NULL)
return (ARCHIVE_FATAL);
filter->bidder = best_bidder;
@ -833,9 +834,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
r = archive_read_data_block(a, &read_buf,
&a->read_data_remaining, &a->read_data_offset);
a->read_data_block = read_buf;
if (r == ARCHIVE_EOF &&
a->read_data_offset == a->read_data_output_offset &&
a->read_data_remaining == 0)
if (r == ARCHIVE_EOF)
return (bytes_read);
/*
* Error codes are all negative, so the status

Some files were not shown because too many files have changed in this diff Show More