CAB reader: fix memory leak on repeated calls to archive_read_support_format_cab
`archive_read_support_format_cab` allocates a fresh context structure on
each call before registering the CAB format with libarchive. On the
second call, however, the registration step reports the format is
already registered, so the function frees the newly allocated context
structure — it is not needed, since the one from the first call is
already in use.
The context structure contains a `ws` field of type `archive_wstring`.
During initialization, `archive_wstring_ensure` is called on that field,
which performs its own heap allocation.
The cleanup path described above frees the context structure without
also releasing the memory owned by the `ws` field, causing a leak.
Fixed by calling `archive_wstring_free` on the `ws` field before freeing
the context structure.
If malloc() returns NULL (e.g., under memory pressure, container memory limits, or constrained embedded environments), the subsequent memcpy(NULL, ...) produces a SIGSEGV.
If run as root (as is the case in CI), switch to an unprivileged user
(default: nobody) before running each test, and switch back after.
This makes it possible to write tests that rely on file permissions.
Note that tests that use the UID or GID must now check the EUID / EGID
instead as they will be different while the test is running. The only
way to avoid that is to run each test case in a child process, which
would hugely increase the complexity of test_run().
When create_dir() fails to create a directory, it immediately checks to
see if the directory already exists, which can happen if it's been given
something like foo/../foo. Unfortunately, this clobbers errno, which
means that create_dir() always reports ENOENT, regardless of the actual
error. Fix this by only performing this extra check if errno is EEXIST,
then reset errno to either EEXIST or ENOTDIR depending on the outcome.
Tim Kientzle [Sun, 1 Mar 2026 21:45:50 +0000 (13:45 -0800)]
Reject LHA archives with ridiculously large headers
The header is a series of blocks, most of which contain
values of just a few bytes (sizes, times, etc). The only
exceptions are the filename and directory name attributes,
which will be limited by the MSDOS/Windows maximum file length
limit. So it seems unlikely that this will ever exceed 64k.
(If we find counter-examples, we can easily extend this limit.)
Tim Kientzle [Sun, 1 Mar 2026 20:17:05 +0000 (12:17 -0800)]
Prune FreeBSD CI from 10 variations down to 3
Previously, we tested many combinations of FreeBSD version, build system, and filesystem.
In practice, that's redundant, and we've started seeing these excessive requests get throttled by Cirrus.
Cutting back to just 3 combinations should suffice and reduce the risk of throttling.
Brad King [Fri, 27 Feb 2026 19:35:55 +0000 (14:35 -0500)]
7zip: Fix out-of-bounds access on ELF 64-bit header
The ELF specification's `Elf64_Ehdr` type is 64 bytes [1].
`find_elf_data_sec` accesses the last field, `e_shstrndx`.
Make sure we read enough data to populate it.
zhangjy1014 [Mon, 9 Feb 2026 03:20:18 +0000 (11:20 +0800)]
Add test for malformed "default" ACL prefix (issue #2744)
Verify that archive_entry_acl_from_text() and
archive_entry_acl_from_text_w() return ARCHIVE_WARN instead of
crashing when given a bare "d" or "default" string with no
subsequent tag field.
Without the accompanying fix in archive_acl.c this test triggers
a NULL-pointer dereference (SEGV) in archive_acl_from_text_w().
zhangjy1014 [Sun, 8 Feb 2026 09:18:43 +0000 (17:18 +0800)]
Fix NULL pointer dereference in archive_acl_from_text_w()
When parsing a short "default" ACL prefix (e.g. L"d") with no
subsequent tag field, field[n] is left as {NULL, NULL} and the
code dereferences it unconditionally in the switch statement,
causing a SEGV.
Add a zero-length check after computing the field length so that
malformed entries are skipped with ARCHIVE_WARN, matching the
documented contract. Also move the st pointer computation after
the guard to avoid dereferencing a NULL start pointer.
Brad King [Wed, 4 Feb 2026 21:35:03 +0000 (16:35 -0500)]
archive_write: Fix crash on failure to convert WCS/UTF-8 pathname to MBS
If an entry pathname is set only by WCS or UTF-8, it may not have any
MBS representation in the archive's hdrcharset. Do not crash or create
an archive with an empty pathname. Furthermore, the entry pathname may
not have any MBS representation in the current locale. Do not report a
`(null)` pathname in the error message.
Brad King [Wed, 4 Feb 2026 21:42:26 +0000 (16:42 -0500)]
archive_string_append_from_wcs: Fix silently lossy conversions on Windows
On Windows, since commit ae54394104 (Implement a string conversion
interface..., 2011-05-09, v3.0.0a~398), `archive_string_append_from_wcs`
no longer returns an error on use of replacement characters in non-C
locales. Restore the error to avoid silent use of replacement
characters, and for consistency across platforms.
Brad King [Wed, 4 Feb 2026 21:22:39 +0000 (16:22 -0500)]
archive_mstring_get_mbs_l: Restore error on failure to convert from WCS/UTF-8
Prior to commit c30f279475 (Complete support for UTF8 encoding
conversion, 2020-05-31, v3.5.0~32^2), `archive_mstring_get_mbs_l` returned
an error on failure to convert WCS to MBS. Restore the error so callers
can distinguish conversion failure from having no string in any form.
On Windows, `archive_mstring_get_mbs_l` from WCS with `sconv != NULL`
internally calls `archive_string_append_from_wcs_in_codepage` more than
once, with both `sconv != NULL` and `sconv == NULL`. Due to another bug
in the `sconv == NULL` case, we cannot enable all test combinations yet.
This happens because `--gc-sections` isn't supported on illumos `ld`.
This patch updates CMakeLists.txt to skip unsupported linker options on
illumos. The flags used on other operating systems are optimizations
that don't affect correctness, so this change is safe.
dependabot[bot] [Thu, 25 Dec 2025 08:53:17 +0000 (08:53 +0000)]
CI: Bump the all-actions group across 1 directory with 3 updates
Bumps the all-actions group with 3 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [actions/upload-artifact](https://github.com/actions/upload-artifact) and [github/codeql-action](https://github.com/github/codeql-action).
Updates `actions/checkout` from 5.0.0 to 5.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/08c6903cd8c0fde910a37f88322edcfb5dd907a8...93cb6efe18208431cddfb8368fd83d5badbf9bfd)
Leslie P. Polzer [Mon, 22 Dec 2025 04:53:06 +0000 (04:53 +0000)]
Refactor all fuzzers to use shared fuzz_helpers.h
Complete the refactoring of all 25 fuzzers:
- Remove duplicate Buffer struct definitions from 15 format fuzzers
- Remove duplicate DataConsumer class from 7 API fuzzers
- Update consume_bytes() calls to match new signature
- All fuzzers now use shared helpers from fuzz_helpers.h
The test runner already lists available tests if it fails to parse the
command line, but add a -l option to explicitly do this without also
printing an error message and a summary of options.
tree_reopen() and tree_dup() return NULL only of they
are unable to allocate memory. Otherwise libarchive enters
ARCHIVE_FATAL if trying to walk an enterable but unreadable
directory.
__archive_ensure_cloexec_flag() operates only on fd >= 0
so there is no need to skip it
Uses the sed-like way (and Java-like, and .Net-like, and Javascript-like…) to fix this issue of advancing the string to be processed by one if the match is zero-length.
Fixes libarchive/libarchive#2725 and solves libarchive/libarchive#2438.