Commit e1f890dc62f7931d971e2483efd8a3d30a98b1f4 fixed the underlying
root cause of these OOB checks: If a header is invalid and ARCHIVE_FATAL
is returned, do not allow data reads anymore.
The checks while reading CFDATA already looked rather off, since the
check exists in header parser and the value is never updated, but
prevent worst case scenario.
Keep the tests as regression tests if archive_read.c is modified again.
The comment states that a warning should be returned, but 97f964e3e0ce3ae34bfb4c366a37ba7c0d9610a6 explicitly changed that to
fatal. Adjust the comment and remove unneeded function call.
data [Mon, 29 Jun 2026 09:10:11 +0000 (17:10 +0800)]
7zip: remove redundant read header checks
archive_read_format_7zip_read_header() already returns before this
point if zip_entry is NULL. The folder pointer is also assigned from an
in-bounds folder array entry, so the extra NULL checks are redundant.
The later DONT_KNOW reset is redundant as well, since the same state is
handled earlier in the function. Remove the dead checks without changing
the encryption detection logic.
data [Sun, 28 Jun 2026 13:28:15 +0000 (21:28 +0800)]
7zip: remove redundant per-entry setup
`archive_read_format_7zip_read_header()` initialized `entry_crc32` with
`crc32(0, NULL, 0)`, which is equivalent to zero for this accumulator.
The same function also formatted the constant string `"7-Zip"` into an
internal buffer for every entry, then assigned it as the archive format name.
The format name can be set directly to the constant string, so the extra
buffer and per-entry `snprintf()` are unnecessary.
Remove the unused buffer and redundant per-entry work.
data [Sun, 28 Jun 2026 10:43:13 +0000 (18:43 +0800)]
zip: harden test cleanup assertion
assertEqualIntA() uses the archive pointer to print archive error details
when the assertion fails. Passing `a` while the asserted expression is
`archive_free(a)` can make the failure path inspect the archive after it has
already been freed.
Dustin L. Howett [Fri, 26 Jun 2026 13:45:58 +0000 (08:45 -0500)]
disk (win32): when caching a path as symlink-safe, only cache the parent
We used to cache the entire target path, which presented a problem when
we used that target path to write a symlink. Future archive entries
could write "through" that symlink because we cached it as safe.
Make sure that all bytes are actually skipped. Normally, the result can
be ignored because the bytes were read previously. Here, more bytes than
previously read will be skipped.
Introduce parse_7zip_size, which performs the UMAX_ENTRY check.
Generally, use this function whenever memory allocation sizes or indices
into memory allocations are used, i.e. when size_t is meant.
Verify that sum of numUnpackStreams will never overflow numDigests. For
this, also set numDigests to size_t because that's how the variable is
used later on.
The skip_stream function is supposed to skip a specified amount of bytes
from input stream. Since streams could be larger than 4 GB even on 32
bit systems, do not cast to size_t. Instead, read the data in small
chunks until all bytes are skipped.
This also helps to avoid large allocations on 64 bit systems.
Also verify that skipped_bytes tracking cannot overflow.
While at it, change return value to int because it's only needed for
status information, i.e. if operation was successful or not. This avoids
another cast issue with uint64_t values larger than INT64_MAX.
Kaif Khan [Fri, 26 Jun 2026 08:27:11 +0000 (13:57 +0530)]
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.
Luca Boccassi [Thu, 25 Jun 2026 15:53:19 +0000 (16:53 +0100)]
read_data_into_fd: Fix spurious "Seek error" for trailing holes
The final seek check never advanced actual_offset for the trailing
hole created by the EOF pad_to(), so extracting any sparse file whose
last region is a hole failed with ARCHIVE_FATAL "Seek error".
This affects the systemd CI which does such an operation, and now
fails since PR https://github.com/libarchive/libarchive/pull/3128
was merged and appeared in Archlinux:
[ 269.636946] TEST-13-NSPAWN.sh[5439]: + run0 --pipe -u testuser importctl -m --user import-tar - inodetest2
[ 270.132545] TEST-13-NSPAWN.sh[5440]: Enqueued transfer job 7. Press C-c to continue download in background.
[ 270.137660] TEST-13-NSPAWN.sh[5440]: Exporting '/home/testuser/.local/state/machines/inodetest', saving to 'pipe:[79515]' with compression 'uncompressed'.
[ 270.148434] TEST-13-NSPAWN.sh[5441]: Enqueued transfer job 8. Press C-c to continue download in background.
[ 270.173410] TEST-13-NSPAWN.sh[5441]: Importing 'pipe:[79515]', saving as 'inodetest2'.
[ 270.178790] TEST-13-NSPAWN.sh[5441]: Operating on image directory '/home/testuser/.local/state/machines'.
[ 270.386155] TEST-13-NSPAWN.sh[5440]: Operation completed successfully.
[ 270.389171] TEST-13-NSPAWN.sh[5440]: Exiting.
[ 270.689994] TEST-13-NSPAWN.sh[5441]: Failed to unpack regular file 'testfile': Seek error
Dustin L. Howett [Wed, 24 Jun 2026 18:51:42 +0000 (13:51 -0500)]
Merge pull request #3180 from dag-erling/des/3.8.8-fixes
Miscellaneous fixes for 3.8.8
* configure.ac: Remove unused checks
* libarchive: Fix `TIME_MAX` and `TIME_MIN`
* test: Fix off-by-one in bounds check Fixes: 0e4fa9ff0d82 ("test: promote the win32-repairing systemf wrapper to all systemf calls")
* bsdunzip_test: Set umask before asserting permissions Fixes: 34b3da0013ae ("unzip: Add symlink tests")
* archive_write_disk_posix: Fix type issues
Fix type issues in the HFS+ (de)compression code, primarily to avoid
arithmetic overflow when calculating the block count during compression.
* archive_write_disk_posix: Miscellaneous cleanup
Use `S_IS*()` macros consistently and clean up some `#ifdef`s.
* archive_write_disk_posix: Symlinks can have AppleDouble data
* libarchive: Fix format string issues
Dustin L. Howett [Tue, 23 Jun 2026 22:56:01 +0000 (17:56 -0500)]
iso9660: do not overflow zisofs block pointer count when a file is ~4GiB
(applies to 32-bit builds of libarchive)
Files within one ZF_BLOCK_SIZE of 4 GiB (which is, incidentally, the max
zisofs-compressible file size) would trigger an overflow in the
calculation of the number of block _pointers_ they would require. We
could have rejected those files, but the truth is that they just require
exactly 131073 block pointers (131072 for the file itself and one for
the trailer.)
Dustin L. Howett [Wed, 24 Jun 2026 14:30:41 +0000 (09:30 -0500)]
iso9660: add a test for the 32-bit zisofs overflow case
Writing a file near 4 GiB causes an overflow when we calculate the
number of block pointers we need to store, which leads to us allocating
the wrong amount of memory to store them.
This is visible with ASan:
Exercising: libarchive 3.9.0dev zlib/1.3.1 liblzma/5.4.4 bz2lib/1.0.8 libzstd/1.5.6 cng/2.0 libb2/bundled
706: test_write_format_iso9660_zisofs_overflow
=================================================================
==40444==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x08c004b4 at pc 0x006acb3b bp 0x002edb44 sp 0x002edb38
WRITE of size 1 at 0x08c004b4 thread T0
#0 0x006acb3a in archive_le32enc libarchive\archive_endian.h:219
#1 0x006c81d0 in zisofs_write_to_temp libarchive\archive_write_set_format_iso9660.c:7760
#2 0x006ca1bd in write_iso9660_data libarchive\archive_write_set_format_iso9660.c:1785
- Use contrib/untar's system_mkdir for extended portability
- Compile warning function only if it's actually used
- Use %H:%M instead of %R in strftime for extended portability
- Introduce system_unlink to add special directory symlink handling
Copy missing functionality from libarchive and cpio.
Kaif Khan [Tue, 23 Jun 2026 17:46:44 +0000 (23:16 +0530)]
xar: add regression test for odd-length base64 name decoding
Crafted TOC with a base64-encoded <name> of odd length, which used to
make strappend_base64() read past the character-data buffer. The trailing
incomplete base64 character is dropped; the rest still decodes.
Dustin L. Howett [Wed, 24 Jun 2026 04:33:12 +0000 (23:33 -0500)]
Merge pull request #3162 from soda0289/add-windows-long-path-manifest
tar: mark bsdtar as long-path aware on Windows
tar -C/--directory option calls SetCurrentDirectoryW(), which is limited to MAX_PATH (260) characters unless the process opts in to longpath support via an application manifest and enables a registry setting or sets an option in developer settings.