A 7-dimension adversarial review of the engine, tool, and routing found
nine real defects (host tests + the in-VM drill missed them). Fixed:
- geometryOf now rejects a crafted VBR whose cluster shift exceeds the
exFAT ceiling (bytes+sectors shift > 25) or whose cluster_count exceeds
the spec max (0xFFFFFFF5) — either would overflow the engine's u32
cluster-byte / cluster-bounds arithmetic and panic under ReleaseSafe on
untrusted removable media. validCluster/allocateCluster widened to u64,
and writeFile's clusters_needed widened, for a >4 GiB file near the u32
offset boundary.
- writeFile no longer claims valid_data_length = size unconditionally: a
sparse write past a foreign file's old valid boundary now zero-fills the
skipped gap on disk, so a read there returns zero, not stale bytes.
- ensureDirCapacity rewrites a grown subdirectory's own DataLength, so a
spec-compliant reader that bounds a directory by DataLength sees the new
entries (danos itself bounds by the end marker, but chkdsk / other OSes
do not).
- make-exfat-image lays the allocation bitmap across as many clusters as
it needs; a >128 MiB image (whose bitmap exceeds one cluster) was
self-inconsistent. Verified: the engine mounts+reads both the 48 MiB
fixture and a 256 MiB image.
Documented (not fixed here — a shared vfs-layer limit, like the u32
offset cap): non-ASCII names fold to '?', the same as the FAT engine.
New host tests pin each fix (crafted-VBR rejection, sparse-gap zero,
subdir-grows-and-records-size). Full suite 131/131, bounds green.
The pure, host-testable byte layer of the second engine: the Main Boot
Sector (VBR) and the six 32-byte directory-entry types — Allocation
Bitmap, Up-case Table, Volume Label, File, Stream Extension, File Name —
as align(1) extern structs, plus the three exFAT checksums (boot region,
up-case table, directory-entry set), the name hash, and the packed
timestamp <-> Unix-epoch conversion.
geometryOf accepts only "EXFAT " + 0xAA55 + an all-zero MustBeZero
region; that last guard is the mutual exclusion with FAT — a FAT prober
reads a zero bytes-per-sector there and rejects the volume, and this one
rejects a FAT boot sector for want of the exFAT name. Wire-format widths
are named consts (spec facts, no bare literals) so the bounds gate stays
green; the layout is pinned by @offsetOf/@sizeOf tests.
Wired into the host-test aggregate directly for now; it moves into the
exfat package's own test step when that lands (step 4). 7/7 host tests,
bounds green.