Commit Graph
713 Commits
Author SHA1 Message Date
Malachi Moody 88f49e2623 tests: reproduce invalid CAB LZX history reference 2026-08-08 13:59:18 -05:00
Dustin L. Howett 6b89e4f9d6 Merge pull request #3340 from subotac/fix/7zip-ppmd-small-read-buffer
7zip: Track PPMd input across read blocks
2026-08-08 13:10:12 -05:00
subotac f514e28373 7zip: Add PPMd small read block regression test
The fixture and reproducer are based on the archive and report provided by @004helix in #3337.
2026-08-08 14:31:35 +03:00
Dustin L. Howett d83294359b Merge pull request #3346 from stoeckmann/append_filter_desync
Always attach filter to correct bidder
2026-08-03 12:48:35 -05:00
Tobias Stoeckmann bf1f5ba79e append_filter: Verify that bidder and filter match
Make sure that appending a filter always matches its supposed bidder.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-08-02 15:12:59 +02:00
Dan Nelson e8154e0bfc tar: add --mode option (compatible with gnutar) 2026-08-01 15:11:08 -05:00
Jin 79b06edf6e archive_read: don't poison archive when seek is unsupported (fixes #3323)
3.8.8 ("make ARCHIVE_FATAL sticky in data-reading entry points",
commit e1f890dc) made archive_seek_data() set
a->archive.state = ARCHIVE_STATE_FATAL whenever the call returned
ARCHIVE_FATAL.  That is correct for genuine I/O / parse failures
returned by a format's seek_data() implementation, but it also
poisoned the archive in two cases where seeking is simply
unsupported for the current format:

  1. The seek_data == NULL branch in archive_seek_data() itself
     (no format_seek_data_block registered: ustar/tar, the
     streaming ZIP reader, ...).

  2. rar5_seek_data() in archive_read_support_format_rar5.c, which
     unconditionally returns ARCHIVE_FATAL because RAR5 is a
     streaming unpacker.  This was latent before 3.8.8 because
     the read core did not make FATAL sticky; the stickiness
     change exposed it.

Both are capability gaps, not stream corruption.  ARCHIVE_FATAL
must always be sticky (it means the archive is irrecoverably
damaged), so both sites now return ARCHIVE_FAILED with an error
string instead.  ARCHIVE_FAILED is recoverable: capability probes
such as

    if (archive_seek_data(a, 0, SEEK_CUR) >= 0) ...

learn that seeking is unavailable while the archive remains
usable for subsequent reads.  The sticky-on-genuine-FATAL part of
the original 3.8.8 change is preserved for actual ARCHIVE_FATAL
returns from a format's seek_data() implementation.

The seek_data == NULL branch also reports the condition better: a
format that never registers a seek hook is not illegal use of the
library, so the error is now ARCHIVE_ERRNO_MISC / "Cannot seek
data with this format" instead of ARCHIVE_ERRNO_PROGRAMMER /
"Internal error: No format_seek_data_block function registered".

The rar5 change also matches how the RAR4 reader already reports
the same situation (archive_read_support_format_rar.c:1339
returns ARCHIVE_FAILED for compressed RAR files).

This restores 3.8.7 behaviour for clients that probe seekability
before reading.  VLC's skins2 stream extractor
(modules/stream_extractor/archive.c, archive_seek_subentry())
probes with archive_seek_data(a, 0, SEEK_CUR); on a non-seekable
format the poisoned state killed all later archive_read_data()
calls, breaking ZIP-packed .vlt skins on distributions shipping
libarchive 3.8.8.

Tests:
  - test_archive_seek_data_unsupported: covers the seek_data==NULL
    branch using a ustar archive.
  - test_read_format_rar5_seek_data_unsupported: covers the
    rar5_seek_data() branch using an existing RAR5 fixture, and
    verifies the entry content with verify_data() after the probe.
  Both fail on master and pass with this change.
