{"record":{"id":"1f904b22b6687b22","repo":"can1357/oh-my-pi","slug":"invalid-cpio-archive-non-zero-what-padding","errorCode":null,"errorMessage":"Invalid CPIO archive: non-zero ${what} padding","messagePattern":"Invalid CPIO archive: non-zero (.+?) padding","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/cpio.ts","lineNumber":198,"sourceCode":"\t\t\tmtime: parseDigits(bytes, offset + 48, 11, 8, \"modification time\"),\n\t\t\tnameSize: field6(59, \"name size\"),\n\t\t\tfileSize: parseDigits(bytes, offset + 65, 11, 8, \"file size\"),\n\t\t};\n\t}\n\tthrow new ArchiveError(`Invalid CPIO archive: unsupported or corrupt magic at offset ${offset}`);\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string | undefined {\n\ttry {\n\t\treturn UTF8_FATAL_DECODER.decode(bytes);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction validateZeroPadding(bytes: Uint8Array, start: number, end: number, what: string): void {\n\tfor (let offset = start; offset < end; offset++) {\n\t\tif (bytes[offset] !== 0) throw new ArchiveError(`Invalid CPIO archive: non-zero ${what} padding`);\n\t}\n}\n\nfunction makeLinkTarget(recordPath: string, targetBytes: Uint8Array, maxPathBytes: number): LinkTarget {\n\tassertArchivePathBytes(targetBytes.byteLength, \"link target\", maxPathBytes);\n\tconst rawTarget = decodeUtf8(targetBytes);\n\tif (rawTarget === undefined || rawTarget.includes(\"\\0\")) {\n\t\tthrow new ArchiveError(`Invalid CPIO archive: symlink '${recordPath}' has an invalid UTF-8 target`);\n\t}\n\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. */","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/cpio.ts#L180-L216","documentation":"CPIO requires alignment padding after the header+name block and after each entry's file data (4-byte for newc, 2-byte for binary, 1-byte for odc). validateZeroPadding walks that padding region and throws ArchiveError if any byte is non-zero. Strict writers must pad with NUL bytes; non-zero padding signals corruption or a nonconforming writer.","triggerScenarios":"Parsing an archive where name/data alignment padding contains garbage — typically because a writer padded with spaces (0x20), or the computed alignment/offsets shifted so real data or the next header is being read as padding. Raised from readCpioEntriesFromBuffer via validateZeroPadding on 'name' and 'data' regions.","commonSituations":"Hand-rolled archive writers using space padding; corruption flipping NUL bytes; writers using wrong alignment for the declared format (e.g. 4-byte data for odc which needs none); archives patched in place.","solutions":["Regenerate the archive with standard tooling (cpio -H newc / -H odc) which emits correct NUL padding","Fix your writer to pad with 0x00 bytes to the format's alignment boundary","Verify the alignment used matches the magic (newc=4, binary=2, odc=1)","Scan the archive for non-NUL bytes in padding regions to locate the corruption"],"exampleFix":"// before: writer pads with spaces\nconst pad = ' '.repeat(align - (len % align));\n// after: pad with NUL bytes\nconst pad = '\\0'.repeat((align - (len % align)) % align);","handlingStrategy":"validation","validationCode":"// after parsing succeeds, archives are verified internally; pre-validate writers in CI:\nconst entries = readCpioEntriesFromBuffer(testArchiveBytes, options); // run round-trip in tests to catch bad padding","typeGuard":null,"tryCatchPattern":"try {\n  const entries = await readCpio(source, options);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('non-zero') && err.message.includes('padding')) {\n    // repack archive with standard tooling or fix writer padding\n  } else throw err;\n}","preventionTips":["Pad with 0x00 bytes, never spaces, to the format's alignment (newc=4, binary=2, odc=1)","Round-trip custom-written archives through the reader in CI","Avoid in-place patching of archive bytes","Verify checksums to detect corruption-induced non-NUL padding"],"tags":["archive","cpio","padding","alignment"],"backgroundTag":"corrupt-archive-header","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}