{"record":{"id":"60aa88429a3300cd","repo":"can1357/oh-my-pi","slug":"invalid-cpio-archive-mode-exceeds-16-bits","errorCode":null,"errorMessage":"Invalid CPIO archive: mode exceeds 16 bits","messagePattern":"Invalid CPIO archive: mode exceeds 16 bits","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/cpio.ts","lineNumber":226,"sourceCode":"\tconst portableTarget = rawTarget.replace(/\\\\/g, \"/\");\n\tif (path.posix.isAbsolute(portableTarget)) return { path: portableTarget, resolveTarget: false };\n\tconst normalized = normalizeArchiveLookupPath(path.posix.join(path.posix.dirname(recordPath), portableTarget));\n\treturn normalized === undefined\n\t\t? { path: portableTarget, resolveTarget: false }\n\t\t: { path: normalized, resolveTarget: true };\n}\n\n/** Parse an already-materialized CPIO stream for direct and RPM-composed readers. */\nexport function readCpioEntriesFromBuffer(bytes: Uint8Array, options: FormatReadOptions): ArchiveIndexEntry[] {\n\tassertInMemorySize(bytes.byteLength, options.limits);\n\tconst records: ParsedRecord[] = [];\n\tlet offset = 0;\n\tlet metadataSize = 0;\n\tlet foundTrailer = false;\n\n\twhile (offset < bytes.byteLength) {\n\t\tconst header = parseHeader(bytes, offset);\n\t\tif (header.mode > 0xffff) throw new ArchiveError(\"Invalid CPIO archive: mode exceeds 16 bits\");\n\t\tif (header.nameSize < 1) throw new ArchiveError(\"Invalid CPIO archive: name size must include a NUL terminator\");\n\t\tassertArchivePathBytes(header.nameSize - 1, \"member path\", options.limits.maxPathBytes);\n\t\tassertArchiveMemberSize(header.fileSize, \"(CPIO entry)\", options.limits);\n\n\t\tconst nameStart = offset + header.headerSize;\n\t\tconst nameEnd = nameStart + header.nameSize;\n\t\tconst dataOffset = align(nameEnd, header.alignment);\n\t\tconst dataEnd = dataOffset + header.fileSize;\n\t\tconst nextOffset = align(dataEnd, header.alignment);\n\t\trequireRange(bytes, nameStart, nameEnd, \"member name\");\n\t\trequireRange(bytes, dataOffset, dataEnd, \"member data\");\n\t\trequireRange(bytes, dataEnd, nextOffset, \"member padding\");\n\t\tif (bytes[nameEnd - 1] !== 0) throw new ArchiveError(\"Invalid CPIO archive: member name is not NUL-terminated\");\n\t\tfor (let index = nameStart; index < nameEnd - 1; index++) {\n\t\t\tif (bytes[index] === 0) throw new ArchiveError(\"Invalid CPIO archive: member name contains an embedded NUL\");\n\t\t}\n\t\tvalidateZeroPadding(bytes, nameEnd, dataOffset, \"name\");\n\t\tvalidateZeroPadding(bytes, dataEnd, nextOffset, \"data\");","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/cpio.ts#L208-L244","documentation":"readCpioEntriesFromBuffer validates each parsed header's mode against the 16-bit POSIX file-mode space and throws ArchiveError if mode > 0xFFFF. Old-binary headers read mode as a 16-bit value (cannot exceed), so in practice this fires on ASCII formats where a corrupt or hostile 8-hex-digit field encodes a value beyond 0xFFFF — indicating a corrupt header or tampered archive.","triggerScenarios":"Parsing a newc ('070701'/'070702') archive whose mode field hex value exceeds FFFF, e.g. all-'F' fields or corruption shifting digit bytes into the mode slot; crafted archives from fuzzing/security tooling.","commonSituations":"Fuzzed or maliciously crafted archives; byte corruption in transit; custom writers emitting 32-bit mode words (including high flags) into the mode field instead of the standard permission+type bits.","solutions":["Rebuild the archive with a standard tool so mode fields contain conventional 16-bit permission/type values","Fix a custom writer to mask mode to 0o7777 | file-type bits (e.g. mode & 0o1707777 → but emit ≤ 0xFFFF)","Verify archive integrity (checksum) — this error usually means the mode field bytes are corrupt","Treat untrusted archives triggering this as rejected input in your ingestion pipeline"],"exampleFix":"// before: writer emits 32-bit mode\nheader.write(mode.toString(16).padStart(8, '0'), MODE_OFFSET, 'ascii');\n// after: clamp to 16-bit st_mode space\nconst m16 = mode & 0xffff;\nheader.write(m16.toString(16).padStart(8, '0'), MODE_OFFSET, 'ascii');","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const entries = await readCpio(source, options);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('mode exceeds 16 bits')) {\n    // corrupt/hostile header: reject the archive rather than retry\n  } else throw err;\n}","preventionTips":["Custom writers must emit mode as 16-bit permission+type bits (≤ 0xFFFF)","Treat this error on untrusted input as tampering and quarantine the archive","Verify archive checksums to catch corruption in the mode field","Regenerate archives with standard tooling"],"tags":["archive","cpio","mode","validation"],"backgroundTag":"corrupt-archive-header","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}