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.
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.
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.
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.
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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
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.
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.
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.
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.
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.
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>