mirror of
https://github.com/libarchive/libarchive.git
synced 2026-01-27 09:54:38 +00:00
Compare commits
304 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d1c9b95f1 | ||
|
|
dea03d6e00 | ||
|
|
3cd503b75a | ||
|
|
86851e3092 | ||
|
|
02eba33825 | ||
|
|
0bb2058bd5 | ||
|
|
e663efb430 | ||
|
|
3ff73fdfce | ||
|
|
e91171c9a0 | ||
|
|
7f27446a51 | ||
|
|
090fbc3655 | ||
|
|
8c2241a7e4 | ||
|
|
d54b2241b9 | ||
|
|
782cdd88b6 | ||
|
|
d1b87af584 | ||
|
|
9a089dc44a | ||
|
|
a55b8e8aec | ||
|
|
76558692a4 | ||
|
|
4a32d9ff7f | ||
|
|
998c0b4080 | ||
|
|
030a93817c | ||
|
|
9298dc503a | ||
|
|
e54c735586 | ||
|
|
b2d68e2f1a | ||
|
|
1cd0b9179c | ||
|
|
095609e89b | ||
|
|
5c84afd664 | ||
|
|
f366e98107 | ||
|
|
c4597a73f3 | ||
|
|
79fac84eb2 | ||
|
|
8042630d4f | ||
|
|
214ee3edc7 | ||
|
|
eb6f992ba1 | ||
|
|
544b07541b | ||
|
|
5e88593708 | ||
|
|
8f3fcf9ecd | ||
|
|
6e77f521fa | ||
|
|
50a67c9223 | ||
|
|
b39f91e5da | ||
|
|
55fbf225c8 | ||
|
|
e75e5892fd | ||
|
|
784b778f3b | ||
|
|
b51e59bcfb | ||
|
|
a7f3b56af6 | ||
|
|
cfb02de558 | ||
|
|
8295366f94 | ||
|
|
8c86c46d1b | ||
|
|
752df6abb7 | ||
|
|
728b43c0c1 | ||
|
|
0a594ab77d | ||
|
|
a819cc2829 | ||
|
|
1b9b42720f | ||
|
|
827905c93f | ||
|
|
aac59c1bd5 | ||
|
|
f49372e945 | ||
|
|
8ef2084104 | ||
|
|
e17f169356 | ||
|
|
47809f10bf | ||
|
|
81bc00a549 | ||
|
|
3150539edb | ||
|
|
8f7d334646 | ||
|
|
12522911fa | ||
|
|
1890755ab2 | ||
|
|
35aac8a925 | ||
|
|
fdec8c2f24 | ||
|
|
2df76f52c2 | ||
|
|
ce7b3f1c15 | ||
|
|
dbacda991c | ||
|
|
2caee6a37e | ||
|
|
d5bd2dfafe | ||
|
|
e1c3061b12 | ||
|
|
c2333a511d | ||
|
|
d8fba4df3a | ||
|
|
f75b5ddab0 | ||
|
|
02a76f2dc9 | ||
|
|
c5cc510145 | ||
|
|
ab09af7304 | ||
|
|
e929454ec8 | ||
|
|
3aa9c22ddf | ||
|
|
daf5abf802 | ||
|
|
f18a754d02 | ||
|
|
3396ba84d7 | ||
|
|
26c769ecdc | ||
|
|
45a873e998 | ||
|
|
fa5f70627c | ||
|
|
c45a07854d | ||
|
|
f80b1ae294 | ||
|
|
1435c4b20c | ||
|
|
989a303793 | ||
|
|
f02961f402 | ||
|
|
dc6c0c5f35 | ||
|
|
ce614c6524 | ||
|
|
8855146220 | ||
|
|
edbada88c0 | ||
|
|
212426e751 | ||
|
|
83c30ee813 | ||
|
|
d2e861769c | ||
|
|
89cbfe1028 | ||
|
|
1c08abc60d | ||
|
|
8fff509f1a | ||
|
|
d0f69b355d | ||
|
|
7976476c9f | ||
|
|
51b3e14257 | ||
|
|
33ac104169 | ||
|
|
de73860cda | ||
|
|
d207d816d0 | ||
|
|
12cdd35f31 | ||
|
|
e12c955dca | ||
|
|
46fe318edd | ||
|
|
582799ee57 | ||
|
|
b12d1c14d1 | ||
|
|
6d8e1a883c | ||
|
|
eb54a4d869 | ||
|
|
fda50c79ba | ||
|
|
372e709c1a | ||
|
|
4ecf62fbd7 | ||
|
|
c34ff01c02 | ||
|
|
2d987e725f | ||
|
|
7fdf32b6b2 | ||
|
|
98731ad500 | ||
|
|
be31ad37f3 | ||
|
|
619e22cae7 | ||
|
|
52bf0d7de0 | ||
|
|
36a530973a | ||
|
|
39dc43b3e0 | ||
|
|
638464b477 | ||
|
|
ab5cb61f49 | ||
|
|
38debf6be1 | ||
|
|
e1dea559c7 | ||
|
|
96f76577d3 | ||
|
|
e5c2eb783b | ||
|
|
a3787a34a8 | ||
|
|
a2933fbefd | ||
|
|
123d92bc3a | ||
|
|
ff3a0c37aa | ||
|
|
589659ed7f | ||
|
|
52db141ece | ||
|
|
3b1100f9a9 | ||
|
|
6bd863f612 | ||
|
|
4768f38535 | ||
|
|
3a072e0bb0 | ||
|
|
06191cd287 | ||
|
|
53135ca48e | ||
|
|
37ab51c2d3 | ||
|
|
ab4d21e4cb | ||
|
|
f12d80442c | ||
|
|
892f331450 | ||
|
|
bf50fe0538 | ||
|
|
2db13f7422 | ||
|
|
93f9e93d73 | ||
|
|
12ffcef28c | ||
|
|
02ebfb5a48 | ||
|
|
e099b418e3 | ||
|
|
6a008e524e | ||
|
|
835fe1133f | ||
|
|
466a2b5c7b | ||
|
|
640c9feced | ||
|
|
9e7af6f21c | ||
|
|
652a0c107b | ||
|
|
980b541632 | ||
|
|
8b3d3ee99b | ||
|
|
fb859e6d3f | ||
|
|
da65b39c06 | ||
|
|
e47c315f51 | ||
|
|
cb403667d7 | ||
|
|
0ff100c8d3 | ||
|
|
3bf1035e67 | ||
|
|
a335429c5e | ||
|
|
23ee781520 | ||
|
|
64bcf69ef8 | ||
|
|
ecce46744f | ||
|
|
6062470cbc | ||
|
|
aa1fc90ae5 | ||
|
|
d1418af239 | ||
|
|
cc97338239 | ||
|
|
ed2ada78a6 | ||
|
|
4dfaf2d359 | ||
|
|
cb6b9e9a28 | ||
|
|
d2d72ac78a | ||
|
|
b57d14f9c9 | ||
|
|
267042ebc7 | ||
|
|
a3d261a29a | ||
|
|
3c646995db | ||
|
|
7b59a6b693 | ||
|
|
e559754d6d | ||
|
|
82e247fe7c | ||
|
|
eff524fa4e | ||
|
|
84e8f3c98e | ||
|
|
4035fca93a | ||
|
|
3997a5f28a | ||
|
|
d01dc496d3 | ||
|
|
d06700a098 | ||
|
|
2db02ae6ae | ||
|
|
595fb29e4c | ||
|
|
609d8122f1 | ||
|
|
31cff981e4 | ||
|
|
d8aaf88c9f | ||
|
|
ee49ac8106 | ||
|
|
9fe18ba0a6 | ||
|
|
cd020d1ccb | ||
|
|
a474bab7e3 | ||
|
|
489d0b8e2f | ||
|
|
1e4b84ed30 | ||
|
|
50d44b4202 | ||
|
|
b1b3709cae | ||
|
|
ffde04f272 | ||
|
|
fd4ecc0146 | ||
|
|
a218a52dbb | ||
|
|
0de62cbda8 | ||
|
|
e4978e2edd | ||
|
|
40a89c7379 | ||
|
|
6a252c84a2 | ||
|
|
4984c652db | ||
|
|
664a20b6c7 | ||
|
|
b7066d4a6b | ||
|
|
6effe2ec6b | ||
|
|
251f7e839c | ||
|
|
47bdf82489 | ||
|
|
c3be70e071 | ||
|
|
9bdc5b82f7 | ||
|
|
475423a154 | ||
|
|
864c904442 | ||
|
|
dcf5475661 | ||
|
|
90c1e32a0d | ||
|
|
c0691458a0 | ||
|
|
75ef803092 | ||
|
|
0931c12b7e | ||
|
|
b1839a20e5 | ||
|
|
f3949062ed | ||
|
|
cdb45d71b2 | ||
|
|
fa85c7eaae | ||
|
|
aa69d34311 | ||
|
|
5a60d8cda4 | ||
|
|
ac66e0bc42 | ||
|
|
f2c3c790ff | ||
|
|
b7e1c617cb | ||
|
|
c40a3887ab | ||
|
|
9836e7e2fe | ||
|
|
a8f93f2480 | ||
|
|
b76c4042ae | ||
|
|
36bac92cd2 | ||
|
|
2764062e65 | ||
|
|
13700e1fb8 | ||
|
|
d7d1d19bb6 | ||
|
|
0f9a06d6ab | ||
|
|
1311a438a3 | ||
|
|
70978468e9 | ||
|
|
c7b7bd7c0e | ||
|
|
8d074302ac | ||
|
|
e1ca935c00 | ||
|
|
e1c0f9a660 | ||
|
|
20b4a4cb7c | ||
|
|
101230094c | ||
|
|
8540cb7cfb | ||
|
|
e2eda9e68b | ||
|
|
9ac39a0168 | ||
|
|
0a320b6a37 | ||
|
|
f90d036057 | ||
|
|
65d0393f24 | ||
|
|
e70e24a738 | ||
|
|
9b07a143ee | ||
|
|
cd5c44c5d0 | ||
|
|
2ed2db55e8 | ||
|
|
59b09796c3 | ||
|
|
d261f46ae5 | ||
|
|
dcdd7338d6 | ||
|
|
702f31a01c | ||
|
|
ebca997192 | ||
|
|
9d07162b08 | ||
|
|
33d3528723 | ||
|
|
715f7eac02 | ||
|
|
51b4c35bb3 | ||
|
|
6389d172ed | ||
|
|
ac96967e36 | ||
|
|
341dd5d1d4 | ||
|
|
18d456377e | ||
|
|
bc5f0884e3 | ||
|
|
101646e34e | ||
|
|
b6e1f06457 | ||
|
|
0685c77e83 | ||
|
|
5bb36db5e1 | ||
|
|
42c2f84649 | ||
|
|
6dbea2df3b | ||
|
|
a5d9c9a7cd | ||
|
|
cdc185e917 | ||
|
|
8b978a0368 | ||
|
|
bef52da622 | ||
|
|
8b763d872c | ||
|
|
51e66d32c6 | ||
|
|
4223b4c548 | ||
|
|
612223356e | ||
|
|
0ed4435209 | ||
|
|
992734d6cc | ||
|
|
627ba5bbbf | ||
|
|
2cdf47f332 | ||
|
|
d8ff8dd62c | ||
|
|
d6f6fdf979 | ||
|
|
38ac49553d | ||
|
|
9eacf09a86 | ||
|
|
0ddaa5f71c | ||
|
|
2961b132d0 | ||
|
|
182726d16a | ||
|
|
447201758e | ||
|
|
27588eba50 |
28
.cirrus.yml
28
.cirrus.yml
@ -1,3 +1,4 @@
|
||||
---
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 1
|
||||
ARCH: amd64
|
||||
@ -9,22 +10,33 @@ FreeBSD_task:
|
||||
env:
|
||||
BS: cmake
|
||||
matrix:
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-5
|
||||
- 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
|
||||
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 CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a configure
|
||||
- env MAKE=gmake CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./build/ci/build.sh -a configure
|
||||
build_script:
|
||||
- env MAKE_ARGS="-j 2" ./build/ci/build.sh -a build
|
||||
- env MAKE=gmake MAKE_ARGS="-j 2" ./build/ci/build.sh -a build
|
||||
test_script:
|
||||
- env SKIP_TEST_RESTORE_ATIME=1 MAKE_ARGS="-j 2" ./build/ci/build.sh -a test
|
||||
- env MAKE=gmake 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_ARGS="-j 2" ./build/ci/build.sh -a install
|
||||
- env MAKE=gmake MAKE_ARGS="-j 2" ./build/ci/build.sh -a install
|
||||
|
||||
Windows_Cygwin_task:
|
||||
windows_container:
|
||||
|
||||
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
matrix:
|
||||
bs: [autotools, cmake]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: libarchive-${{ github.sha }}
|
||||
path: libarchive-dist.tar
|
||||
@ -127,7 +127,7 @@ jobs:
|
||||
matrix:
|
||||
be: [mingw-gcc, msvc]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: libarchive-windows-${{ matrix.be }}-${{ github.sha }}
|
||||
path: libarchive.zip
|
||||
|
||||
2
.github/workflows/cifuzz.yml
vendored
2
.github/workflows/cifuzz.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
|
||||
8
.github/workflows/codeql.yml
vendored
8
.github/workflows/codeql.yml
vendored
@ -26,18 +26,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
||||
8
.github/workflows/scorecard.yml
vendored
8
.github/workflows/scorecard.yml
vendored
@ -29,12 +29,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
|
||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
||||
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
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@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
||||
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
135
CMakeLists.txt
135
CMakeLists.txt
@ -3,6 +3,9 @@ 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)
|
||||
@ -136,7 +139,12 @@ 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(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
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()
|
||||
# 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")
|
||||
@ -145,10 +153,7 @@ 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")
|
||||
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()
|
||||
ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
|
||||
CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
|
||||
IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
|
||||
@ -255,6 +260,10 @@ 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)")
|
||||
@ -771,12 +780,22 @@ 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)
|
||||
|
||||
#
|
||||
@ -985,85 +1004,6 @@ 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 **
|
||||
@ -1078,8 +1018,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 success is a miss
|
||||
# detection. So this needs for all build mode(even it's a release mode).
|
||||
# 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.
|
||||
#
|
||||
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
|
||||
ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
|
||||
@ -1257,7 +1197,7 @@ ELSE(LIBXML2_FOUND)
|
||||
# Check linkage as well; versions of mingw-w64 before v11.0.0
|
||||
# do not contain an import library for xmllite.
|
||||
cmake_push_check_state()
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "xmllite")
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "xmllite" "uuid")
|
||||
check_c_source_compiles("
|
||||
#include <initguid.h>
|
||||
#include <xmllite.h>
|
||||
@ -1268,7 +1208,7 @@ ELSE(LIBXML2_FOUND)
|
||||
cmake_pop_check_state()
|
||||
IF(HAVE_XMLLITE_H)
|
||||
SET(XMLLITE_FOUND TRUE)
|
||||
LIST(APPEND ADDITIONAL_LIBS "xmllite")
|
||||
LIST(APPEND ADDITIONAL_LIBS "xmllite" "uuid")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF(EXPAT_FOUND)
|
||||
@ -1472,6 +1412,8 @@ 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)
|
||||
@ -1489,15 +1431,19 @@ 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(getpid HAVE_GETPID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getresgid HAVE_GETRESGID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getresuid HAVE_GETRESUID)
|
||||
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)
|
||||
@ -1516,6 +1462,7 @@ 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)
|
||||
@ -1579,12 +1526,6 @@ 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);}"
|
||||
@ -2176,8 +2117,6 @@ 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")
|
||||
|
||||
243
Makefile.am
243
Makefile.am
@ -96,60 +96,73 @@ distclean-local:
|
||||
|
||||
include_HEADERS= libarchive/archive.h libarchive/archive_entry.h
|
||||
|
||||
libarchive_la_SOURCES= \
|
||||
libarchive/archive_acl.c \
|
||||
noinst_HEADERS= \
|
||||
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_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_check_magic.c \
|
||||
libarchive/archive_cmdline.c \
|
||||
libarchive/archive_cryptor.c \
|
||||
libarchive/archive_digest.c \
|
||||
libarchive/archive_entry.c \
|
||||
libarchive/archive_entry_copy_stat.c \
|
||||
libarchive/archive_entry_link_resolver.c \
|
||||
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 \
|
||||
@ -157,12 +170,11 @@ 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_bzip2.c \
|
||||
libarchive/archive_read_support_filter_by_code.c \
|
||||
libarchive/archive_read_support_filter_bzip2.c \
|
||||
libarchive/archive_read_support_filter_compress.c \
|
||||
libarchive/archive_read_support_filter_grzip.c \
|
||||
libarchive/archive_read_support_filter_gzip.c \
|
||||
@ -193,23 +205,12 @@ 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 \
|
||||
@ -225,6 +226,12 @@ 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 \
|
||||
@ -234,59 +241,54 @@ 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
|
||||
libarchive_la_SOURCES+= \
|
||||
noinst_HEADERS+= \
|
||||
libarchive/archive_blake2.h \
|
||||
libarchive/archive_blake2_impl.h \
|
||||
libarchive/archive_blake2_impl.h
|
||||
libarchive_la_SOURCES+= \
|
||||
libarchive/archive_blake2s_ref.c \
|
||||
libarchive/archive_blake2sp_ref.c
|
||||
endif
|
||||
|
||||
if INC_LINUX_ACL
|
||||
libarchive_la_SOURCES+= libarchive/archive_disk_acl_linux.c
|
||||
else
|
||||
endif
|
||||
if INC_SUNOS_ACL
|
||||
libarchive_la_SOURCES+= libarchive/archive_disk_acl_sunos.c
|
||||
else
|
||||
endif
|
||||
if INC_DARWIN_ACL
|
||||
libarchive_la_SOURCES+= libarchive/archive_disk_acl_darwin.c
|
||||
else
|
||||
endif
|
||||
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.
|
||||
@ -350,22 +352,24 @@ 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_common.h
|
||||
test_utils/test_utils.c
|
||||
|
||||
#
|
||||
#
|
||||
# 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 \
|
||||
@ -465,6 +469,7 @@ 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 \
|
||||
@ -525,14 +530,17 @@ 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 \
|
||||
libarchive/test/test_read_format_tar_empty_with_gnulabel.c \
|
||||
libarchive/test/test_read_format_tar_filename.c \
|
||||
libarchive/test/test_read_format_tar_invalid_pax_size.c \
|
||||
libarchive/test/test_read_format_tar_mac_metadata.c \
|
||||
libarchive/test/test_read_format_tar_pax_g_large.c \
|
||||
libarchive/test/test_read_format_tar_pax_large_attr.c \
|
||||
libarchive/test/test_read_format_tar_pax_negative_time.c \
|
||||
libarchive/test/test_read_format_tbz.c \
|
||||
libarchive/test/test_read_format_tgz.c \
|
||||
libarchive/test/test_read_format_tlz.c \
|
||||
@ -565,6 +573,7 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_read_format_zip_zip64.c \
|
||||
libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c \
|
||||
libarchive/test/test_read_large.c \
|
||||
libarchive/test/test_read_pax_empty_val_no_nl.c \
|
||||
libarchive/test/test_read_pax_xattr_rht_security_selinux.c \
|
||||
libarchive/test/test_read_pax_xattr_schily.c \
|
||||
libarchive/test/test_read_pax_truncated.c \
|
||||
@ -667,7 +676,6 @@ 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 \
|
||||
@ -680,9 +688,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: Makefile
|
||||
libarchive/test/list.h: $(libarchive_test_SOURCES)
|
||||
$(MKDIR_P) libarchive/test
|
||||
cat $(top_srcdir)/libarchive/test/test_*.c | grep '^DEFINE_TEST' > libarchive/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test LRZIP=NOCONFIG
|
||||
|
||||
@ -702,6 +710,7 @@ 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 \
|
||||
@ -808,6 +817,7 @@ 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 \
|
||||
@ -918,6 +928,9 @@ 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 \
|
||||
@ -949,6 +962,7 @@ 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 \
|
||||
@ -957,6 +971,7 @@ 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 \
|
||||
@ -969,14 +984,17 @@ 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 \
|
||||
libarchive/test/test_read_format_tar_empty_pax.tar.Z.uu \
|
||||
libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \
|
||||
libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu \
|
||||
libarchive/test/test_read_format_tar_mac_metadata_1.tar.uu \
|
||||
libarchive/test/test_read_format_tar_pax_g_large.tar.uu \
|
||||
libarchive/test/test_read_format_tar_pax_large_attr.tar.Z.uu \
|
||||
libarchive/test/test_read_format_tar_pax_negative_time.tar.uu \
|
||||
libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \
|
||||
libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
|
||||
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
|
||||
@ -1041,6 +1059,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_large_splitted_rar_ac.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ad.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ae.uu \
|
||||
libarchive/test/test_read_pax_empty_val_no_nl.tar.uu \
|
||||
libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu \
|
||||
libarchive/test/test_read_pax_xattr_schily.tar.uu \
|
||||
libarchive/test/test_read_splitted_rar_aa.uu \
|
||||
@ -1052,6 +1071,7 @@ 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 \
|
||||
@ -1061,14 +1081,15 @@ libarchive_test_EXTRA_DIST=\
|
||||
#
|
||||
# Common code for libarchive frontends (cpio, tar)
|
||||
#
|
||||
libarchive_fe_la_SOURCES= \
|
||||
libarchive_fe/err.c \
|
||||
libarchive_fe/err.h \
|
||||
noinst_HEADERS+= \
|
||||
libarchive_fe/lafe_err.h \
|
||||
libarchive_fe/lafe_platform.h \
|
||||
libarchive_fe/line_reader.c \
|
||||
libarchive_fe/line_reader.h \
|
||||
libarchive_fe/passphrase.c \
|
||||
libarchive_fe/passphrase.h
|
||||
libarchive_fe_la_SOURCES= \
|
||||
libarchive_fe/lafe_err.c \
|
||||
libarchive_fe/line_reader.c \
|
||||
libarchive_fe/passphrase.c
|
||||
|
||||
libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
|
||||
#
|
||||
@ -1077,21 +1098,23 @@ libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
|
||||
#
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
tar/bsdtar.h \
|
||||
tar/bsdtar_platform.h
|
||||
bsdtar_SOURCES= \
|
||||
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
|
||||
tar/bsdtar.c \
|
||||
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.h \
|
||||
tar/bsdtar_windows.c
|
||||
tar/bsdtar_windows.c
|
||||
endif
|
||||
|
||||
bsdtar_DEPENDENCIES= libarchive.la libarchive_fe.la
|
||||
@ -1128,12 +1151,15 @@ 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 \
|
||||
@ -1210,9 +1236,9 @@ bsdtar_test_CPPFLAGS=\
|
||||
-I$(top_builddir)/tar/test \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
|
||||
tar/test/list.h: Makefile
|
||||
tar/test/list.h: $(bsdtar_test_SOURCES)
|
||||
$(MKDIR_P) tar/test
|
||||
cat $(top_srcdir)/tar/test/test_*.c | grep '^DEFINE_TEST' > tar/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDTAR
|
||||
bsdtar_test_programs= bsdtar_test
|
||||
@ -1253,16 +1279,18 @@ bsdtar_test_EXTRA_DIST= \
|
||||
#
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
cpio/cpio.h \
|
||||
cpio/cpio_platform.h
|
||||
bsdcpio_SOURCES= \
|
||||
cpio/cmdline.c \
|
||||
cpio/cpio.c \
|
||||
cpio/cpio.h \
|
||||
cpio/cpio_platform.h
|
||||
cpio/cmdline.c \
|
||||
cpio/cpio.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+= \
|
||||
cpio/cpio_windows.h
|
||||
bsdcpio_SOURCES+= \
|
||||
cpio/cpio_windows.h \
|
||||
cpio/cpio_windows.c
|
||||
cpio/cpio_windows.c
|
||||
endif
|
||||
|
||||
bsdcpio_DEPENDENCIES = libarchive.la libarchive_fe.la
|
||||
@ -1301,10 +1329,11 @@ 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 \
|
||||
@ -1363,9 +1392,9 @@ bsdcpio_test_CPPFLAGS= \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
bsdcpio_test_LDADD=libarchive_fe.la
|
||||
|
||||
cpio/test/list.h: Makefile
|
||||
cpio/test/list.h: $(bsdcpio_test_SOURCES)
|
||||
$(MKDIR_P) cpio/test
|
||||
cat $(top_srcdir)/cpio/test/test_*.c | grep '^DEFINE_TEST' > cpio/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDCPIO
|
||||
bsdcpio_test_programs= bsdcpio_test
|
||||
@ -1410,13 +1439,15 @@ bsdcpio_test_EXTRA_DIST= \
|
||||
#
|
||||
#
|
||||
|
||||
noinst_HEADERS+= \
|
||||
cat/bsdcat.h \
|
||||
cat/bsdcat_platform.h
|
||||
bsdcat_SOURCES= \
|
||||
cat/bsdcat.c \
|
||||
cat/bsdcat.h \
|
||||
cat/bsdcat_platform.h \
|
||||
cat/cmdline.c
|
||||
cat/bsdcat.c \
|
||||
cat/cmdline.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+=
|
||||
bsdcat_SOURCES+=
|
||||
endif
|
||||
|
||||
@ -1453,9 +1484,10 @@ 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 \
|
||||
@ -1483,9 +1515,9 @@ bsdcat_test_CPPFLAGS= \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
bsdcat_test_LDADD=libarchive_fe.la
|
||||
|
||||
cat/test/list.h: Makefile
|
||||
cat/test/list.h: $(bsdcat_test_SOURCES)
|
||||
$(MKDIR_P) cat/test
|
||||
cat $(top_srcdir)/cat/test/test_*.c | grep '^DEFINE_TEST' > cat/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDCAT
|
||||
bsdcat_test_programs= bsdcat_test
|
||||
@ -1516,16 +1548,18 @@ 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/bsdunzip.h \
|
||||
unzip/bsdunzip_platform.h \
|
||||
unzip/cmdline.c \
|
||||
unzip/la_getline.c \
|
||||
unzip/la_getline.h \
|
||||
unzip/la_queue.h
|
||||
unzip/bsdunzip.c \
|
||||
unzip/cmdline.c \
|
||||
unzip/la_getline.c
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
noinst_HEADERS+=
|
||||
bsdunzip_SOURCES+=
|
||||
endif
|
||||
|
||||
@ -1562,9 +1596,10 @@ 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 \
|
||||
@ -1595,9 +1630,9 @@ bsdunzip_test_CPPFLAGS= \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
bsdunzip_test_LDADD=libarchive_fe.la
|
||||
|
||||
unzip/test/list.h: Makefile
|
||||
unzip/test/list.h: $(bsdunzip_test_SOURCES)
|
||||
$(MKDIR_P) unzip/test
|
||||
cat $(top_srcdir)/unzip/test/test_*.c | grep '^DEFINE_TEST' > unzip/test/list.h
|
||||
grep -h '^DEFINE_TEST(' $^ | LC_COLLATE=C sort > $@
|
||||
|
||||
if BUILD_BSDUNZIP
|
||||
bsdunzip_test_programs= bsdunzip_test
|
||||
|
||||
10
NEWS
10
NEWS
@ -1,3 +1,13 @@
|
||||
May 20, 2025: libarchive 3.8.0 released
|
||||
|
||||
Mar 30, 2025: libarchive 3.7.9 released
|
||||
|
||||
Mar 20, 2025: libarchive 3.7.8 released
|
||||
|
||||
Oct 13, 2024: libarchive 3.7.7 released
|
||||
|
||||
Sep 23, 2024: libarchive 3.7.6 released
|
||||
|
||||
Sep 13, 2024: libarchive 3.7.5 released
|
||||
|
||||
Apr 26, 2024: libarchive 3.7.4 released
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 me 90 days to work on a fix before public exposure.
|
||||
that you give us 90 days to work on a fix before public exposure.
|
||||
|
||||
@ -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
|
||||
pkg install -y autoconf automake cmake libiconv libtool pkgconf expat libxml2 liblz4 zstd gmake
|
||||
elif [ "${UNAME}" = "Darwin" ]
|
||||
then
|
||||
set -x -e
|
||||
|
||||
@ -5,6 +5,9 @@ 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 \
|
||||
|
||||
@ -29,5 +29,5 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in
|
||||
# And install it, of course ;).
|
||||
IF(ENABLE_INSTALL)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc
|
||||
DESTINATION "lib/pkgconfig")
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
ENDIF()
|
||||
|
||||
@ -405,6 +405,12 @@ 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
|
||||
|
||||
@ -970,9 +976,6 @@ 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
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
3008000
|
||||
3009000
|
||||
|
||||
@ -13,8 +13,8 @@ IF(ENABLE_CAT)
|
||||
bsdcat.h
|
||||
bsdcat_platform.h
|
||||
cmdline.c
|
||||
../libarchive_fe/err.c
|
||||
../libarchive_fe/err.h
|
||||
../libarchive_fe/lafe_err.c
|
||||
../libarchive_fe/lafe_err.h
|
||||
../libarchive_fe/lafe_platform.h
|
||||
)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
|
||||
|
||||
15
cat/bsdcat.c
15
cat/bsdcat.c
@ -7,6 +7,9 @@
|
||||
|
||||
#include "bsdcat_platform.h"
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
@ -22,7 +25,7 @@
|
||||
#include <archive_entry.h>
|
||||
|
||||
#include "bsdcat.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
#define BYTES_PER_BLOCK (20*512)
|
||||
|
||||
@ -105,6 +108,16 @@ 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;
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include "bsdcat.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
/*
|
||||
* Short options for bsdcat. Please keep this sorted.
|
||||
|
||||
42
configure.ac
42
configure.ac
@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
|
||||
dnl In particular, this allows the version macro to be used in AC_INIT
|
||||
|
||||
dnl These first two version numbers are updated automatically on each release.
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.8.0dev])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3008000])
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.9.0dev])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3009000])
|
||||
|
||||
dnl bsdtar and bsdcpio versioning tracks libarchive
|
||||
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
|
||||
@ -258,7 +258,8 @@ AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ])
|
||||
case $host in
|
||||
*mingw* | *cygwin* | *msys* )
|
||||
AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#ifdef _WIN32_WINNT
|
||||
[[#include <windows.h>
|
||||
#ifdef _WIN32_WINNT
|
||||
# error _WIN32_WINNT already defined
|
||||
#endif
|
||||
]],[[;]])
|
||||
@ -267,7 +268,8 @@ case $host in
|
||||
AC_DEFINE([NTDDI_VERSION], 0x05020000, [Define to '0x05020000' for Windows Server 2003 APIs.])
|
||||
])
|
||||
AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#ifdef WINVER
|
||||
[[#include <windows.h>
|
||||
#ifdef WINVER
|
||||
# error WINVER already defined
|
||||
#endif
|
||||
]],[[;]])
|
||||
@ -375,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([wincrypt.h winioctl.h],[],[],
|
||||
AC_CHECK_HEADERS([winioctl.h],[],[],
|
||||
[[#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
@ -436,13 +438,15 @@ if test "x$with_bz2lib" != "xno"; then
|
||||
esac
|
||||
fi
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_ARG_WITH([libb2],
|
||||
AS_HELP_STRING([--without-libb2], [Don't build support for BLAKE2 through libb2]))
|
||||
|
||||
if test "x$with_libb2" != "xno"; then
|
||||
AC_CHECK_HEADERS([blake2.h])
|
||||
AC_CHECK_LIB(b2,blake2sp_init)
|
||||
BLAKE2_PC_VER=`pkg-config --modversion libb2`
|
||||
BLAKE2_PC_VER=`$PKG_CONFIG --modversion libb2`
|
||||
if test "x$BLAKE2_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBB2_PKGCONFIG_VERSION], ["$BLAKE2_PC_VER"], [Libb2 version coming from pkg-config.])
|
||||
fi
|
||||
@ -817,16 +821,20 @@ 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 ctime_r])
|
||||
AC_CHECK_FUNCS([arc4random_buf chflags chown chroot])
|
||||
AC_CHECK_FUNCS([closefrom close_range 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([geteuid getline getpid getgrgid_r getgrnam_r])
|
||||
AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
|
||||
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([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_spawnp readlink readlinkat])
|
||||
AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawn posix_spawnp])
|
||||
AC_CHECK_FUNCS([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])
|
||||
@ -877,14 +885,6 @@ 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>
|
||||
@ -925,7 +925,7 @@ if test "x$enable_xattr" != "xno"; then
|
||||
])
|
||||
AC_CHECK_DECLS([XATTR_NOFOLLOW], [], [], [#include <sys/xattr.h>
|
||||
])
|
||||
ATTR_PC_VER=`pkg-config --modversion libattr`
|
||||
ATTR_PC_VER=`$PKG_CONFIG --modversion libattr`
|
||||
if test "x$ATTR_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBATTR_PKGCONFIG_VERSION], ["$ATTR_PC_VER"], [Libattr version coming from pkg-config.])
|
||||
fi
|
||||
@ -1024,7 +1024,7 @@ AC_ARG_ENABLE([acl],
|
||||
if test "x$enable_acl" != "xno"; then
|
||||
# Libacl
|
||||
AC_CHECK_LIB([acl], [acl_get_file])
|
||||
ACL_PC_VER=`pkg-config --modversion libacl`
|
||||
ACL_PC_VER=`$PKG_CONFIG --modversion libacl`
|
||||
if test "x$ACL_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBACL_PKGCONFIG_VERSION], ["$ACL_PC_VER"], [Libacl version coming from pkg-config.])
|
||||
fi
|
||||
@ -1038,7 +1038,7 @@ if test "x$enable_acl" != "xno"; then
|
||||
])
|
||||
|
||||
AC_CHECK_LIB([richacl], [richacl_get_file])
|
||||
RICHACL_PC_VER=`pkg-config --modversion librichacl`
|
||||
RICHACL_PC_VER=`$PKG_CONFIG --modversion librichacl`
|
||||
if test "x$RICHACL_PC_VER" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([LIBRICHACL_PKGCONFIG_VERSION], ["$RICHACL_PC_VER"], [Librichacl version coming from pkg-config.])
|
||||
fi
|
||||
|
||||
@ -26,6 +26,8 @@ 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 \
|
||||
@ -44,6 +46,7 @@ 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 \
|
||||
@ -86,6 +89,7 @@ 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 \
|
||||
@ -93,6 +97,7 @@ 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 \
|
||||
@ -123,7 +128,9 @@ 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 \
|
||||
@ -151,7 +158,7 @@ else
|
||||
libarchive_host_src_files :=
|
||||
endif
|
||||
|
||||
libarchive_fe_src_files := libarchive_fe/err.c \
|
||||
libarchive_fe_src_files := libarchive_fe/lafe_err.c \
|
||||
libarchive_fe/line_reader.c \
|
||||
libarchive_fe/passphrase.c
|
||||
|
||||
@ -305,4 +312,17 @@ 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
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
#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
|
||||
@ -40,6 +42,8 @@
|
||||
|
||||
#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
|
||||
@ -53,6 +57,8 @@
|
||||
#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
|
||||
@ -135,7 +141,7 @@
|
||||
#define HAVE_STRING_H 1
|
||||
#define HAVE_STRRCHR 1
|
||||
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
|
||||
#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
|
||||
#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 0
|
||||
#define HAVE_STRUCT_TM_TM_GMTOFF 1
|
||||
#define HAVE_SYMLINK 1
|
||||
#define HAVE_SYS_CDEFS_H 1
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
#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
|
||||
@ -180,7 +182,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
|
||||
|
||||
@ -175,6 +175,12 @@
|
||||
/* 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 */
|
||||
|
||||
@ -620,9 +626,6 @@
|
||||
/* 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 */
|
||||
|
||||
@ -896,9 +899,6 @@
|
||||
/* 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
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Macros for file64 functions
|
||||
*
|
||||
* Android does not support the macro _FILE_OFFSET_BITS=64
|
||||
@ -19,7 +19,6 @@
|
||||
#include <sys/vfs.h>
|
||||
|
||||
//dirent.h
|
||||
#define readdir_r readdir64_r
|
||||
#define readdir readdir64
|
||||
#define dirent dirent64
|
||||
//fcntl.h
|
||||
|
||||
156
contrib/oss-fuzz/fuzz_helpers.h
Normal file
156
contrib/oss-fuzz/fuzz_helpers.h
Normal file
@ -0,0 +1,156 @@
|
||||
// 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_
|
||||
63
contrib/oss-fuzz/libarchive_7zip_fuzzer.cc
Normal file
63
contrib/oss-fuzz/libarchive_7zip_fuzzer.cc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
47
contrib/oss-fuzz/libarchive_7zip_fuzzer.dict
Normal file
47
contrib/oss-fuzz/libarchive_7zip_fuzzer.dict
Normal file
@ -0,0 +1,47 @@
|
||||
# 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"
|
||||
10
contrib/oss-fuzz/libarchive_7zip_fuzzer.options
Normal file
10
contrib/oss-fuzz/libarchive_7zip_fuzzer.options
Normal file
@ -0,0 +1,10 @@
|
||||
[libfuzzer]
|
||||
max_len = 524288
|
||||
timeout = 60
|
||||
rss_limit_mb = 2048
|
||||
|
||||
[honggfuzz]
|
||||
timeout = 60
|
||||
|
||||
[afl]
|
||||
timeout = 60
|
||||
54
contrib/oss-fuzz/libarchive_ar_fuzzer.cc
Normal file
54
contrib/oss-fuzz/libarchive_ar_fuzzer.cc
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
20
contrib/oss-fuzz/libarchive_ar_fuzzer.dict
Normal file
20
contrib/oss-fuzz/libarchive_ar_fuzzer.dict
Normal file
@ -0,0 +1,20 @@
|
||||
# AR format dictionary
|
||||
|
||||
# AR magic
|
||||
"!<arch>\x0a"
|
||||
|
||||
# File header terminator
|
||||
"\x60\x0a"
|
||||
|
||||
# Special entries
|
||||
"/"
|
||||
"//"
|
||||
"/SYM64/"
|
||||
|
||||
# Common permissions
|
||||
"100644 "
|
||||
"100755 "
|
||||
|
||||
# UID/GID fields
|
||||
"0 "
|
||||
"1000 "
|
||||
51
contrib/oss-fuzz/libarchive_cab_fuzzer.cc
Normal file
51
contrib/oss-fuzz/libarchive_cab_fuzzer.cc
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
23
contrib/oss-fuzz/libarchive_cab_fuzzer.dict
Normal file
23
contrib/oss-fuzz/libarchive_cab_fuzzer.dict
Normal file
@ -0,0 +1,23 @@
|
||||
# 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"
|
||||
58
contrib/oss-fuzz/libarchive_cpio_fuzzer.cc
Normal file
58
contrib/oss-fuzz/libarchive_cpio_fuzzer.cc
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
25
contrib/oss-fuzz/libarchive_cpio_fuzzer.dict
Normal file
25
contrib/oss-fuzz/libarchive_cpio_fuzzer.dict
Normal file
@ -0,0 +1,25 @@
|
||||
# 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"
|
||||
101
contrib/oss-fuzz/libarchive_encryption_fuzzer.cc
Normal file
101
contrib/oss-fuzz/libarchive_encryption_fuzzer.cc
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
10
contrib/oss-fuzz/libarchive_encryption_fuzzer.options
Normal file
10
contrib/oss-fuzz/libarchive_encryption_fuzzer.options
Normal file
@ -0,0 +1,10 @@
|
||||
[libfuzzer]
|
||||
max_len = 524288
|
||||
timeout = 60
|
||||
rss_limit_mb = 2048
|
||||
|
||||
[honggfuzz]
|
||||
timeout = 60
|
||||
|
||||
[afl]
|
||||
timeout = 60
|
||||
105
contrib/oss-fuzz/libarchive_entry_fuzzer.cc
Normal file
105
contrib/oss-fuzz/libarchive_entry_fuzzer.cc
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
65
contrib/oss-fuzz/libarchive_filter_fuzzer.cc
Normal file
65
contrib/oss-fuzz/libarchive_filter_fuzzer.cc
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
33
contrib/oss-fuzz/libarchive_filter_fuzzer.dict
Normal file
33
contrib/oss-fuzz/libarchive_filter_fuzzer.dict
Normal file
@ -0,0 +1,33 @@
|
||||
# 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"
|
||||
10
contrib/oss-fuzz/libarchive_filter_fuzzer.options
Normal file
10
contrib/oss-fuzz/libarchive_filter_fuzzer.options
Normal file
@ -0,0 +1,10 @@
|
||||
[libfuzzer]
|
||||
max_len = 262144
|
||||
timeout = 30
|
||||
rss_limit_mb = 2048
|
||||
|
||||
[honggfuzz]
|
||||
timeout = 30
|
||||
|
||||
[afl]
|
||||
timeout = 30
|
||||
@ -3,20 +3,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "archive.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;
|
||||
}
|
||||
#include "fuzz_helpers.h"
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
|
||||
int ret;
|
||||
@ -26,7 +13,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};
|
||||
Buffer buffer = {buf, len, 0};
|
||||
archive_read_open(a, &buffer, NULL, reader_callback, NULL);
|
||||
|
||||
std::vector<uint8_t> data_buffer(getpagesize(), 0);
|
||||
|
||||
76
contrib/oss-fuzz/libarchive_fuzzer.dict
Normal file
76
contrib/oss-fuzz/libarchive_fuzzer.dict
Normal file
@ -0,0 +1,76 @@
|
||||
# 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"
|
||||
9
contrib/oss-fuzz/libarchive_fuzzer.options
Normal file
9
contrib/oss-fuzz/libarchive_fuzzer.options
Normal file
@ -0,0 +1,9 @@
|
||||
[libfuzzer]
|
||||
max_len = 524288
|
||||
timeout = 30
|
||||
|
||||
[honggfuzz]
|
||||
timeout = 30
|
||||
|
||||
[afl]
|
||||
timeout = 30
|
||||
58
contrib/oss-fuzz/libarchive_iso9660_fuzzer.cc
Normal file
58
contrib/oss-fuzz/libarchive_iso9660_fuzzer.cc
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
36
contrib/oss-fuzz/libarchive_iso9660_fuzzer.dict
Normal file
36
contrib/oss-fuzz/libarchive_iso9660_fuzzer.dict
Normal file
@ -0,0 +1,36 @@
|
||||
# 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"
|
||||
10
contrib/oss-fuzz/libarchive_iso9660_fuzzer.options
Normal file
10
contrib/oss-fuzz/libarchive_iso9660_fuzzer.options
Normal file
@ -0,0 +1,10 @@
|
||||
[libfuzzer]
|
||||
max_len = 1048576
|
||||
timeout = 60
|
||||
rss_limit_mb = 2048
|
||||
|
||||
[honggfuzz]
|
||||
timeout = 60
|
||||
|
||||
[afl]
|
||||
timeout = 60
|
||||
54
contrib/oss-fuzz/libarchive_lha_fuzzer.cc
Normal file
54
contrib/oss-fuzz/libarchive_lha_fuzzer.cc
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
26
contrib/oss-fuzz/libarchive_lha_fuzzer.dict
Normal file
26
contrib/oss-fuzz/libarchive_lha_fuzzer.dict
Normal file
@ -0,0 +1,26 @@
|
||||
# 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"
|
||||
110
contrib/oss-fuzz/libarchive_linkify_fuzzer.cc
Normal file
110
contrib/oss-fuzz/libarchive_linkify_fuzzer.cc
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
96
contrib/oss-fuzz/libarchive_match_fuzzer.cc
Normal file
96
contrib/oss-fuzz/libarchive_match_fuzzer.cc
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
61
contrib/oss-fuzz/libarchive_mtree_fuzzer.cc
Normal file
61
contrib/oss-fuzz/libarchive_mtree_fuzzer.cc
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
47
contrib/oss-fuzz/libarchive_mtree_fuzzer.dict
Normal file
47
contrib/oss-fuzz/libarchive_mtree_fuzzer.dict
Normal file
@ -0,0 +1,47 @@
|
||||
# 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"
|
||||
61
contrib/oss-fuzz/libarchive_rar5_fuzzer.cc
Normal file
61
contrib/oss-fuzz/libarchive_rar5_fuzzer.cc
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
37
contrib/oss-fuzz/libarchive_rar5_fuzzer.dict
Normal file
37
contrib/oss-fuzz/libarchive_rar5_fuzzer.dict
Normal file
@ -0,0 +1,37 @@
|
||||
# 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"
|
||||
56
contrib/oss-fuzz/libarchive_rar_fuzzer.cc
Normal file
56
contrib/oss-fuzz/libarchive_rar_fuzzer.cc
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
76
contrib/oss-fuzz/libarchive_read_disk_fuzzer.cc
Normal file
76
contrib/oss-fuzz/libarchive_read_disk_fuzzer.cc
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
110
contrib/oss-fuzz/libarchive_roundtrip_fuzzer.cc
Normal file
110
contrib/oss-fuzz/libarchive_roundtrip_fuzzer.cc
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
3
contrib/oss-fuzz/libarchive_roundtrip_fuzzer.options
Normal file
3
contrib/oss-fuzz/libarchive_roundtrip_fuzzer.options
Normal file
@ -0,0 +1,3 @@
|
||||
[libfuzzer]
|
||||
max_len = 65536
|
||||
timeout = 30
|
||||
125
contrib/oss-fuzz/libarchive_seek_fuzzer.cc
Normal file
125
contrib/oss-fuzz/libarchive_seek_fuzzer.cc
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
3
contrib/oss-fuzz/libarchive_seek_fuzzer.options
Normal file
3
contrib/oss-fuzz/libarchive_seek_fuzzer.options
Normal file
@ -0,0 +1,3 @@
|
||||
[libfuzzer]
|
||||
max_len = 262144
|
||||
timeout = 30
|
||||
144
contrib/oss-fuzz/libarchive_string_fuzzer.cc
Normal file
144
contrib/oss-fuzz/libarchive_string_fuzzer.cc
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
86
contrib/oss-fuzz/libarchive_tar_fuzzer.cc
Normal file
86
contrib/oss-fuzz/libarchive_tar_fuzzer.cc
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
51
contrib/oss-fuzz/libarchive_tar_fuzzer.dict
Normal file
51
contrib/oss-fuzz/libarchive_tar_fuzzer.dict
Normal file
@ -0,0 +1,51 @@
|
||||
# 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="
|
||||
50
contrib/oss-fuzz/libarchive_warc_fuzzer.cc
Normal file
50
contrib/oss-fuzz/libarchive_warc_fuzzer.cc
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
34
contrib/oss-fuzz/libarchive_warc_fuzzer.dict
Normal file
34
contrib/oss-fuzz/libarchive_warc_fuzzer.dict
Normal file
@ -0,0 +1,34 @@
|
||||
# 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"
|
||||
125
contrib/oss-fuzz/libarchive_write_disk_fuzzer.cc
Normal file
125
contrib/oss-fuzz/libarchive_write_disk_fuzzer.cc
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
3
contrib/oss-fuzz/libarchive_write_disk_fuzzer.options
Normal file
3
contrib/oss-fuzz/libarchive_write_disk_fuzzer.options
Normal file
@ -0,0 +1,3 @@
|
||||
[libfuzzer]
|
||||
max_len = 65536
|
||||
timeout = 30
|
||||
132
contrib/oss-fuzz/libarchive_write_fuzzer.cc
Normal file
132
contrib/oss-fuzz/libarchive_write_fuzzer.cc
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
60
contrib/oss-fuzz/libarchive_xar_fuzzer.cc
Normal file
60
contrib/oss-fuzz/libarchive_xar_fuzzer.cc
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
44
contrib/oss-fuzz/libarchive_xar_fuzzer.dict
Normal file
44
contrib/oss-fuzz/libarchive_xar_fuzzer.dict
Normal file
@ -0,0 +1,44 @@
|
||||
# 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"
|
||||
10
contrib/oss-fuzz/libarchive_xar_fuzzer.options
Normal file
10
contrib/oss-fuzz/libarchive_xar_fuzzer.options
Normal file
@ -0,0 +1,10 @@
|
||||
[libfuzzer]
|
||||
max_len = 524288
|
||||
timeout = 60
|
||||
rss_limit_mb = 2048
|
||||
|
||||
[honggfuzz]
|
||||
timeout = 60
|
||||
|
||||
[afl]
|
||||
timeout = 60
|
||||
68
contrib/oss-fuzz/libarchive_zip_fuzzer.cc
Normal file
68
contrib/oss-fuzz/libarchive_zip_fuzzer.cc
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
43
contrib/oss-fuzz/libarchive_zip_fuzzer.dict
Normal file
43
contrib/oss-fuzz/libarchive_zip_fuzzer.dict
Normal file
@ -0,0 +1,43 @@
|
||||
# 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"
|
||||
@ -1,16 +1,131 @@
|
||||
# build the project
|
||||
#!/bin/bash -eu
|
||||
|
||||
# Build the project
|
||||
./build/autogen.sh
|
||||
./configure
|
||||
make -j$(nproc) all
|
||||
|
||||
# build seed
|
||||
cp $SRC/libarchive/contrib/oss-fuzz/corpus.zip\
|
||||
$OUT/libarchive_fuzzer_seed_corpus.zip
|
||||
FUZZ_DIR=$SRC/libarchive/contrib/oss-fuzz
|
||||
TEST_DIR=$SRC/libarchive/libarchive/test
|
||||
|
||||
# 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
|
||||
# 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."
|
||||
|
||||
@ -13,8 +13,8 @@ IF(ENABLE_CPIO)
|
||||
cpio.c
|
||||
cpio.h
|
||||
cpio_platform.h
|
||||
../libarchive_fe/err.c
|
||||
../libarchive_fe/err.h
|
||||
../libarchive_fe/lafe_err.c
|
||||
../libarchive_fe/lafe_err.h
|
||||
../libarchive_fe/lafe_platform.h
|
||||
../libarchive_fe/line_reader.c
|
||||
../libarchive_fe/line_reader.h
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
#endif
|
||||
|
||||
#include "cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
/*
|
||||
* Short options for cpio. Please keep this sorted.
|
||||
|
||||
16
cpio/cpio.c
16
cpio/cpio.c
@ -60,7 +60,7 @@
|
||||
#endif
|
||||
|
||||
#include "cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
#include "line_reader.h"
|
||||
#include "passphrase.h"
|
||||
|
||||
@ -124,13 +124,21 @@ main(int argc, char *argv[])
|
||||
cpio->buff_size = sizeof(buff);
|
||||
|
||||
|
||||
#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
|
||||
{ /* Ignore SIGPIPE signals. */
|
||||
#if defined(HAVE_SIGACTION)
|
||||
{
|
||||
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
|
||||
|
||||
@ -717,7 +725,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->gname_override != NULL)
|
||||
if (cpio->uname_override != NULL)
|
||||
archive_entry_set_uname(entry, cpio->uname_override);
|
||||
if (cpio->gid_override >= 0)
|
||||
archive_entry_set_gid(entry, cpio->gid_override);
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#include <sddl.h>
|
||||
|
||||
#include "cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
#define EPOC_TIME (116444736000000000ULL)
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
IF(ENABLE_CPIO AND ENABLE_TEST)
|
||||
SET(bsdcpio_test_SOURCES
|
||||
../cmdline.c
|
||||
../../libarchive_fe/err.c
|
||||
../../libarchive_fe/lafe_err.c
|
||||
../../test_utils/test_utils.c
|
||||
../../test_utils/test_main.c
|
||||
test.h
|
||||
|
||||
@ -219,7 +219,7 @@ DEFINE_TEST(test_format_newc)
|
||||
assert(is_hex(e, 110));
|
||||
assertEqualMem(e + 0, "070701", 6); /* Magic */
|
||||
assert(is_hex(e + 6, 8)); /* ino */
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Mode: Group members bits and others bits do not work. */
|
||||
assertEqualInt(0xa180, from_hex(e + 14, 8) & 0xffc0);
|
||||
#else
|
||||
|
||||
@ -52,7 +52,7 @@ test_create(void)
|
||||
* #ifdef this section out. Most of the test below is
|
||||
* still valid. */
|
||||
memset(×, 0, sizeof(times));
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
times.actime = 86400;
|
||||
times.modtime = 86400;
|
||||
#else
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#include "test.h"
|
||||
|
||||
#include "../cpio.h"
|
||||
#include "err.h"
|
||||
#include "lafe_err.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#define ROOT "root"
|
||||
|
||||
@ -52,6 +52,7 @@ 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
|
||||
@ -248,11 +249,14 @@ IF(BUILD_SHARED_LIBS)
|
||||
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
|
||||
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
|
||||
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
|
||||
SET_TARGET_PROPERTIES(archive PROPERTIES
|
||||
SET_TARGET_PROPERTIES(archive PROPERTIES
|
||||
VERSION ${SOVERSION_FULL}
|
||||
SOVERSION ${SOVERSION}
|
||||
MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
|
||||
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
|
||||
@ -261,6 +265,9 @@ 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)
|
||||
@ -271,13 +278,13 @@ IF(ENABLE_INSTALL)
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
INSTALL(TARGETS archive
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
INSTALL(TARGETS archive_static
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
INSTALL_MAN(${libarchive_MANS})
|
||||
INSTALL(FILES ${include_HEADERS} DESTINATION include)
|
||||
ENDIF()
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3008000
|
||||
#define ARCHIVE_VERSION_NUMBER 3009000
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void);
|
||||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.8.0dev"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.9.0dev"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
@ -210,7 +210,9 @@ __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);
|
||||
@ -1250,8 +1252,10 @@ __LA_DECL int archive_match_include_gname_w(struct archive *,
|
||||
const wchar_t *);
|
||||
|
||||
/* Utility functions */
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Convenience function to sort a NULL terminated list of strings */
|
||||
__LA_DECL int archive_utility_string_sort(char **);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -270,6 +270,19 @@ 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. */
|
||||
@ -822,6 +835,9 @@ 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':';
|
||||
@ -878,6 +894,7 @@ 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);
|
||||
@ -1057,6 +1074,9 @@ append_entry(char **p, const char *prefix, int type,
|
||||
name = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
default:
|
||||
**p = '\0';
|
||||
break;
|
||||
}
|
||||
*p += strlen(*p);
|
||||
*(*p)++ = ':';
|
||||
@ -1112,6 +1132,9 @@ 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);
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@ -54,8 +55,14 @@ 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;
|
||||
}
|
||||
|
||||
@ -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) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
#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 -1; /* UNSUPPORTED */
|
||||
return CRYPTOR_STUB_FUNCTION; /* UNSUPPORTED */
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -197,7 +197,7 @@ aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
|
||||
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 -1;
|
||||
return CRYPTOR_STUB_FUNCTION;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
(void)ctx; /* UNUSED */
|
||||
return -1;
|
||||
return CRYPTOR_STUB_FUNCTION;
|
||||
}
|
||||
|
||||
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 -1;
|
||||
return CRYPTOR_STUB_FUNCTION;
|
||||
}
|
||||
|
||||
#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;
|
||||
unsigned pos = ctx->encr_pos;
|
||||
unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
|
||||
unsigned i;
|
||||
size_t pos = ctx->encr_pos;
|
||||
size_t max = (in_len < *out_len)? in_len: *out_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < max; ) {
|
||||
if (pos == AES_BLOCK_SIZE) {
|
||||
|
||||
@ -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
|
||||
# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -56,13 +56,13 @@ int __libarchive_cryptor_build_hack(void);
|
||||
typedef struct {
|
||||
CCCryptorRef ctx;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
size_t key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
size_t encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
#include <bcrypt.h>
|
||||
#define ARCHIVE_CRYPTOR_USE_CNG 1
|
||||
|
||||
@ -168,6 +168,9 @@ 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
|
||||
|
||||
@ -44,16 +44,11 @@
|
||||
/*
|
||||
* Message digest functions for Windows platform.
|
||||
*/
|
||||
#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)
|
||||
#if defined(HAVE_BCRYPT_H)
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
@ -72,30 +67,6 @@ 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.
|
||||
@ -107,42 +78,26 @@ 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(ARCHIVE_CRYPTO_*_WIN) */
|
||||
#endif /* defined(HAVE_BCRYPT_H) */
|
||||
|
||||
|
||||
/* MD5 implementations */
|
||||
@ -234,11 +189,7 @@ __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
|
||||
@ -645,11 +596,7 @@ __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
|
||||
@ -925,11 +872,7 @@ __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
|
||||
@ -1177,11 +1120,7 @@ __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
|
||||
@ -1453,11 +1392,7 @@ __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
|
||||
|
||||
@ -165,8 +165,7 @@
|
||||
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_WIN)
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
/* don't use bcrypt when XP needs to be supported */
|
||||
#if defined(HAVE_BCRYPT_H)
|
||||
#include <bcrypt.h>
|
||||
#define ARCHIVE_CRYPTO_CNG 1
|
||||
typedef struct {
|
||||
@ -174,15 +173,6 @@ 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
|
||||
|
||||
|
||||
@ -124,7 +124,6 @@ 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;
|
||||
@ -195,7 +194,7 @@ add_trivial_nfs4_acl(struct archive_entry *entry)
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tacl_entry[1].permset |= eperm;
|
||||
|
||||
for (i = 0; i < sizeof(tacl_entry) / sizeof(tacl_entry[0]); i++) {
|
||||
for (size_t 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,
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3008000
|
||||
#define ARCHIVE_VERSION_NUMBER 3009000
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
.Fn archive_entry_size_is_set
|
||||
can be used to query that status.
|
||||
.Fn archive_entry_set_size
|
||||
and
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
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));
|
||||
@ -74,7 +75,10 @@ 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);
|
||||
st->st_size = (off_t)archive_entry_size(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_mode = archive_entry_mode(entry);
|
||||
|
||||
/*
|
||||
|
||||
@ -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) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
|
||||
#ifndef BCRYPT_HASH_REUSABLE_FLAG
|
||||
# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
|
||||
|
||||
@ -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) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
#include <bcrypt.h>
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -35,6 +35,9 @@
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
@ -53,8 +56,7 @@ struct match {
|
||||
struct match_list {
|
||||
struct match *first;
|
||||
struct match **last;
|
||||
int count;
|
||||
int unmatched_count;
|
||||
size_t unmatched_count;
|
||||
struct match *unmatched_next;
|
||||
int unmatched_eof;
|
||||
};
|
||||
@ -73,7 +75,6 @@ struct match_file {
|
||||
struct entry_list {
|
||||
struct match_file *first;
|
||||
struct match_file **last;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct id_array {
|
||||
@ -144,12 +145,15 @@ static int add_pattern_mbs(struct archive_match *, struct match_list *,
|
||||
const char *);
|
||||
static int add_pattern_wcs(struct archive_match *, struct match_list *,
|
||||
const wchar_t *);
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
static int cmp_key_mbs(const struct archive_rb_node *, const void *);
|
||||
static int cmp_key_wcs(const struct archive_rb_node *, const void *);
|
||||
static int cmp_node_mbs(const struct archive_rb_node *,
|
||||
const struct archive_rb_node *);
|
||||
#else
|
||||
static int cmp_key_wcs(const struct archive_rb_node *, const void *);
|
||||
static int cmp_node_wcs(const struct archive_rb_node *,
|
||||
const struct archive_rb_node *);
|
||||
#endif
|
||||
static void entry_list_add(struct entry_list *, struct match_file *);
|
||||
static void entry_list_free(struct entry_list *);
|
||||
static void entry_list_init(struct entry_list *);
|
||||
@ -189,12 +193,12 @@ static int validate_time_flag(struct archive *, int, const char *);
|
||||
|
||||
#define get_date archive_parse_date
|
||||
|
||||
static const struct archive_rb_tree_ops rb_ops_mbs = {
|
||||
static const struct archive_rb_tree_ops rb_ops = {
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
cmp_node_mbs, cmp_key_mbs
|
||||
};
|
||||
|
||||
static const struct archive_rb_tree_ops rb_ops_wcs = {
|
||||
#else
|
||||
cmp_node_wcs, cmp_key_wcs
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -228,7 +232,7 @@ archive_match_new(void)
|
||||
a->recursive_include = 1;
|
||||
match_list_init(&(a->inclusions));
|
||||
match_list_init(&(a->exclusions));
|
||||
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
|
||||
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops);
|
||||
entry_list_init(&(a->exclusion_entry_list));
|
||||
match_list_init(&(a->inclusion_unames));
|
||||
match_list_init(&(a->inclusion_gnames));
|
||||
@ -507,7 +511,9 @@ archive_match_path_unmatched_inclusions(struct archive *_a)
|
||||
ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions");
|
||||
a = (struct archive_match *)_a;
|
||||
|
||||
return (a->inclusions.unmatched_count);
|
||||
if (a->inclusions.unmatched_count > (size_t)INT_MAX)
|
||||
return INT_MAX;
|
||||
return (int)(a->inclusions.unmatched_count);
|
||||
}
|
||||
|
||||
int
|
||||
@ -650,7 +656,7 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (*b == 0x0d || *b == 0x0a) {
|
||||
if (*b == 0x0d || *b == 0x0a) {
|
||||
found_separator = 1;
|
||||
break;
|
||||
}
|
||||
@ -735,7 +741,7 @@ path_excluded(struct archive_match *a, int mbs, const void *pathname)
|
||||
}
|
||||
}
|
||||
|
||||
/* Exclusions take priority */
|
||||
/* Exclusions take priority. */
|
||||
for (match = a->exclusions.first; match != NULL;
|
||||
match = match->next){
|
||||
r = match_path_exclusion(a, match, mbs, pathname);
|
||||
@ -834,7 +840,6 @@ match_list_init(struct match_list *list)
|
||||
{
|
||||
list->first = NULL;
|
||||
list->last = &(list->first);
|
||||
list->count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -855,7 +860,6 @@ match_list_add(struct match_list *list, struct match *m)
|
||||
{
|
||||
*list->last = m;
|
||||
list->last = &(m->next);
|
||||
list->count++;
|
||||
list->unmatched_count++;
|
||||
}
|
||||
|
||||
@ -1275,6 +1279,7 @@ set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
|
||||
/*
|
||||
* Call back functions for archive_rb.
|
||||
*/
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
static int
|
||||
cmp_node_mbs(const struct archive_rb_node *n1,
|
||||
const struct archive_rb_node *n2)
|
||||
@ -1291,7 +1296,7 @@ cmp_node_mbs(const struct archive_rb_node *n1,
|
||||
return (-1);
|
||||
return (strcmp(p1, p2));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmp_key_mbs(const struct archive_rb_node *n, const void *key)
|
||||
{
|
||||
@ -1303,7 +1308,7 @@ cmp_key_mbs(const struct archive_rb_node *n, const void *key)
|
||||
return (-1);
|
||||
return (strcmp(p, (const char *)key));
|
||||
}
|
||||
|
||||
#else
|
||||
static int
|
||||
cmp_node_wcs(const struct archive_rb_node *n1,
|
||||
const struct archive_rb_node *n2)
|
||||
@ -1320,7 +1325,7 @@ cmp_node_wcs(const struct archive_rb_node *n1,
|
||||
return (-1);
|
||||
return (wcscmp(p1, p2));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmp_key_wcs(const struct archive_rb_node *n, const void *key)
|
||||
{
|
||||
@ -1332,13 +1337,13 @@ cmp_key_wcs(const struct archive_rb_node *n, const void *key)
|
||||
return (-1);
|
||||
return (wcscmp(p, (const wchar_t *)key));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
entry_list_init(struct entry_list *list)
|
||||
{
|
||||
list->first = NULL;
|
||||
list->last = &(list->first);
|
||||
list->count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1359,7 +1364,6 @@ entry_list_add(struct entry_list *list, struct match_file *file)
|
||||
{
|
||||
*list->last = file;
|
||||
list->last = &(file->next);
|
||||
list->count++;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1382,9 +1386,7 @@ add_entry(struct archive_match *a, int flag,
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
archive_mstring_copy_wcs(&(f->pathname), pathname);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
|
||||
#else
|
||||
(void)rb_ops_wcs;
|
||||
pathname = archive_entry_pathname(entry);
|
||||
if (pathname == NULL) {
|
||||
free(f);
|
||||
@ -1392,7 +1394,6 @@ add_entry(struct archive_match *a, int flag,
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
archive_mstring_copy_mbs(&(f->pathname), pathname);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_mbs;
|
||||
#endif
|
||||
f->flag = flag;
|
||||
f->mtime_sec = archive_entry_mtime(entry);
|
||||
@ -1517,16 +1518,13 @@ time_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
}
|
||||
|
||||
/* If there is no exclusion list, include the file. */
|
||||
if (a->exclusion_entry_list.count == 0)
|
||||
if (a->exclusion_entry_list.first == NULL)
|
||||
return (0);
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
pathname = archive_entry_pathname_w(entry);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
|
||||
#else
|
||||
(void)rb_ops_wcs;
|
||||
pathname = archive_entry_pathname(entry);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_mbs;
|
||||
#endif
|
||||
if (pathname == NULL)
|
||||
return (0);
|
||||
@ -1682,7 +1680,7 @@ archive_match_owner_excluded(struct archive *_a,
|
||||
static int
|
||||
add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
|
||||
{
|
||||
unsigned i;
|
||||
size_t i;
|
||||
|
||||
if (ids->count + 1 >= ids->size) {
|
||||
void *p;
|
||||
@ -1719,10 +1717,10 @@ add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
|
||||
static int
|
||||
match_owner_id(struct id_array *ids, int64_t id)
|
||||
{
|
||||
unsigned b, m, t;
|
||||
size_t b, m, t;
|
||||
|
||||
t = 0;
|
||||
b = (unsigned)ids->count;
|
||||
b = ids->count;
|
||||
while (t < b) {
|
||||
m = (t + b)>>1;
|
||||
if (ids->ids[m] == id)
|
||||
@ -1817,7 +1815,7 @@ owner_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (a->inclusion_unames.count) {
|
||||
if (a->inclusion_unames.first != NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
r = match_owner_name_wcs(a, &(a->inclusion_unames),
|
||||
archive_entry_uname_w(entry));
|
||||
@ -1831,7 +1829,7 @@ owner_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
return (r);
|
||||
}
|
||||
|
||||
if (a->inclusion_gnames.count) {
|
||||
if (a->inclusion_gnames.first != NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
r = match_owner_name_wcs(a, &(a->inclusion_gnames),
|
||||
archive_entry_gname_w(entry));
|
||||
|
||||
@ -703,9 +703,7 @@ 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;
|
||||
/* 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
|
||||
if (Year < EPOCH || (sizeof(time_t) <= 4 && Year >= 2038)
|
||||
|| Month < 1 || Month > 12
|
||||
/* Lint fluff: "conversion from long may lose accuracy" */
|
||||
|| Day < 1 || Day > DaysInMonth[(int)--Month]
|
||||
|
||||
@ -183,16 +183,6 @@
|
||||
#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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user