Skip to main content

ZiPatchError

Enum ZiPatchError 

Source
#[non_exhaustive]
pub enum ZiPatchError {
Show 22 variants Io(Error), InvalidMagic, UnknownChunkTag([u8; 4]), UnknownSqpkCommand(u8), ChecksumMismatch { tag: [u8; 4], expected: u32, actual: u32, }, Decompress(Error), InvalidField { context: &'static str, }, OversizedChunk(usize), UnknownFileOperation(u8), Utf8Error(FromUtf8Error), BinrwError(Error), NegativeFileOffset(i64), TruncatedPatch, UnsupportedPlatform(u16), Cancelled, IndexSourceUnavailable { target_offset: u64, length: u32, }, PatchSourceTooShort { offset: u64, requested: usize, }, PatchIndexOutOfRange { patch: u32, count: usize, }, UnsafeTargetPath(String), SchemaVersionMismatch { kind: &'static str, found: u32, expected: u32, }, DuplicatePatch { name: String, }, Crc32Mismatch { target_offset: u64, expected: u32, actual: u32, },
}
Expand description

All failures returned by parsing or applying a ZiPatch stream.

Both the parsing layer (crate::chunk) and the apply layer (crate::apply) surface errors through this single enum, so callers need only one error type in their match arms.

§Mapping from standard errors

§Example

use zipatch_rs::ZiPatchError;

fn describe(e: &ZiPatchError) -> &'static str {
    match e {
        ZiPatchError::Io(_)               => "I/O error",
        ZiPatchError::InvalidMagic        => "not a ZiPatch file",
        ZiPatchError::UnknownChunkTag(_)  => "unrecognised chunk",
        ZiPatchError::ChecksumMismatch {..}=> "corrupt chunk",
        ZiPatchError::TruncatedPatch      => "download incomplete",
        _                                 => "other error",
    }
}

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.
§

Io(Error)

Underlying I/O failure from the patch source or target filesystem.

Raised by the parsing layer when reading from the patch stream fails (e.g. a network read error), and by the apply layer when any filesystem operation fails (open, seek, write, delete, create-dir).

The wrapped std::io::Error carries the OS-level error code and kind. Use std::io::Error::kind to distinguish NotFound, PermissionDenied, and similar conditions.

§

InvalidMagic

The 12-byte ZiPatch magic header was missing or did not match.

Raised by ZiPatchReader::new and ZiPatchReader::from_path when the first 12 bytes of the source do not equal the expected magic sequence \x91ZIPATCH\r\n\x1a\n. Typically indicates the caller opened the wrong file, or the file is corrupted at the very start.

§

UnknownChunkTag([u8; 4])

A 4-byte chunk tag was not recognised by the parser.

Raised by the chunk dispatcher in crate::chunk when a tag does not match any of FHDR, APLY, APFS, ADIR, DELD, SQPK, or EOF_. The raw tag bytes are preserved so callers can log them for diagnostic purposes.

This can occur with genuinely new chunk types introduced by Square Enix in future patches. Upgrading the library or filing an issue is the appropriate response.

§

UnknownSqpkCommand(u8)

A SQPK sub-command byte was not recognised by the parser.

Raised by the SQPK dispatcher in crate::chunk when the single-byte command code inside an SQPK chunk does not match any of the known values (A, D, E, F, H, I, T, X). The raw byte is preserved for diagnostics.

§

ChecksumMismatch

A chunk’s recorded CRC32 did not match the computed CRC32.

Raised by the chunk framing code in crate::chunk when CRC32 verification is enabled (the default) and the stored checksum in the patch stream does not match the checksum computed over tag ++ body.

This indicates a corrupt or partially-written patch file. Disable verification with ZiPatchReader::skip_checksum_verification if the source has already been verified out-of-band.

The tag, expected, and actual fields provide enough information to log a precise diagnostic message.

Fields

§tag: [u8; 4]

Tag of the chunk whose checksum failed.

§expected: u32

CRC32 stored in the patch file.

§actual: u32

CRC32 computed over the actual chunk bytes.

§

Decompress(Error)

DEFLATE decompression of a SqpkFile block failed.

Raised by the SqpkFile apply logic when flate2 cannot decompress a compressed block payload inside an AddFile operation. The wrapped std::io::Error is the decompressor’s error, not a filesystem error; it is stored as a #[source] rather than #[from] to keep it distinct from ZiPatchError::Io.

§

InvalidField

A field value failed a parser invariant (e.g. negative size).

