{"record":{"id":"de8d9324facd454c","repo":"can1357/oh-my-pi","slug":"invalid-rpm-package-tag-tag-exceeds-header-dat","errorCode":null,"errorMessage":"Invalid RPM package: tag ${tag} exceeds header data","messagePattern":"Invalid RPM package: tag (.+?) exceeds header data","errorType":"validation","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rpm.ts","lineNumber":114,"sourceCode":"\t\t\tif (stringCount > remaining) {\n\t\t\t\tthrow new ArchiveError(`Invalid RPM package: string tag ${tag} exceeds header data`);\n\t\t\t}\n\t\t\tlet cursor = indexSize + offset;\n\t\t\tconst limit = indexSize + intro.dataSize;\n\t\t\tfor (let stringIndex = 0; stringIndex < stringCount; stringIndex++) {\n\t\t\t\twhile (cursor < limit && body[cursor] !== 0) cursor++;\n\t\t\t\tif (cursor === limit) {\n\t\t\t\t\tthrow new ArchiveError(`Invalid RPM package: string tag ${tag} is not NUL-terminated`);\n\t\t\t\t}\n\t\t\t\tcursor++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tthrow new ArchiveError(`Invalid RPM package: tag ${tag} uses unknown data type ${type}`);\n\t\t}\n\t\tif (offset % elementSize !== 0) throw new ArchiveError(`Invalid RPM package: tag ${tag} data is misaligned`);\n\t\tif (count * elementSize > remaining)\n\t\t\tthrow new ArchiveError(`Invalid RPM package: tag ${tag} exceeds header data`);\n\t}\n}\n\nfunction readHeaderString(\n\tbody: Uint8Array,\n\tindexSize: number,\n\tdataSize: number,\n\toffset: number,\n\tcount: number,\n\ttype: number,\n\ttag: number,\n): string {\n\tif (type !== RPM_TYPE_STRING || count !== 1) {\n\t\tthrow new ArchiveError(`Invalid RPM package: tag ${tag} must contain one string`);\n\t}\n\tconst start = indexSize + offset;\n\tconst limit = indexSize + dataSize;\n\tlet end = start;","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rpm.ts#L96-L132","documentation":"For fixed-size numeric/binary tag types, the parser checks that count * elementSize bytes actually fit between the tag's offset and the end of the header data region. An overrun means the index entry claims more data than exists, so the header is inconsistent and the package is rejected.","triggerScenarios":"readRpm()/parseMainHeader validates an index entry whose count * elementSize exceeds dataSize - offset, e.g. an INT32 tag with count 10 but only 8 bytes remaining in the data region.","commonSituations":"Truncated .rpm files (header data cut off mid-region); corrupted count or offset fields; crafted packages attempting to make the parser read out of bounds.","solutions":["Re-download or rebuild the package — the header cannot be trusted.","Check file size against the upstream checksum to detect truncation.","Confirm with `rpm -qp` that the file is genuinely malformed.","Handle ArchiveError in your pipeline and skip the package with a logged reason."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (fileSize < expectedMinimumSize) throw new Error(\"file too small to be a complete RPM\");","typeGuard":null,"tryCatchPattern":"try {\n  const entries = await readRpm(source, options);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"exceeds header data\")) {\n    return { ok: false, reason: \"truncated RPM header\" };\n  }\n  throw err;\n}","preventionTips":["Compare downloaded file size and hash with the repository manifest before parsing.","Fail fast on truncated transfers rather than passing partial files to the parser.","Restrict parsing to packages from signed, trusted repositories."],"tags":["rpm","archive","bounds-check","corrupt-file"],"backgroundTag":"rpm-header-validation-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}