From 93c456355550fac3a1dd1b10a05e601f00fe6471 Mon Sep 17 00:00:00 2001 From: AirRunner Date: Wed, 3 Jun 2026 19:34:09 +0200 Subject: [PATCH] fix: handle bvx2 LZFSE blocks in IWA decompression Numbers Creator Studio can write bvx2 (LZFSE) instead of bvxn (LZVN) for OperationStorage.iwa. Matching the 3-byte bvx prefix instead of the 4-byte bvxn magic routes all LZFSE variants to decompressLZFSE(), which handles them correctly via compression_decode_buffer. --- Sources/WorkKit/IWorkParser.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/WorkKit/IWorkParser.swift b/Sources/WorkKit/IWorkParser.swift index 958afd1..69205ed 100644 --- a/Sources/WorkKit/IWorkParser.swift +++ b/Sources/WorkKit/IWorkParser.swift @@ -434,17 +434,17 @@ enum IWorkParser { // MARK: - IWA Decompression /// LZFSE block magics. Apple's LZFSE framing uses these little-endian 4-byte markers; - /// `bvxn` is the LZVN compressed-block header and `bvx$` closes the stream. + /// `bvxn` (LZVN) and `bvx2` (LZFSE) are compressed-block headers and `bvx$` closes the stream. /// Creator Studio–era writers emit some IWAs (e.g. `OperationStorage.iwa`) in this framing /// instead of the classic `0x00 | len24 | snappy-chunk` repeating structure. - private static let lzfseMagicBvxn: [UInt8] = [0x62, 0x76, 0x78, 0x6E] + private static let lzfseMagicBvx: [UInt8] = [0x62, 0x76, 0x78] private static func decompressIWA(_ data: Data) throws -> Data { guard data.count >= 4 else { throw IWorkError.invalidArchiveStructure(reason: "IWA file too small to contain a header.") } - if data.starts(with: Self.lzfseMagicBvxn) { + if data.starts(with: Self.lzfseMagicBvx) { return try decompressLZFSE(data) }