{"record":{"id":"62bf85f55dfaef93","repo":"can1357/oh-my-pi","slug":"invalid-xz-stream-non-zero-block-padding","errorCode":null,"errorMessage":"Invalid XZ stream: non-zero block padding","messagePattern":"Invalid XZ stream: non-zero block padding","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/xz.ts","lineNumber":479,"sourceCode":"\tconst compressedStart = offset + headerSize;\n\tconst compressedEnd = compressedStart + compressedSize;\n\tconst paddingSize = (4 - ((headerSize + compressedSize) & 3)) & 3;\n\tconst checkStart = compressedEnd + paddingSize;\n\tif (checkStart + integritySize > bytes.byteLength) throw new ArchiveError(\"Invalid XZ stream: truncated block data\");\n\tconst last = filters[filters.length - 1]!;\n\tif (last.id !== 0x21 || last.properties.byteLength !== 1)\n\t\tthrow new ArchiveError(`Unsupported XZ terminal filter ID 0x${last.id.toString(16)} (LZMA2 required)`);\n\tlet output = await lzma2Decompress(\n\t\tlast.properties[0]!,\n\t\tbytes.subarray(compressedStart, compressedEnd),\n\t\trecord.uncompressedSize,\n\t);\n\tif (output.byteLength !== record.uncompressedSize)\n\t\tthrow new ArchiveError(\"Invalid XZ stream: decoded block size mismatch\");\n\toutput = output.slice();\n\tfor (let index = filters.length - 2; index >= 0; index--) applyFilter(output, filters[index]!);\n\tfor (let index = compressedEnd; index < checkStart; index++)\n\t\tif (bytes[index] !== 0) throw new ArchiveError(\"Invalid XZ stream: non-zero block padding\");\n\tverifyCheck(checkId, output, bytes.subarray(checkStart, checkStart + integritySize));\n\tconst paddedEnd = offset + Math.ceil(record.unpaddedSize / 4) * 4;\n\tif (checkStart + integritySize !== paddedEnd)\n\t\tthrow new ArchiveError(\"Invalid XZ stream: block size does not match its index record\");\n\treturn output;\n}\n\n/** Whether bytes begin with the XZ stream-header magic. */\nexport function isXz(bytes: Uint8Array): boolean {\n\treturn bytes.byteLength >= XZ_MAGIC.byteLength && equalBytes(bytes.subarray(0, XZ_MAGIC.byteLength), XZ_MAGIC);\n}\n\n/** Decompress all concatenated streams in an XZ container within `maxOutput`. */\nexport async function xzDecompress(bytes: Uint8Array, maxOutput: number): Promise<Uint8Array> {\n\tif (!Number.isSafeInteger(maxOutput) || maxOutput < 0) throw new ArchiveError(\"Invalid XZ output limit\");\n\ttry {\n\t\tconst streams = discoverStreams(bytes);\n\t\tlet totalSize = 0;","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/xz.ts#L461-L497","documentation":"Between the end of the compressed data and the integrity check, XZ blocks are padded with zero bytes to a 4-byte boundary. A non-zero byte in that gap means the block layout does not match the index record's geometry, so the stream is rejected as invalid.","triggerScenarios":"xzDecompress scans bytes from compressedEnd to checkStart after decompression and finds any non-zero padding byte.","commonSituations":"Archives damaged after creation (bytes overwritten in the padding region), hand-spliced streams, or non-conforming encoders that write junk instead of zero padding.","solutions":["Re-acquire an intact copy of the archive and verify with `xz -t`.","Re-encode with the standard xz tool if a custom producer wrote the stream.","Avoid any post-processing that rewrites archive bytes in place.","Treat repeated occurrences as evidence of a faulty producer or failing storage medium."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const ok = await $`xz -t ${path}`.quiet().nothrow();\nif (ok.exitCode !== 0) throw new Error(`XZ integrity check failed: ${path}`);","typeGuard":null,"tryCatchPattern":"try {\n\treturn await xzDecompress(bytes, maxOutput);\n} catch (err) {\n\tif (err instanceof ArchiveError && /non-zero block padding/i.test(err.message)) {\n\t\tthrow new Error('Archive block layout invalid — file was likely modified or corrupted');\n\t}\n\tthrow err;\n}","preventionTips":["Treat archives as immutable — never edit bytes in place.","Verify checksums after any transfer or backup restore.","Re-encode with stock xz if a non-standard producer wrote padding.","Fail fast on ArchiveError instead of attempting partial recovery."],"tags":["archive","xz","corrupt-data","format-validation"],"backgroundTag":"xz-stream-corrupt","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}