8131 Commits
Author SHA1 Message Date
datauwu ca8044d3c4 warc: modernize writer comments
Rewrite WARC writer comments to use clearer wording and consistent
terminology.

Keep the change comment-only while preserving existing behavior.
2026-07-11 16:47:24 +08:00
datauwu eb6fc941b8 warc: modernize reader comments
Rewrite WARC reader comments to use clearer wording and match the
style used by other libarchive format readers.

Keep the change comment-only while preserving existing behavior.
2026-07-11 16:47:23 +08:00
datauwu 23b54da0ba cpio: fix read-ahead pointer lifetime issue
Cache the CPIO trailer-name check before consuming the pathname
buffer.

The reader kept a pointer returned by __archive_read_ahead() and used
it after __archive_read_consume(), and after possible symlink body
processing. Read-ahead pointers are views into libarchive input buffers
and should not be relied on after the associated bytes are consumed.

Store the TRAILER!!! decision while the pathname buffer is still valid,
then use the saved boolean after the remaining header handling.
2026-07-11 12:11:53 +08:00
Tim Kientzle 2139626099 Merge pull request #3276 from DHowett/dh/fix-archive-literals
tidy: prefer ARCHIVE_OK over 0 when appropriate
2026-07-10 20:40:54 -07:00
Dustin L. Howett bf4c5688d8 write: prefer ARCHIVE_OK over literal in set_bytes_per_block 2026-07-10 20:26:37 -05:00
Dustin L. Howett abfcfabbe7 iso9660: prefer ARCHIVE_OK over literal in gen*identifier 2026-07-10 20:26:31 -05:00
Dustin L. Howett a94475b11a shar: prefer ARCHIVE_OK over literal in finish_entry 2026-07-10 20:26:25 -05:00
Dustin L. Howett 8149e6bd92 xz: prefer ARCHIVE_OK over literal in filter_open 2026-07-10 20:26:17 -05:00
Dustin L. Howett 3e8e0cb32d uuencode: prefer ARCHIVE_OK over literal in filter_open 2026-07-10 20:26:08 -05:00
Dustin L. Howett 56bed7f2bd compress: prefer ARCHIVE_OK over literal in filter_open 2026-07-10 20:25:58 -05:00
Dustin L. Howett 65ddb3d0f4 b64: prefer ARCHIVE_OK over literal in filter_open 2026-07-10 20:25:34 -05:00
Dustin L. Howett 98d1ceeca6 Merge pull request #3274 from datauwu/warc-fix-oob-read
warc: parse Content-Length as a bounded field
2026-07-10 16:39:15 -05:00
datauwu 9fcb4048fa warc: parse Content-Length as a bounded field
Parse Content-Length only up to the located end-of-line instead of
passing a bounded header field to strtol(). Use int64_t for the parsed
entry size, ASCII digit checks, and checked arithmetic while accumulating
the value.
2026-07-11 02:08:05 +08:00
Tim Kientzle 2ff2b423e7 Merge pull request #3275 from datauwu/fix-several-left-shift-ub
libarchive: fix left-shift UB in several places
2026-07-10 10:29:24 -07:00
datauwu 2854735c80 tests: fix signed left-shift UB in fuzz consumer
Fix i64 construction by using a uint64_t accumulator.
2026-07-10 21:35:35 +08:00
datauwu 27c56a53d5 pax: fix signed-char left-shift UB in base64 encoder
Fix base64 shifts by casting input bytes to unsigned.
2026-07-10 21:35:35 +08:00
datauwu 342d2728d3 rar: fix signed left-shift UB in audio filter
Fix signed audio delta scaling by using multiplication.
2026-07-10 21:35:35 +08:00
datauwu 801b9707c3 7zip: fix negative shift count in x86 BCJ filter
Fix the previous-position shift count before updating the mask.
2026-07-10 21:35:35 +08:00
Dustin L. Howett 8d62a0512a Merge pull request #3257 from R4mbb/fix-pax-all-slash-pathname
pax: handle all-slash pathnames in USTAR name splitting
2026-07-09 10:53:22 -05:00
Daan De Meyer ce008c72af test_sparse_basic: avoid out-of-bounds pointer arithmetic in verify
When a sparse map entry began before the current data block
(expected_offset < offset), verify_sparse_file() formed the intermediate
pointer "buff + (expected_offset - offset)" before adding the entry
size.  That intermediate points before buff, which is undefined behavior;
with file4's large hole it trapped the test under UBSan
(-fsanitize=pointer-overflow).  Fold the size into the displacement so the
whole byte offset is computed as one integer and added to buff in a
single, in-bounds step.
2026-07-09 17:17:29 +02:00
Dustin L. Howett cb2c1207f0 Merge pull request #3256 from stoeckmann/cab_integers
cab: Refactor data types + extend huffman tables to 16 bit if needed
2026-07-09 10:03:45 -05:00
Tobias Stoeckmann d3d8481e7f cab: Grow pre-tree Huffman table if needed
The standard has no fixed 10 bit limit. Instead, a pre-tree could
contain up to 16 bit codes, although this is very unlikely.

Grow the table if needed.

While at it, clarify now that max_bits are actually lookup_bits.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
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 a791094bdf cab: Clarify LZX/Huffman bit handling
- Huffman operations are up to 16 bit, thus uint16_t
- LZX itself can handle up to 32 bit, thus uint32_t
- Memory sizes are size_t

Otherwise:

