{"record":{"id":"537423352f9cad9b","repo":"can1357/oh-my-pi","slug":"invalid-xz-stream-block-sha-256-mismatch","errorCode":null,"errorMessage":"Invalid XZ stream: block SHA-256 mismatch","messagePattern":"Invalid XZ stream: block SHA-256 mismatch","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/xz.ts","lineNumber":425,"sourceCode":"\t\t\tthrow new ArchiveError(`Unsupported XZ filter ID 0x${filter.id.toString(16)}`);\n\t}\n}\n\nfunction verifyCheck(checkId: number, output: Uint8Array, expected: Uint8Array): void {\n\tif (checkId === 0) return;\n\tif (checkId === 1) {\n\t\tif (read32LE(expected, 0) !== crc32(output)) throw new ArchiveError(\"Invalid XZ stream: block CRC32 mismatch\");\n\t\treturn;\n\t}\n\tif (checkId === 4) {\n\t\tconst actual = crc64(output);\n\t\tlet stored = 0n;\n\t\tfor (let index = 0; index < 8; index++) stored |= BigInt(expected[index]!) << BigInt(index * 8);\n\t\tif (actual !== stored) throw new ArchiveError(\"Invalid XZ stream: block CRC64 mismatch\");\n\t\treturn;\n\t}\n\tconst actual = new Uint8Array(new Bun.CryptoHasher(\"sha256\").update(output).digest());\n\tif (!equalBytes(actual, expected)) throw new ArchiveError(\"Invalid XZ stream: block SHA-256 mismatch\");\n}\n\nasync function decodeBlock(bytes: Uint8Array, offset: number, record: XzRecord, checkId: number): Promise<Uint8Array> {\n\tif (offset >= bytes.byteLength || bytes[offset] === 0)\n\t\tthrow new ArchiveError(\"Invalid XZ stream: missing block header\");\n\tconst headerSize = (bytes[offset]! + 1) * 4;\n\tif (offset + headerSize > bytes.byteLength || headerSize < 8)\n\t\tthrow new ArchiveError(\"Invalid XZ stream: truncated block header\");\n\tif (crc32(bytes.subarray(offset, offset + headerSize - 4)) !== read32LE(bytes, offset + headerSize - 4))\n\t\tthrow new ArchiveError(\"Invalid XZ stream: block header CRC32 mismatch\");\n\tconst cursor: Cursor = { bytes, pos: offset + 1, limit: offset + headerSize - 4 };\n\tconst flags = bytes[cursor.pos++]!;\n\tif ((flags & 0x3c) !== 0) throw new ArchiveError(\"Unsupported XZ block flags\");\n\tconst filterCount = (flags & 3) + 1;\n\tconst declaredCompressed = (flags & 0x40) !== 0 ? readVarInt(cursor) : undefined;\n\tconst declaredUncompressed = (flags & 0x80) !== 0 ? readVarInt(cursor) : undefined;\n\tconst filters: XzFilter[] = [];\n\tfor (let index = 0; index < filterCount; index++) {","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/xz.ts#L407-L443","documentation":"XZ check type 10 is SHA-256. The library hashes each decoded block with Bun's SHA-256 CryptoHasher and compares to the 32 bytes stored in the block. A mismatch means the decompressed output differs from what the encoder committed — the stream is corrupt, truncated, or was tampered with.","triggerScenarios":"Decoding an XZ stream created with `xz --check=sha256` where a block's stored 32-byte SHA-256 does not equal the hash of the block's decoded output.","commonSituations":"Archives stored on failing disks; corrupted cloud sync; deliberate modification of archive contents; producer-side bugs writing wrong check bytes.","solutions":["Replace the file with a verified copy from the original source","Cross-check with the xz CLI (`xz -t`) to confirm the corruption is in the file, not the decoder","Re-compress the original data if the source archive is unrecoverable","Treat the input as untrusted and reject it with a clear integrity error message"],"exampleFix":"// before: ignoring integrity errors\ncatch { /* proceed with partial data */ }\n// after: fail closed on hash mismatch\ncatch (e) { if (String(e.message).includes('SHA-256 mismatch')) throw new Error('Archive integrity check failed'); }","handlingStrategy":"try-catch","validationCode":"const t = await $`xz -t archive.xz`.quiet().nothrow();\nif (t.exitCode !== 0) throw new Error('archive.xz failed integrity check');","typeGuard":"null","tryCatchPattern":"try {\n  return await decodeXz(bytes);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('SHA-256 mismatch')) {\n    throw new Error('XZ block data is corrupt (SHA-256); archive must be replaced');\n  }\n  throw err;\n}","preventionTips":["Use xz's default CRC64 check unless SHA-256 is required and you verify end-to-end","Confirm any post-compression transformation of the file (encryption wrappers, signatures) doesn't touch the XZ bytes","Keep original data so corrupt archives can be re-compressed","Treat integrity mismatch as fail-closed; never emit partial decompressed data"],"tags":["xz","archive","sha256","integrity","corrupt-input"],"backgroundTag":"checksum-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}