Skip to content

A few fuzzing and CI fixes, run fuzzing in CI#14

Merged
cgwalters merged 6 commits intomainfrom
fuzzing-and-ci
Mar 2, 2026
Merged

A few fuzzing and CI fixes, run fuzzing in CI#14
cgwalters merged 6 commits intomainfrom
fuzzing-and-ci

Conversation

@cgwalters
Copy link
Collaborator

No description provided.

Remove the duplicate parse_tar_core_archive function from the interop
example and use parse_tar_core_with_limits from tar-core-testutil
instead. The two callers (test_gnu_tar_to_tar_core and
smoke_test_gnu_tar_non_utf8_roundtrip) now compare against OwnedEntry
fields directly.

EntryParams is intentionally kept since it serves a different purpose:
generating test archives with build_tar_core_archive, where its field
types (u32 vs u64, is_dir vs entry_type, non-optional username) better
match the test generation API.

Assisted-by: OpenCode (Claude claude-opus-4-6)
Disable semver-checks until the crate is published to crates.io;
cargo-semver-checks needs a baseline version to compare against and
currently always fails.

Fix the MSRV job to read rust-version from Cargo.toml instead of
hardcoding "1.86.0". Also restrict the MSRV build to --lib only, since
dev-dependencies (like home@0.5.12) may legitimately require a newer
Rust version than the library's MSRV.

Assisted-by: OpenCode (Claude claude-opus-4-6)
Add a fuzz job to the main CI workflow that runs all cargo-fuzz targets
for 2 minutes each on every push/PR. Add a separate extended fuzzing
workflow that runs post-merge only with 15 minutes per target.

Add a `just fuzz-all` recipe (default 2 min per target) and include it
in `just ci`. Also fix `just fuzz-list` to use the correct nightly
toolchain.

Assisted-by: OpenCode (Claude claude-opus-4-6)
PAX `linkpath` and GNU long link extensions can set an empty value,
which surfaces as `link_target: Some([])` instead of `None`. An empty
link target is semantically equivalent to no link target, matching
the behavior of tar-rs which filters these with `.filter(|b| !b.is_empty())`.

The header path already had a guard (`if !header_link.is_empty()`) but
the PAX linkpath and GNU long link code paths did not. Rather than
adding guards at each source, normalize after all sources have been
applied, right before constructing the ParsedEntry.

Found by the differential fuzzer (crash-8689eb1a2a408c74f42ba6948f330effb32e2306).

Assisted-by: OpenCode (Claude claude-opus-4-6)
When using permissive limits (max_pax_size = u64::MAX), the size field
can be large enough that `padded_size` (after rounding up to block
alignment) overflows when added to HEADER_SIZE. Use checked_add in
both the global PAX handler and the extension handler to return
InvalidSize instead of panicking.

Found by the differential fuzzer (crash-6300171db6afdcdb33b78318640acec5760fec81).

Assisted-by: OpenCode (Claude claude-opus-4-6)
Same class of fix as the link_target normalization: PAX overrides
can set empty values that surface as Some([]) instead of None.
Apply the same normalization for consistency.

Assisted-by: OpenCode (Claude claude-opus-4-6)
@cgwalters cgwalters merged commit fea65bc into main Mar 2, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant