#[non_exhaustive]pub enum Fidelity {
TrailingIndexUnread {
format: FormatId,
},
SizeFromDataDescriptor {
entry: String,
},
EntryCountUnknown,
EntryCountMismatch {
format: FormatId,
declared: u64,
enumerated: u64,
reason: String,
},
MetadataIncomplete {
entry: String,
fields: MetaFields,
},
SolidBlockFullyDecoded {
wasted_bytes: u64,
},
EncryptedEntrySkipped {
entry: String,
},
EntrySkipped {
entry: String,
reason: String,
},
EntrySizeChanged {
entry: String,
declared: u64,
fixup: String,
},
TruncatedStream {
at: u64,
},
DirectoryRecordChecksum {
format: FormatId,
offset: u64,
computed: u16,
recorded: u16,
},
}Expand description
One specific, structured thing that was lost or approximated.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
TrailingIndexUnread
SizeFromDataDescriptor
EntryCountUnknown
EntryCountMismatch
The archive’s own index declares a different number of records than the reader enumerated. Usually FEWER were enumerated, so entries exist in the file that no caller can reach; zip can also enumerate MORE, when its end-of-central-directory record’s two counts contradict each other (the v0.7.0 deep-fuzz finding), so the message names both figures without saying which way round they are.
Distinct from Self::EntryCountUnknown, which is the forward reader
admitting it never saw a count at all. Here the count WAS read, from
the format’s authoritative structure, and it disagrees with what came
back — the strongest evidence available that a read is incomplete, and
the one a seekable Rung::Exact read would otherwise have no way to
express. Without it a partial enumeration is indistinguishable from a
complete one, which is the failure this variant exists to prevent:
listing six of eight records and calling it exact fidelity.
Raised, not recovered. Reaching the shadowed records would mean
re-parsing the index by hand; naming the shortfall is what the caller
needs in order to know not to trust the result, and
--strict-fidelity turns it into exit 4.
reason is an owned String for the same reason
Self::EntrySkipped’s is: the cause is specific to the container
and the reader, and a shortfall that cannot say WHY is one the user
cannot act on.
Fields
MetadataIncomplete
SolidBlockFullyDecoded
EncryptedEntrySkipped
EntrySkipped
An entry this build cannot materialise, named along with why.
Distinct from Self::MetadataIncomplete, which is about an entry
that WAS written and lost some of its metadata: here the entry itself
is absent from the result. Extraction raises it for a device node,
fifo or socket — crate::EntryKind::Other, the honest answer a
container gives for an entry shape EntryKind has no variant for yet
— and for a crate::EntryKind::Hardlink whose target it did not
write, or whose target is a directory. Writing one out as a regular
file carrying its “contents” would be a silent lie about what the
archive held. The write side
raises it too, for something met on disk that no container here can
store — a socket, an undecodable name, a directory being packed into
ar.
reason is an owned String rather than a &'static str because the
write side’s reasons carry runtime detail — the failing errno, the
container’s own name, the undecodable bytes — and a reason that cannot
name the particular thing that went wrong is a reason the user cannot
act on.
EntrySizeChanged
A file that changed length between the moment its size was recorded and the moment its bytes were read, stored at the length its header already declares.
Distinct from Self::EntrySkipped: the entry IS in the archive, and
the archive is structurally valid. What was lost is the tail of a file
that grew, or the tail of a file that shrank — replaced by zeros,
because the entry header was written before the payload was read and a
container cannot un-write it. Refusing instead would throw away the
whole archive over one file that a live system happened to touch,
which is what pack ~ -o backup.tar over a running home directory does
routinely; GNU tar prints file changed as we read it and continues,
and this is the same bargain, with the loss named rather than printed
and forgotten.
--strict-fidelity still refuses on it, which is the half of the
bargain that keeps it honest.
Fields
fixup: StringWhat the file actually supplied and what was done about it.
Prose rather than a second u64 because the two directions know
different things: a file that shrank supplies an exact count, while
a file that grew is only known to have had more — measuring how
much more would mean reading a tail that is deliberately not being
stored. A field that could name the figure in one case and not the
other would have to lie in one of them.
TruncatedStream
DirectoryRecordChecksum
A directory record carries a checksum over ITSELF, and it does not match the bytes the record is made of.
Distinct from every other integrity signal in this enum: those are
about an entry’s CONTENT, and a content checksum that fails is
crate::Error::Corrupt, not a warning, because there is nothing
honest to hand back. This is about the METADATA record, and the
verdict is deliberately softer for one measured reason — the format
that carries such a field may itself treat it as advisory. ZOO is the
first: zoo 2.10’s own lister prints a * beside an entry whose
dir_crc fails and carries on listing it, so refusing would be
stricter than the reference implementation, which is how a guard comes
to fire on input a real tool accepts.
What it must NOT do is stay silent. A record whose own checksum fails
has been altered since it was written, and every field a caller is
about to trust — the entry’s name, size, offset, and the link to the
next record — comes out of it. --strict-fidelity turns this into
exit 4, which is the whole point: a verb that says “exact fidelity”
over an altered record is making a claim the archive itself disputes.
offset is the record’s own position in the file, because a record
that fails its checksum may have no usable name to identify it by —
the reproducer that motivated this variant is a record whose name
field is intact and whose link field is not.
Trait Implementations§
impl Eq for Fidelity
Source§impl Error for Fidelity
impl Error for Fidelity
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()