2026-07-28 00:30:34 +08:00
Dustin L. Howett f5509ae993 Merge pull request #3299 from datauwu/tar-read-fix-uaf
tar: fix UAF when reading GNU sparse headers
2026-07-21 13:13:03 -05:00
Dustin L. Howett 0b71b606dd Merge commit from fork
Fix RAR seek_data cursor underflow
2026-07-21 12:55:13 -05:00
Tobias Stoeckmann 91fa66073e tar: Verify that huge files are not written
Files which cannot fit into a stream should never return success, which
can happen due to truncation on 32 bit systems.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-19 23:07:44 +02:00
0xmrniko f3d21565cb Add RAR seek_data cursor regression test 2026-07-19 19:30:18 +05:30
datauwu dc81f68c6f tar: add GNU sparse header buffer reuse test
Add a test archive that reuses one read buffer for every 512-byte block.

Reading the sparse extension overwrites the main GNU header. Check that
mode, uid, gid, and mtime still come from the original header.
2026-07-18 15:48:44 +08:00
Dustin L. Howett 1a9e48f6b8 iso9660: add a test for repeated long-named files blowing up RR blocks 2026-07-15 15:07:29 -05:00
Dustin L. Howett a6a899d655 Merge pull request #3278 from uchiha-bug-hunter/cpio-trailer-uaf
cpio: add regression test for symlink-trailer end-of-archive check
2026-07-13 12:03:30 -05:00
Tim Kientzle 46e9236e4e Merge pull request #3272 from daandemeyer/push-kysumqozmsuq
pax: add "align" write option for reflink-friendly archives
2026-07-13 07:53:21 -07:00
Kaif Khan 54b7f1f679 xar: fix one-byte over-read in parse_time date parser 2026-07-13 19:31:09 +05:30
Daan De Meyer 7d53dd2b49 pax: add "align" write option for reflink-friendly archives
Add a per-format "align" option to the pax writer that pads each
regular file's pax extended header (creating one if necessary) so the
file data that follows begins on a multiple of the requested number of
bytes within the uncompressed archive stream.  The value must be a
power of two and a multiple of the 512-byte tar block.

The alignment is applied to the stream feeding into any compression
filter, so the decompressed archive is aligned regardless of whether
the archive is compressed.  This lets tools share file contents out of
an (uncompressed copy of an) archive using reflinks / copy_file_range(2)
instead of doing a full data copy on extraction.

The padding is carried in an ignorable "LIBARCHIVE.pad" pax record, so
existing readers extract the archive unchanged.  Files shorter than the
alignment are left unpadded since they cannot share a whole block.

Add a test covering uncompressed and gzip-compressed archives and
document the option.

Signed-off-by: Daan De Meyer <daan@amutable.com>
2026-07-13 09:47:24 +02:00
Kaif Khan b76abee5b1 cpio: add regression test for symlink-trailer end-of-archive check
A symlink entry named TRAILER!!! with a body large enough to grow the
read filter's copy buffer used to leave the cached name pointer stale
before the end-of-archive comparison.  Read a static newc archive in
small blocks and assert the trailer is still detected (ARCHIVE_EOF).

The fix landed in 23b54da; this only adds coverage.
2026-07-13 11:44:09 +05:30
Tobias Stoeckmann e04051cb4b cab: Add large LZX pre-tree test
If a pre-tree is larger than 10 bit, libarchive fails to read the data.
According to spec, up to 16 bit are valid.

Example file provided by Duncan Horn. Thanks a lot!

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann ba202cdafc Merge pull request #3259 from uchiha-bug-hunter/7zip-bound-header-counts
7zip: bound folder and stream counts before allocating
2026-07-09 08:34:32 +02:00
Kaif Khan 18449a3f8d archive_string: add test for best-effort converter over-read
Drives the best-effort converter (charset iconv cannot open) through
archive_strncpy_l with a length-delimited buffer: once with trailing
non-NUL bytes after the declared length and once with an exact-length
heap allocation with no trailing NUL. Fails under ASan before the fix.
2026-07-08 22:10:19 +05:30
Kaif Khan e5d72383a6 7zip: bound NumFolders before allocating folders array 2026-07-08 01:13:52 +05:30
Kaif Khan 91648e29bd tar: add test for SUN.holesdata sparse map ending on a digit
Read a Solaris pax entry whose SUN.holesdata value ends right after its
final decimal offset (no trailing space), which is the shape of every
valid map. The 1536-byte file has data at [0,512) and [1024,1536) with a
hole between them, so archive_entry_sparse must report exactly those two
data blocks. This pins the parser's loop-termination behavior for the
common case where the run consumes all value_length bytes.
2026-07-07 23:44:50 +05:30
Dustin L. Howett 51060e492b Merge pull request #3236 from uchiha-bug-hunter/acl-from-text-nl-overread
acl: fix over-read on empty field in archive_acl_from_text_nl
2026-07-06 09:29:59 -05:00
Tim Kientzle f2f3eb9f50 Merge pull request #3245 from kientzle/kientzle-archive-read-failed-header-recovery
[Read core] Allow format handlers to FAIL a header read
2026-07-05 10:36:10 -07:00
Tim Kientzle 0409837cb9 [Read core] Test handling of FAILED header reads
While investigating improvements to Zip's header reading,
I found	an overlooked case in the read core:  When a format
returned FAILED	for a header read (indicating that the entry
could not be read but that the archive as a whole is still valid),
the core silently converted that to FATAL, ending the archive
at that	point.

