{"record":{"id":"e7dbfa230fa19551","repo":"can1357/oh-my-pi","slug":"invalid-lzma2-stream-trailing-data","errorCode":null,"errorMessage":"Invalid LZMA2 stream: trailing data","messagePattern":"Invalid LZMA2 stream: trailing data","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/lzma.ts","lineNumber":431,"sourceCode":"\t\t\t\tlet property = takeByte();\n\t\t\t\tif (property >= 9 * 5 * 5) throw new ArchiveError(\"Invalid LZMA2 properties\");\n\t\t\t\tconst lc = property % 9;\n\t\t\t\tproperty = Math.floor(property / 9);\n\t\t\t\tconst lp = property % 5;\n\t\t\t\tconst pb = Math.floor(property / 5);\n\t\t\t\tif (lc + lp > 4) throw new ArchiveError(\"Invalid LZMA2 literal properties\");\n\t\t\t\tdecoder.setProperties(lc, lp, pb);\n\t\t\t\tpropertiesSet = true;\n\t\t\t}\n\t\t\tif (packSize > bytes.byteLength - pos || unpackSize > maxOutput - decoder.outputPos)\n\t\t\t\tthrow new ArchiveError(\"Invalid LZMA2 chunk size\");\n\t\t\tif (resetsDictionary) decoder.resetDictionary();\n\t\t\telse if (resetsState) decoder.resetState();\n\t\t\tdecoder.decodeChunk(bytes.subarray(pos, pos + packSize), unpackSize);\n\t\t\tpos += packSize;\n\t\t\tneedDictionaryReset = false;\n\t\t}\n\t\tif (pos !== bytes.byteLength) throw new ArchiveError(\"Invalid LZMA2 stream: trailing data\");\n\t\treturn output.subarray(0, decoder.outputPos);\n\t} catch (error) {\n\t\tif (error instanceof ArchiveError) throw error;\n\t\tthrow new ArchiveError(`Invalid LZMA2 stream: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n}\n","sourceCodeStart":413,"sourceCodeEnd":438,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/lzma.ts#L413-L438","documentation":"After decoding the final LZMA2 chunk (marked by an end marker in the chunk control byte), the decoder requires the input cursor to land exactly at the end of the input buffer. If pos !== bytes.byteLength, extra undecoded bytes follow the terminated stream, so the input is not a single well-formed LZMA2 stream.","triggerScenarios":"Calling lzmaDecompress on a buffer that contains an LZMA2 stream plus appended padding or an extra chunk after the terminating 0x00 control byte; concatenating multiple LZMA2 streams into one buffer and decoding them as one.","commonSituations":"Manually extracted .xz payload with trailing zero padding; concatenated archives; reading a fixed-size block from a file/stream that includes data beyond the stream end.","solutions":["Trim trailing padding/zero bytes so the buffer ends exactly at the LZMA2 end marker.","Split concatenated LZMA2 streams and decompress each separately.","Extract the payload using the container's recorded stream length instead of reading a fixed block size.","If the extra data is intentional, slice it off before calling the decompressor."],"exampleFix":"// before: fixed 4096-byte read includes padding\nconst buf = new Uint8Array(4096);\nlzmaDecompress(buf.subarray(0, bytesRead), max);\n// after: use exact stream length\nlzmaDecompress(buf.subarray(0, streamLength), max);","handlingStrategy":"try-catch","validationCode":"if (bytes.length > 0 && bytes[bytes.length - 1] !== 0x00) {\n  // LZMA2 streams end with a 0x00 terminator control byte\n  throw new Error(\"Buffer does not end at an LZMA2 stream terminator\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return lzmaDecompress(bytes, maxOutput);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"trailing data\")) {\n    throw new Error(\"Extra bytes after LZMA2 end marker — split streams or trim padding\", { cause: err });\n  }\n  throw err;\n}","preventionTips":["Slice buffers to the exact recorded stream length instead of fixed block reads.","Split concatenated LZMA2 streams before decoding.","Strip container padding before passing the payload.","Don't blindly append multiple compressed payloads into one buffer."],"tags":["archive","lzma","malformed-input"],"backgroundTag":"trailing-garbage-after-stream","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}