- Use uint8_t to show where bit lengths are stored
- Use int to clarify that a status is stored

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann e155b516a0 cab: Remove check in lzx_make_huffman_table
The check against table size is redundant since Kraft's inequality
already verified that this operation cannot exceed table size anymore.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann 8d22629c9e cab: Use correct limit in lzx_make_huffman_table
The table size is in bytes, but bitlen must be checked against maximum
bit length allowed.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann dcf31bea79 cab: Clarify lzx_decode_huffman signature
No more than 16 bits shall ever be supplied for a table lookup.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann 8beccd23e2 cab: Adjust lzx_read_bitlen API
Use 0 as marker for maximum symbol count to be able to eventually switch
to another data type.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann 4fa9fc1f37 cab: Clear lookup table in lzx_huffman_init
This step is not actually needed, but will prevent static analysis
warnings that values might exist which have never been initialized.

"Invalid" values only exist outside of the addressable area, which can
happen if maximum code bit length is smaller than table bit length.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann 5bcaf207c1 cab: Clarify what "len_size" is
It's actually the amount of symbols/codes in Huffman tree. Clarify it by
using the field name symbol_count instead.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann 4d8e56fd19 cab: Use ARCHIVE_* values with lzx functions
Some lzx functions reverse the generic logic of 0 being success and
anything else being an error. It's debatable from a boolean point of
view but use the regular ARCHIVE_OK in case of success, which is 0.

Unifies with other lzx functions and general idea of libarchive
functions.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann 898b63c19b cab: Fix Kraft's inequality check
We really have to check if Kraft's inequality is 1 (in our case it's
0x10000) or 0 for an empty tree. Anything else is an error.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann eed685b4d6 cab: Simplify lzx_decode_huffman
As long as the given index is in range of the table, the previous
creation of the lookup table takes care that all elements are valid.

This is a left over of actual tree removal done in commit
c253f0aae9.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-09 08:37:34 +02:00
Tobias Stoeckmann 06765dbea5 cab: Remove inline keyword
Most if not all compilers today understand inline, but it's also just a
hint. Static functions will be inlined if it's worth it from compiler
perspective and inline functions will be still functions, too.

Remove it and let compilers decide. Increases portability for very old
compilers which cannot handle it.

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
Dustin L. Howett 1e48c53e9e Merge pull request #3266 from datauwu/pax-fix-oob-read
pax: fix 1-byte OOB read in sparse name building
2026-07-08 22:26:06 -05:00
Dustin L. Howett cfb3eb5497 Merge pull request #3267 from datauwu/iso9660-fix-oob
iso9660: fix 1-byte OOB read in iso-level option
2026-07-08 22:20:50 -05:00
Dustin L. Howett 1d7b49b8d9 Merge pull request #3268 from uchiha-bug-hunter/best-effort-strncat-overread
archive_string: bound best_effort_strncat_in_locale to length
2026-07-08 22:19:43 -05:00
Kaif Khan 9b5dae145f archive_string: bound best_effort_strncat_in_locale to length
remaining was set to length but never decremented, so the loop only stopped at a NUL and read past fields passed without a trailing NUL (a read_ahead window sized by mbsnbytes). Decrement per byte and check the count before dereferencing *itp.
2026-07-08 22:10:27 +05:30
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
datauwu 0046f16644 iso9660: fix 1-byte OOB read in iso-level option
iso9660_options() checks the second byte of the iso-level option value
before checking that the first byte contains a valid ISO level.

For an empty option value such as iso9660:iso-level=,
archive_write_set_options() passes a value pointer to the terminating NUL
byte of the duplicated options string. Reading value[1] then reads one byte
past that heap allocation.

Check value[0] before reading value[1]. This keeps the same accepted values
while rejecting the empty value without reading past the option buffer.
2026-07-08 20:24:33 +08:00
datauwu 51287cecd6 pax: fix 1-byte OOB read in sparse name building
The GNU sparse name builder trims trailing slash and /. components before
building the synthetic ustar entry name. If the sparse pathname is fully
pruned, the effective source length becomes zero and build_ustar_entry_name()
reads one byte before the pathname buffer.

Handle the all-pruned pathname case before calling the ustar name builder.
The synthetic name then preserves the root-directory case.
2026-07-08 18:10:27 +08:00
Kaif Khan e5d72383a6 7zip: bound NumFolders before allocating folders array 2026-07-08 01:13:52 +05:30
Dustin L. Howett 40a71c8382 Merge pull request #3265 from stoeckmann/ckd_alloc
Check size arithmetic before memory allocations
2026-07-07 13:49:14 -05:00
Dustin L. Howett 6752ed2c27 Merge pull request #3214 from uchiha-bug-hunter/tar-sun-holesdata-overread
tar: add regression test for SUN.holesdata sparse map ending on a digit
2026-07-07 13:45:47 -05:00
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
Tobias Stoeckmann 761652401f Merge pull request #3220 from DHowett/fix-assertions-lstat
test: make Windows file assertions act like lstat
2026-07-07 19:28:21 +02:00
Tobias Stoeckmann 1bcc833a5d Check size arithmetic before memory allocations
Make sure that multiplications do not overflow (or if they overflow,
handle them properly).

This also means that proper data type size_t instead of int is used.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-07-07 17:57:33 +02:00
Dustin L. Howett 8324372849 Merge pull request #3249 from datauwu/warc-fix-pending-data
warc: fix pending data when skipping entries
2026-07-07 10:47:10 -05:00
Dustin L. Howett 617d422c86 test: make Windows file assertions act like lstat
I've removed our lstat shim and replaced all uses with my_GetFileInformationByName.
2026-07-07 10:24:00 -05:00