Skip to content

Support streaming TAR hard-link extraction and opt-in preservation - #493

Open
wilx wants to merge 8 commits into
codehaus-plexus:masterfrom
wilx:hardlinks-v2
Open

wilx wants to merge 8 commits into
codehaus-plexus:masterfrom
wilx:hardlinks-v2

Conversation

@wilx

@wilx wilx commented Sep 13, 2026 •

Copy link
Copy Markdown

What does this change?

Adds streaming TAR hard-link extraction, opt-in preservation, and logical content access through archived file sets.

  • Extraction: ordinary extraction uses one forward stream, without a preliminary scan or payload staging. Links must reference earlier regular members or backward-link chains and use the target's current mapped destination, following GNU tar and bsdtar. Invalid links fail without a copy fallback.
  • Creation: TarArchiver.setPreserveHardLinks(true) preserves resources with equal identities and compatible output metadata. The default is false; transformed contents, unknown identities, and conflicting metadata produce full entries. Resource subclasses must explicitly guarantee their content identity.
  • Resource access: aliases expose their referenced contents, supporting alias-only selection, TAR repacking, and ZIP conversion. Earlier payload reads may replay decompression and cache requested contents.

Related issue

Addresses PR #286 using explicit resource identities, mapped destination handling, and logical resource reads, while retaining the protected AbstractUnArchiver.extractFile signature.

Depends on Plexus IO PR #191. Local builds require installing its 3.7.1-SNAPSHOT first, then building Archiver with JDK 17+. The dependency must be available to CI and its version finalized before merging. These changes are released in Plexus IO 3.8.0, which this PR now uses. Build Archiver with JDK 17+.

Anything reviewers should look at closely?

  • Contained directory-symlink traversal is allowed by default, as in GNU tar. TarUnArchiver.setFailOnSymlinkTraversal(true) rejects intermediate symlinks in destinations and hard-link targets. Both settings enforce destination containment; failures can leave earlier outputs in place.
  • Directly managed TAR readers and resource collections require closure. Archivers close registered collections and their payload caches on success or failure. Concurrent reads on one reader are unsupported.

Documentation covers detailed semantics, GNU tar/bsdtar differences, replay/cache tradeoffs, and Maven Assembly configuration.

Validation

  • JDK 17 build, Javadoc, and formatting: 651 tests, zero failures/errors, four skips, including 147 hard-link/streaming/policy invocations across six compression modes.
  • Compatibility fixtures checked with GNU tar 1.35 and bsdtar 3.7.2.
  • Maven Assembly 3.8.0 produces a data member and backward hard link; both utilities verify contents and a shared inode.

Validation is Linux-only; Windows and macOS remain unvalidated.

@wilx wilx changed the title Support TAR hard-link extraction and opt-in preservation Support streaming TAR hard-link extraction and opt-in preservation Sep 13, 2026
@wilx
wilx force-pushed the hardlinks-v2 branch 2 times, most recently from edcfad4 to 4b2cc87 Compare September 14, 2026 17:29
@wilx
wilx marked this pull request as ready for review September 14, 2026 17:30
@wilx

wilx commented Sep 26, 2026

Copy link
Copy Markdown
Author

Rebased.

@wilx
wilx marked this pull request as draft September 26, 2026 11:12
Resolve existing path components before checking containment, including missing destinations and symlink/.. roots. Share the resolver between ordinary extraction and TAR hard links, reject final symlinks for ordinary entries, and avoid changing symlink target metadata.

Add shared, TAR, and ZIP regressions while preserving traversal policy and extraction hooks.
Extract 512 physical links and check their shared inode and timestamp. Exercise a separate 2000-link logical chain through TarFile content resolution without requiring thousands of filesystem links.
Reuse up to 1024 physical directory spellings after fresh type and file-identity checks, and clear the cache after each extraction. Resolve relative entry components from the already resolved root to avoid repeating its path walk.

Keep symlinks, missing paths, and providers without file identities on fresh resolution. Cover directory replacement, newly created symlinks, and extractor reuse after failure.
Use the relative-path shortcut only for paths without a root. Resolve other forms against the extraction root through Path.resolve before checking containment.

Cover rooted backslash, rooted forward-slash, and drive-relative mappings through shared extraction, TAR, and ZIP.
@wilx
wilx marked this pull request as ready for review September 26, 2026 13:49
@wilx
wilx marked this pull request as draft September 26, 2026 13:53
@wilx
wilx marked this pull request as ready for review September 26, 2026 14:16

This branch has not been deployed

No deployments
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