Two formats already returned FAILED for	certain	header issues:
Zip and	LHA both indicated unreadable symlink entries in this way,
which should allow the rest of the archive to continue being read.
New tests here verify that we can now continue reading past
such entries, and that clients who ignore the FAILED result
get the	same FATAL handling as other API misuse.
2026-07-05 10:11:50 -07:00
Kaif Khan 18f5209e48 acl: add test_acl_from_text_overread regression test
Drives archive_acl_from_text_nl() with exact-length, non-NUL-terminated
buffers whose first field is only whitespace, covering the empty-entry
and trailing-whitespace cases.  Allow the test to include
archive_acl_private.h via __LIBARCHIVE_TEST.
2026-07-05 13:39:52 +05:30
datauwu 9a2087f9d7 zip: test PKWARE Unix extra field
Add a test for the PKWARE Unix extra field 0x000d.

The fixture stores a regular file with the 12-byte fixed metadata
prefix in both the local header and central directory. The test checks
that the ZIP reader exposes mtime, atime, uid, and gid metadata for
seekable and streaming reads.
2026-07-05 13:22:03 +08:00
Tim Kientzle d21fdc9f84 Merge pull request #3240 from kientzle/kientzle-zip-uncompressed-size-exact-check
[Zip] Reject archives if the 32-bit size field is not correct
2026-07-04 22:06:35 -07:00
Dustin L. Howett 3c3ec69d44 Merge pull request #3232 from kientzle/kientzle-read-data-into-fd-size-boundary
[Write] Truncate write-to-fd at the declared entry size
2026-07-04 15:08:23 -05:00
Tobias Stoeckmann 41a72e5553 Merge pull request #3231 from datauwu/7zip-skip-archiveproperties
7zip: skip ArchiveProperties payload data
2026-07-04 09:56:23 +02:00
Tim Kientzle e7e408a1a9 [Write] Truncate write-to-fd at the declared entry size
This is the test for....

Update the common archive_read_data_into_fd() to truncate
output to the actual entry size from the most recent
archive_read_header result.

This addresses a hole in handling of certain subtly-malformed archives
that can have more data than declared in the header.  Before this,
bsdtar explicitly truncates the entry data to the actual declared size
when extracting to a file, but did not do so when extracting to
stdout.
2026-07-03 21:41:08 -07:00
Tim Kientzle 1559ae86da [Zip] Be strict about the 32-bit uncompressed size
Test:  If the uncompressed size stored in the archive differs
from the actual uncompressed size by a multiple of 2^32,
we should report some kind of error.

This currently goes undiagnosed because of an old attempt
to support larger-than-4GiB entries in plain 32-bit Zip
archives without necessarily requiring Zip64 extensions.
While this is technically feasible, it requires treating
the 32-bit size field ambiguously, which can lead to size
confusion from readers.
2026-07-03 21:22:48 -07:00
Tim Kientzle 5a2ec45b9c Merge pull request #3230 from kientzle/kientzle-zip-reject-overlong-bodies
[Zip] Reject entries with overlong bodies
2026-07-03 13:26:30 -07:00
Tim Kientzle 5f29836190 [Zip] Reject entries with overlong bodies
Tests for...

If an entry declares an uncompressed size, we should not return any
data beyond that point.  This doesn't impact bsdtar and friends since
they independently truncate to the declared entry size, but other
clients may not be so careful.

Apparently discovered (but not reported) by @bikini
Reported by @dkgkdfg65
2026-07-03 13:13:31 -07:00
datauwu 49a273e314 7zip: add ArchiveProperties payload test
Add a 7z test archive with a non-empty ArchiveProperties payload.

The archive has one empty file and an ArchiveProperties entry with a
1-byte payload. It is accepted by 7-Zip/7zz.

This covers parsing when ArchiveProperties has payload bytes.
2026-07-04 01:44:58 +08:00
Tobias Stoeckmann 53d1c0bc65 cab: Add E8 translation test
Covers basic E8 translations, yet it lacks the handling of negative
values because this would require large archives.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-03 17:37:37 +02:00
Dustin L. Howett f59675ccff Merge pull request #3207 from datauwu/tests-merge-fix-typo
tests: merge tests and fix misleading labels
2026-06-30 11:33:06 -05:00
datauwu 6333be32b8 7zip: add SFX boundary tests
Add PE and ELF SFX fixtures for the SFX scanner boundary cases.

The PE fixture places an empty 7z archive at the final exact
32-byte scan window. The ELF fixture places ".data\0" at the final
valid section string-table position.

Register the fixtures for autotools distcheck.
2026-06-30 21:46:54 +08:00
datauwu 5e1afc9b42 zip: fix lzma/xz compression test name
The ZIP compression test name used lzmaxz even though the test covers
the LZMA and XZ compression paths. Rename it to lzma_xz.
2026-06-30 17:12:11 +08:00
datauwu e519625cf5 iso9660: fix compress test names
Several ISO tests used a bz2 suffix even though they read .Z files
and verify ARCHIVE_FILTER_COMPRESS. Rename them to use a compress
suffix so the test names match the filter.
2026-06-30 17:12:11 +08:00
datauwu ae78682a02 archive_write: group option setter tests
The write option setter checks used several tiny source files with the
same basic shape.

Keep the same DEFINE_TEST cases. Put the write-side option setter
checks in test_archive_write_set_options.c. Remove the extra source
files from the build lists.
2026-06-30 17:12:10 +08:00
datauwu 25533dd722 archive_read: group option setter tests
The read option setter checks used several tiny source files with the
same basic shape.

Keep the same DEFINE_TEST cases. Put the read-side option setter
checks in test_archive_read_set_options.c. Remove the extra source
files from the build lists.
2026-06-30 17:12:10 +08:00
datauwu d6e1e7bc3d archive_read: group close-twice tests
The close-twice read checks used three tiny source files.

Keep the same DEFINE_TEST cases. Put the fresh-object, fd-backed,
and filename-backed checks in one source file. Remove the two extra
files from the build lists.
2026-06-30 17:12:09 +08:00
Dustin L. Howett 588363eb4e Merge pull request #3187 from nvmb3r/rar5-unpacked-size-limit
rar5: reject streams that exceed the declared unpacked size
2026-06-29 11:30:15 -05:00
Kaif Khan 86e5498285 iso9660: add regression test for short ZF entry over-read 2026-06-29 11:28:38 +05:30
nvmb3r b41a768d61 rar5: add unpacked-size regression test 2026-06-28 17:35:16 -07:00
Tobias Stoeckmann 4558c310de Merge pull request #3167 from stoeckmann/unzip_windows
unzip: Add Windows port
2026-06-27 16:56:53 +02:00
Kaif Khan 0352fe5033 xar: add regression test for atou64 numeric field over-read
Exercise atou64() through a TOC numeric element (<inode>) read via the
expat backend, which hands the parser its raw, non-NUL-terminated
character-data buffer. Mirrors test_read_format_xar_base64_oob; build
with ASan for the out-of-bounds coverage.
2026-06-26 13:57:11 +05:30
Reyad Attiyat bf0ce94fec unzip: mark bsdunzip as long-path aware on Windows
Signed-off-by: God-damnit-all <53661808+God-damnit-all@users.noreply.github.com>
2026-06-24 18:02:20 +02:00