Skip to main content

Fidelity

Enum Fidelity 

Source
#[non_exhaustive]
pub enum Fidelity {
Show 15 variants 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, }, HeadersDisagree { format: FormatId, entry: String, fields: Vec<&'static str>, }, HeadersDisagreeUnlisted { format: FormatId, entries: u64, }, TrailingDataIgnored { format: FormatId, bytes: u64, }, LocalHeadersUnchecked { format: FormatId, entries: u64, },
}
Expand description

One specific, structured thing that was lost or approximated.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

TrailingIndexUnread

Fields

§format: FormatId
§

SizeFromDataDescriptor

Fields

§entry: String
§

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

§format: FormatId
§declared: u64

What the archive’s own index says it holds.

§enumerated: u64

What the reader was actually able to enumerate.

§reason: String

Why the two differ, in terms the caller can act on.

§

MetadataIncomplete

Fields

§entry: String
§fields: MetaFields
§

SolidBlockFullyDecoded

Fields

§wasted_bytes: u64
§

EncryptedEntrySkipped

Fields

§entry: String
§

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.

Fields

§entry: String
§reason: String
§

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

§entry: String
§declared: u64

The length written into the entry header, from the walk’s stat.

§fixup: String

What 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

Fields

§at: u64
§

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.

Fields

§format: FormatId
§offset: u64
§computed: u16
§recorded: u16
§

HeadersDisagree

A zip entry’s local file header and its central-directory record disagree on a field both carry — the “cloaking” shape (GHSA-m665-v7pm- 7grj), where one archive shows different names or contents depending on which of its two descriptions a reader trusts.

A warning, not crate::Error::Corrupt: the bytes handed back are still a coherent reading (the central directory’s on a seekable source, the local headers’ on a pipe), and the archive is not self-contradictory within either description. What cannot be claimed is that the reading is the only one, so --strict-fidelity turns this into exit 4.

fields lists, in a fixed order and never empty, every field the two records disagree on for this one entry — one warning per entry, not per field (it was per field up to 0.22.0, as field). Each is one of "order", "name", "compression method", "CRC-32", "compressed size", "uncompressed size", "encryption flag", "data-descriptor flag", "UTF-8 flag" or "entry count". entry is the name as the authoritative description (the central directory, when it was read) spells it, decoded as the reader decodes names.

An archive lists at most 64 entries this way; the rest are counted in one Fidelity::HeadersDisagreeUnlisted.

Fields

§format: FormatId
§entry: String
§fields: Vec<&'static str>
§

HeadersDisagreeUnlisted

More entries whose local header and central record disagree, past the 64 an archive lists as Fidelity::HeadersDisagree: entries counts them. Each listed warning copies its entry’s name, so an archive of a hundred thousand cloaked records would otherwise make a report as large as its index; the count keeps the verdict (--strict-fidelity exits 4 on either) without the copies.

Fields

§format: FormatId
§entries: u64
§

TrailingDataIgnored

A codec stream whose last complete, verified member (or stream) is followed by bytes that are neither another member nor padding, and were ignored.

gzip and bzip2 files are legitimately concatenations, and the tools that write them sometimes pad the end with NUL or 'X' bytes, which stay silent. Anything else after a verified member is ambiguous: it may be harmless junk, or it may be the next member with its first magic byte flipped — one byte that drops every later member while the members before it still verify. The data handed back is the members that did verify, so this is a warning rather than crate::Error::Corrupt (the reference tools likewise say “trailing garbage ignored” and recover the data), and --strict-fidelity turns it into exit 4. A tail that starts like a damaged member header — the magic intact and a field behind it impossible — is Corrupt instead, and never reaches this variant.

bytes is how many bytes were ignored, counted while the tail was read through (never buffered).

Fields

§format: FormatId
§bytes: u64
§

LocalHeadersUnchecked

The local headers of entries entries were not compared with their central-directory records (Fidelity::HeadersDisagree could not be ruled out for them), because the comparison ran out of its work budget.

Each comparison reads a local header — up to 128 KiB of name and extra field — and an index whose records keep pointing at the same few fat headers (or at headers overlapping one another) makes every record pay that again. The reads are bounded by a budget proportional to the archive’s own length, generous enough that a well-formed archive, which reads each local header once, never reaches it. Past it, the remaining entries are delivered as the central directory describes them, unchecked, and this says so; --strict-fidelity turns it into exit 4.

Fields

§format: FormatId
§entries: u64

Trait Implementations§

Source§

impl Clone for Fidelity

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Fidelity

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Fidelity

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Fidelity

Source§

impl Error for Fidelity

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for Fidelity

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Fidelity

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.