{"record":{"id":"c3150a70b258ab83","repo":"can1357/oh-my-pi","slug":"invalid-xz-bcj-filter-0x-filter-id-tostring-16-c3150a","errorCode":null,"errorMessage":"Invalid XZ BCJ filter 0x${filter.id.toString(16)} start offset","messagePattern":"Invalid XZ BCJ filter 0x(.+?) start offset","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/xz.ts","lineNumber":380,"sourceCode":"\t\t}\n\t\twrite32LE(bytes, index, instruction);\n\t\twrite32LE(bytes, index + 4, instruction2);\n\t\tindex += 6;\n\t}\n}\n\nfunction applyFilter(bytes: Uint8Array, filter: XzFilter): void {\n\tif (filter.id === 3) {\n\t\tif (filter.properties.byteLength !== 1) throw new ArchiveError(\"Invalid XZ Delta filter properties\");\n\t\tdeltaDecode(bytes, filter.properties[0]! + 1);\n\t\treturn;\n\t}\n\tif (filter.properties.byteLength !== 0 && filter.properties.byteLength !== 4)\n\t\tthrow new ArchiveError(`Invalid XZ BCJ filter 0x${filter.id.toString(16)} properties`);\n\tconst startOffset = filter.properties.byteLength === 4 ? read32LE(filter.properties, 0) : 0;\n\tconst alignment = filter.id === 6 ? 16 : filter.id === 8 || filter.id === 11 ? 2 : filter.id === 4 ? 1 : 4;\n\tif ((startOffset & (alignment - 1)) !== 0)\n\t\tthrow new ArchiveError(`Invalid XZ BCJ filter 0x${filter.id.toString(16)} start offset`);\n\tswitch (filter.id) {\n\t\tcase 4:\n\t\t\tx86Decode(bytes, startOffset);\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tpowerPcDecode(bytes, startOffset);\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tia64Decode(bytes, startOffset);\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tarmDecode(bytes, startOffset);\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tarmThumbDecode(bytes, startOffset);\n\t\t\tbreak;\n\t\tcase 9:\n\t\t\tsparcDecode(bytes, startOffset);","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/xz.ts#L362-L398","documentation":"Each BCJ XZ filter requires its start offset to be aligned to the instruction size it decodes (16 for ARM64, 2 for RISC-V/Thumb-style, 4 for most others, 1 for x86's special case here when id=4 alignment is 1). The library throws when the 4-byte start offset stored in a BCJ filter's properties is not a multiple of the filter's required alignment.","triggerScenarios":"Decompressing an XZ stream where a BCJ filter's properties contain a 4-byte start offset whose value fails the alignment check (e.g. start offset 1 with a 4-byte-aligned filter such as PowerPC or SPARC).","commonSituations":"Archives produced by encoders that wrote an unaligned start offset; manual or corrupted edits to filter properties; exotic BCJ start offsets from non-default encoder configurations that this decoder validates strictly.","solutions":["Re-compress the file with standard xz using default BCJ settings (no custom --delta start offset) to get an aligned start offset","Check the producing encoder's start-offset argument and align it to the filter's instruction size","Verify the file with `xz -t` and obtain a good copy if the bytes are corrupt","If this file must be decoded, pre-process it externally (decode with the xz binary) and feed uncompressed data to the library"],"exampleFix":"// before: unaligned start offset for PowerPC BCJ (alignment 4)\nconst filter = { id: 5, properties: new Uint8Array([1, 0, 0, 0]) };\n// after: start offset aligned to the filter's instruction size\nconst filter = { id: 5, properties: new Uint8Array([4, 0, 0, 0]) };","handlingStrategy":"validation","validationCode":"function bcjStartOffsetAligned(f: { id: number; properties: Uint8Array }): boolean {\n  if (f.properties.byteLength !== 4) return true;\n  const off = f.properties[0] | f.properties[1] << 8 | f.properties[2] << 16 | f.properties[3] << 24;\n  const align = f.id === 6 ? 16 : f.id === 8 || f.id === 11 ? 2 : f.id === 4 ? 1 : 4;\n  return (off & (align - 1)) === 0;\n}","typeGuard":"null","tryCatchPattern":"try {\n  await decodeXz(bytes);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('start offset')) {\n    throw new Error('Archive BCJ start offset is misaligned; re-compress with default xz settings');\n  }\n  throw err;\n}","preventionTips":["When compressing with BCJ filters, leave start offsets at defaults or align them to the filter's instruction size","Avoid custom xz encoder flags (e.g. --delta=start=...) unless you control both ends","Keep the xz tool and this library current so exotic configurations are handled consistently"],"tags":["xz","archive","bcj","alignment","corrupt-input"],"backgroundTag":"corrupt-archive-input","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}