Raised by chunk-specific parsers in crate::chunk when a field value is syntactically valid (i.e. could be parsed) but violates a semantic constraint required by the format — for example, a length field that is negative, or a size that overflows the expected range.

The context string names the specific field that failed its check, giving enough information to locate the offending position in the binary format documentation.

Fields

§context: &'static str

Human-readable description of which field was invalid and why.

§

OversizedChunk(usize)

A chunk declared a size larger than the parser’s maximum (512 MiB).

Raised by the chunk framing code in crate::chunk when the body_len field of a chunk frame exceeds 512 MiB. This guard prevents allocating an arbitrarily large buffer from a malformed or malicious patch stream. The preserved size value can be logged for diagnostics.

§

UnknownFileOperation(u8)

A SqpkFile operation byte was not recognised.

Raised by the SqpkFile parser when the single-byte operation field does not match any of A (AddFile), R (RemoveAll), D (DeleteFile), or M (MakeDirTree). The raw byte is preserved for diagnostics.

§

Utf8Error(FromUtf8Error)

A UTF-8 decode failed when reading a path or name field.

Raised by the parsing layer when a length-prefixed byte string (e.g. a directory name in an ADIR chunk or a file path in a SqpkFile chunk) is not valid UTF-8. FFXIV patch paths are documented as ASCII, so this error indicates either a corrupt patch file or an undocumented encoding extension.

§

BinrwError(Error)

A binrw parser produced an error; wraps the underlying cause.

