pub struct Candidate {
pub offset: u64,
pub meta: EntryMeta,
pub declared_len: Option<u64>,
pub verifier: Option<Verifier>,
pub available_len: Option<u64>,
}Expand description
A record a scanner believes it found, before anything is decoded.
Fields§
§offset: u64Byte offset of the record’s header in the archive.
meta: EntryMeta§declared_len: Option<u64>Declared payload length. None when the header does not carry one.
verifier: Option<Verifier>The checksum the ORIGINAL writer computed, when the format has one.
None is what produces the intact/complete split honestly, rather
than by a per-format convention someone has to remember.
available_len: Option<u64>How many of declared_len’s bytes the SOURCE actually holds, when
it holds fewer — the truncated-tail case. None means the declared
payload is entirely present (the ordinary case) or nothing was
declared at all; Some(n) always means n < declared_len.
§Why a scanner reports this instead of dropping the candidate
A truncated archive — an interrupted download — is the single most
common damaged zip there is, and it was the one shape salvage said
nothing at all about. zip_salvage.rs’s validation gate refused any
candidate whose declared payload ran past the end of the file, which
is a correct refusal to INVENT the missing bytes (zip -FF
fabricates them and reports success) implemented as SILENCE: no row,
no note, no non-zero exit. Swept across six truncation points inside
a three-header archive’s last entry, every one reported “2 scanned”
at exit 0 — the third header was not even counted.
Reporting the candidate with this field set is what turns the
refusal into a statement. Nothing is invented: the declared length
stays exactly what the header said, so a reader can see both figures,
and the bytes that ARE present are still a genuine prefix. What a
scanner must NOT do is fold the shortfall into declared_len — that
would make a truncated entry indistinguishable from a whole one of
the smaller size, which is the same mistake in a different place.