Skip to content

feat(core)!: report ZIP entries whose xl extra field gives another file type than the central attributes - #689

Merged
bug-ops merged 2 commits into
mainfrom
fix/686-zip-local-xl-symlink
Oct 21, 2026
Merged

bug-ops merged 2 commits into
mainfrom
fix/686-zip-local-xl-symlink

Conversation

@bug-ops

@bug-ops bug-ops commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Summary

libarchive honours the `xl` (0x6c78) extra field of a local header, and of a central record when it reads from a seekable file. Such a field can turn an entry that the central directory lists as a regular file into a symlink or a directory, so `verify` passed archives that `bsdtar` extracts differently.

`verify`, `list` and `extract` now reject these archives under `Enforce` with `ZipInconsistency::XlTypeDivergence` (category `HiddenEntry`):

  • the type is derived with the reader's precedence (local `xl` over central `xl`, central `xl` over the central attributes) and its final-name rules (Unicode Path with a matching CRC, DOS backslash, DOS read-only mask)
  • the check runs as its own pass, independent of the other finding limits, and reads each distinct local header, including its name, once
  • a central `xl` is compared as well, because the seekable reader applies it; a pipe reader ignores it
  • entries without any `xl` type are not flagged, so ordinary Info-ZIP and bsdtar symlink archives still pass

Live checks with bsdtar 3.5.3 on a file and on a real pipe: a local `xl` symlink is applied by both readers, a central `xl` link or directory only by the file reader. All three are rejected. The 21-archive ZIP corpus and real symlink archives still pass. Measured cost on a 10000-entry archive: list +1.6%, verify +2.8%.

`skills/exarch-cli/SKILL.md` and spec 017 are updated.

Closes #686

…le type than the central attributes

A local or central xl (0x6c78) extra field overrides the entry type for
libarchive readers, so an entry listed as a regular file could be written
as a symlink or directory by a reader that honours the field. verify, list
and extract now reject such archives under Enforce with
ZipInconsistency::XlTypeDivergence, derived with the reader's own
precedence (local over central) and final-name rules.

BREAKING CHANGE: ZIP archives carrying an xl extra whose type differs from
the central attributes are rejected under Enforce.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Changes to exarch-core docs Documentation tests Test changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zip: local xl extra marks an entry as a symlink while the central directory says file

1 participant