Several chunk types (notably those using #[derive(BinRead)]) delegate their parsing to binrw. When binrw encounters an unexpected byte pattern or short read, it returns a binrw::Error which is wrapped here via #[from].

The inner error message usually identifies the field name and byte offset where parsing failed.

§

NegativeFileOffset(i64)

A SqpkFile carried a negative file_offset that cannot be applied.

Raised by the AddFile arm of the SqpkFile apply logic when cmd.file_offset is negative and therefore cannot be converted to a u64 seek position. The wire format stores this field as i64; a non-negative value is the invariant required for correct application.

The preserved i64 value can be logged to report the exact field content.

§

TruncatedPatch

Stream ended without an EOF_ chunk; download or copy was truncated.

Raised by the chunk framing code when attempting to read the 4-byte body_len field of the next chunk returns an unexpected EOF. This indicates the patch stream ended before the mandatory EOF_ terminator chunk was encountered — the patch file was likely incompletely downloaded or written to disk.

Use ZiPatchReader::is_complete after iteration to distinguish this case from a clean end of stream.

§

UnsupportedPlatform(u16)

SqPack path resolution refused to fall back to a default platform layout.

Raised by the apply layer’s internal dat_path and index_path resolvers when crate::apply::ApplyContext::platform is crate::Platform::Unknown: the parser tolerates unrecognised platform_id values from SqpkTargetInfo so that future platforms do not hard-fail parsing, but the apply layer refuses to resolve a .dat/.index path against a guessed-at platform — silently misrouting writes to e.g. the win32 layout would corrupt the on-disk install. The wrapped u16 is the raw platform_id carried by the offending TargetInfo chunk, so callers can surface it to users.

Callers who legitimately know which platform layout to use can override the context after the TargetInfo chunk has been applied (which requires manual chunk iteration rather than ZiPatchReader::apply_to) by setting crate::apply::ApplyContext::platform back to a concrete variant.

§

Cancelled

Apply was cancelled by an ApplyObserver.

Raised by ZiPatchReader::apply_to when an observer returns std::ops::ControlFlow::Break from ApplyObserver::on_chunk_applied, or when ApplyObserver::should_cancel returns true during a long-running chunk (currently checked between blocks of an SqpkFile AddFile operation).

Cancellation is best-effort: filesystem changes already applied by previous chunks — or by previous blocks within the cancelled chunk — are not rolled back. The format provides no transactional semantics, so callers expecting clean cancellation must perform their own recovery at a higher level (e.g. by re-running the patch from scratch against a clean install snapshot).

§

IndexSourceUnavailable

An indexed-apply plan referenced a region whose source bytes are not reachable from the current applier.

Raised by crate::index::IndexApplier when it encounters a crate::index::PartSource::Unavailable region. The builder does not emit this variant from any in-tree chunk parser, so reaching it typically means the plan was hand-constructed (or deserialized) with an explicit crate::index::PartSource::Unavailable region whose source bytes are not in the crate::index::PatchSource the applier was constructed with.

Fields

§target_offset: u64

Target-file offset of the unavailable region.

§length: u32

Length in bytes of the unavailable region.

§

PatchSourceTooShort

A crate::index::PatchSource::read call could not fill the requested buffer.

Raised by crate::index::IndexApplier (via the built-in crate::index::FilePatchSource / [crate::index::MemoryPatchSource] implementations) when the source has fewer than requested bytes available at offset — i.e. the underlying file or buffer is shorter than the plan expected, or the caller passed an offset past the end. Indicates either a truncated patch source or a plan that does not match the source it is being applied against.

Fields

§offset: u64

Patch-file offset at which the read was attempted.

§requested: usize

Number of bytes the caller asked for.

§

PatchIndexOutOfRange

A crate::index::PatchSource::read call asked for a patch index outside the source’s configured chain.

Raised by crate::index::FilePatchSource / [crate::index::MemoryPatchSource] when the applier passes a patch: u32 value >= count. Indicates either a stale plan referring to a patch the source no longer carries, or an off-by-one in a hand-built chain source.

Fields

§patch: u32

Index that was requested.

§count: usize

Total number of patches the source was constructed with.

§

UnsafeTargetPath(String)

An indexed-plan target or filesystem-op carried a path that escapes the install root.

Raised by crate::index::PlanBuilder when a chunk carries a relative path that contains a .. component, starts with / (absolute Unix path), or starts with a Windows drive-letter prefix (e.g. C:\). The indexed builder is a natural choke point for this check; the sequential apply path does not currently reject these paths (writes would land outside the install root if a malicious patch supplied one), but the indexed builder refuses to construct the plan rather than building one that would point at the wrong filesystem location. SqPack-encoded targets (crate::index::TargetPath::SqpackDat / crate::index::TargetPath::SqpackIndex) are structurally constrained by their numeric (main_id, sub_id, file_id) triple and are not subject to this check.

§

SchemaVersionMismatch

A serialized type carrying a schema_version field was decoded with a version this build cannot represent.

Raised by crate::index::Plan::check_schema_version and by the resume side of the apply-checkpoint surface when a persisted record’s schema_version does not equal the constant this build pins. Older readers refuse to silently drop fields they cannot understand rather than risk an apply against a partial decode.

The kind field is a &'static str naming which type’s schema the mismatch refers to ("plan" for crate::index::Plan, future kinds for the checkpoint structs). found is the persisted version, expected the constant this build supports.

Fields

§kind: &'static str

Type name whose schema the mismatch refers to (e.g. "plan").

§found: u32

schema_version field stored on the persisted record.

§expected: u32

schema_version this build supports.

§

DuplicatePatch

Two patches in the same chain shared a name.

Raised by crate::index::PlanBuilder::add_patch (and the freestanding crate::index::build_plan_chain) when a patch with the same name has already been added to this builder. The chain protocol is order-sensitive — re-adding the same patch almost always indicates a caller accidentally fed the same source into the chain twice, which would produce a Plan whose patches vector carries duplicate entries and whose region timelines reapply the same bytes. The builder refuses to construct the plan rather than silently letting this slip through. The duplicate name is preserved so callers can log it.

Fields

§name: String

The patch name that was added twice.

§

Crc32Mismatch

A region’s post-write CRC32 did not match the expected value.

Reserved for content-CRC verification flows that operate on plans populated by crate::index::Plan::compute_crc32. The default builder only emits crate::index::PartExpected::SizeOnly / Zeros / EmptyBlock, so this variant is only reached once a plan has had CRC32 expectations populated and a downstream check compares observed bytes against them.

Fields

§target_offset: u64

Target-file offset of the mismatched region.

§expected: u32

CRC32 declared by the plan’s crate::index::PartExpected::Crc32.

§actual: u32

CRC32 computed over the bytes the applier wrote.

Trait Implementations§

Source§

impl Debug for ZiPatchError

Source§

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

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

impl Display for ZiPatchError

Source§

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

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

impl Error for ZiPatchError

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 From<Error> for ZiPatchError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ZiPatchError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<FromUtf8Error> for ZiPatchError

Source§

fn from(source: FromUtf8Error) -> Self

Converts to this type from the input type.

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> CustomError for T
where T: Display + Debug + Send + Sync + 'static,

Source§

fn as_any(&self) -> &(dyn Any + Sync + Send + 'static)

Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + Sync + Send + 'static)

Source§

fn as_box_any(self: Box<T>) -> Box<dyn Any + Sync + Send>

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> 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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more