can1357/oh-my-pi · error · ArchiveError

Invalid RPM package: tag ${tag} string is too large

Error message

Invalid RPM package: tag ${tag} string is too large

What it means

As a defensive limit, single-string metadata tag values longer than 4096 bytes are rejected. Real NAME/VERSION/compressor strings are far shorter, so a value this large indicates corruption or an adversarial header; the parser stops instead of allocating/returning a huge string.

Source

Thrown at packages/utils/src/ar/rpm.ts:135

function readHeaderString(
	body: Uint8Array,
	indexSize: number,
	dataSize: number,
	offset: number,
	count: number,
	type: number,
	tag: number,
): string {
	if (type !== RPM_TYPE_STRING || count !== 1) {
		throw new ArchiveError(`Invalid RPM package: tag ${tag} must contain one string`);
	}
	const start = indexSize + offset;
	const limit = indexSize + dataSize;
	let end = start;
	while (end < limit && body[end] !== 0) end++;
	if (end === limit) throw new ArchiveError(`Invalid RPM package: tag ${tag} string is not NUL-terminated`);
	if (end - start > 4096) throw new ArchiveError(`Invalid RPM package: tag ${tag} string is too large`);
	try {
		return UTF8_FATAL_DECODER.decode(body.subarray(start, end));
	} catch {
		throw new ArchiveError(`Invalid RPM package: tag ${tag} is not valid UTF-8`);
	}
}

function parseMainHeader(body: Uint8Array, intro: HeaderIntro): RpmMetadata {
	validateHeaderBody(body, intro, "main");
	const indexSize = intro.indexCount * RPM_INDEX_ENTRY_SIZE;
	if (body.byteLength !== intro.bodySize) throw new ArchiveError("Invalid RPM package: truncated main header");
	const metadata: RpmMetadata = {};
	for (let index = 0; index < intro.indexCount; index++) {
		const recordOffset = index * RPM_INDEX_ENTRY_SIZE;
		const tag = readUInt32BE(body, recordOffset);
		const type = readUInt32BE(body, recordOffset + 4);
		const offset = readUInt32BE(body, recordOffset + 8);
		const count = readUInt32BE(body, recordOffset + 12);

View on GitHub (pinned to 9690622007)

Solutions

  1. Treat the package as invalid: obtain it from a trusted source and verify its checksum/signature.
  2. Rebuild the package with sane metadata if it came from internal tooling.
  3. Inspect the header tags with `rpm -qp` to see the offending oversized value.
  4. Catch ArchiveError and quarantine the package rather than parsing it.
Defensive patterns

Strategy: validation

Validate before calling

// Verify package authenticity before parsing untrusted RPMs
const trusted = await verifyRpmSignature(filePath); // e.g. rpm --checksig equivalent
if (!trusted) throw new Error("refusing to parse unverified RPM");

Try / catch

try {
  return await readRpm(source, options);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes("string is too large")) {
    return quarantine(file, "oversized RPM metadata (possible tampering)");
  }
  throw err;
}

Prevention

When it happens

Trigger: parseMainHeader decodes one of the known string tags and the NUL-terminated byte run from the tag offset exceeds 4096 characters — e.g. a NAME field stuffed with kilobytes of data by a crafted package.

Common situations: Maliciously crafted packages with oversized metadata fields; corruption that destroys the NUL terminator so the scan runs long; tooling that writes pathological metadata values.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/364e1c6490bc0e79. Report an issue: GitHub.