{"record":{"id":"ccf47a089c6e2191","repo":"can1357/oh-my-pi","slug":"invalid-rpm-package-null-tag-tag-has-values","errorCode":null,"errorMessage":"Invalid RPM package: null tag ${tag} has values","messagePattern":"Invalid RPM package: null tag (.+?) has values","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rpm.ts","lineNumber":89,"sourceCode":"\nfunction validateHeaderBody(body: Uint8Array, intro: HeaderIntro, what: string): void {\n\tconst indexSize = intro.indexCount * RPM_INDEX_ENTRY_SIZE;\n\tif (body.byteLength !== intro.bodySize) throw new ArchiveError(`Invalid RPM package: truncated ${what} header`);\n\tfor (let index = 0; index < intro.indexCount; index++) {\n\t\tconst recordOffset = index * RPM_INDEX_ENTRY_SIZE;\n\t\tconst tag = readUInt32BE(body, recordOffset);\n\t\tconst type = readUInt32BE(body, recordOffset + 4);\n\t\tconst offset = readUInt32BE(body, recordOffset + 8);\n\t\tconst count = readUInt32BE(body, recordOffset + 12);\n\t\tif (offset > intro.dataSize) throw new ArchiveError(`Invalid RPM package: tag ${tag} points outside header data`);\n\t\tconst remaining = intro.dataSize - offset;\n\t\tlet elementSize = 0;\n\t\tif (type === 1 || type === 2 || type === 7) elementSize = 1;\n\t\telse if (type === 3) elementSize = 2;\n\t\telse if (type === 4) elementSize = 4;\n\t\telse if (type === 5) elementSize = 8;\n\t\telse if (type === 0) {\n\t\t\tif (count !== 0) throw new ArchiveError(`Invalid RPM package: null tag ${tag} has values`);\n\t\t\tcontinue;\n\t\t} else if (type === RPM_TYPE_STRING || type === 8 || type === 9) {\n\t\t\tconst stringCount = type === RPM_TYPE_STRING ? 1 : count;\n\t\t\tif (type === RPM_TYPE_STRING && count !== 1) {\n\t\t\t\tthrow new ArchiveError(`Invalid RPM package: string tag ${tag} has an invalid count`);\n\t\t\t}\n\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}","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rpm.ts#L71-L107","documentation":"ArchiveError thrown by validateHeaderBody() when an index entry has type 0 (RPM NULL type) but a non-zero count. Per the RPM format, NULL entries carry no data, so count must be 0; this enforces that invariant while walking the header index.","triggerScenarios":"Header index entry with type==0 and count!==0 — non-conformant header written by broken tooling, or corrupted index bytes.","commonSituations":"Packages produced by non-rpm tools or custom repackers, bit corruption in the index region, fuzzed inputs.","solutions":["Rebuild/re-download the package with standard rpmbuild","Verify checksums before parsing","If generating headers yourself, set count=0 for NULL-type entries"],"exampleFix":"// before\n{ tag: 1234, type: 0, offset: 0, count: 4 } // NULL with values\n// after\n{ tag: 1234, type: 0, offset: 0, count: 0 } // NULL entries carry no data","handlingStrategy":"try-catch","validationCode":"// validate with standard tooling before parsing\nconst chk = await $`rpm -K ${path}`.quiet().nothrow();\nif (chk.exitCode !== 0) throw new Error('rpm failed verification');","typeGuard":"null","tryCatchPattern":"try {\n  const rpm = await readRpmArchive(buf);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('null tag')) {\n    // reject non-conformant header\n  } else throw err;\n}","preventionTips":["Produce packages only with standard rpmbuild","Reject packages failing `rpm -K` before parsing","Keep checksum verification in the ingestion pipeline"],"tags":["rpm","archive","format-validation","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"}