can1357/oh-my-pi · error · ArchiveError

Empty ar archive long name at offset ${offset}

Error message

Empty ar archive long name at offset ${offset}

What it means

resolveLongName extracts an entry name from the ar '//' long-name table. This error means the name slice at the requested offset was zero bytes long — the table contains an empty string where a filename was expected. The library treats a corrupt/empty long-name reference as a structural archive failure and refuses to guess.

Source

Thrown at packages/utils/src/ar/unix-ar.ts:140

}

function resolveLongName(
	reference: string,
	table: Uint8Array,
	limits: ArchiveLimits,
): { name: string; byteLength: number } {
	const offsetText = reference.slice(1);
	if (!/^\d+$/.test(offsetText)) throw new ArchiveError(`Invalid ar archive member name '${reference}'`);
	const offset = Number.parseInt(offsetText, 10);
	if (!Number.isSafeInteger(offset) || offset < 0 || offset >= table.byteLength) {
		throw new ArchiveError(`Invalid ar archive long-name offset '${reference}'`);
	}
	let end = offset;
	while (end < table.byteLength && table[end] !== 0 && table[end] !== 0x0a) end++;
	if (end === table.byteLength) throw new ArchiveError(`Unterminated ar archive long name at offset ${offset}`);
	let nameEnd = end;
	if (table[end] === 0x0a && nameEnd > offset && table[nameEnd - 1] === 0x2f) nameEnd--;
	if (nameEnd === offset) throw new ArchiveError(`Empty ar archive long name at offset ${offset}`);
	const nameBytes = table.subarray(offset, nameEnd);
	return { name: decodeName(nameBytes, limits), byteLength: nameBytes.byteLength };
}

function isMetadataName(name: string): boolean {
	return name === "/" || name === "//" || name === "/SYM64/" || name === "__.SYMDEF" || name === "__.SYMDEF SORTED";
}

function materializeEntries(
	records: RawArMember[],
	longNames: Uint8Array | undefined,
	source: ByteSource,
	options: FormatReadOptions,
): ArchiveIndexEntry[] {
	const entries = new Map<string, ArchiveIndexEntry>();
	for (const record of records) {
		let name = record.name;
		let nameByteLength = record.nameByteLength;

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-download or re-extract the archive — the long-name table is corrupt and usually the file itself is damaged.
  2. Re-create the archive with ar/gcc-ar so the '//' table is regenerated correctly.
  3. If you control the writer, ensure every '/NNN' offset points at a non-empty NUL/newline-terminated name (with a trailing '/' where applicable).
  4. If you only need short-named members, skip or pre-filter entries with '/NNN' names before materializing.

Example fix

// before: trusting an untrusted .deb
const entries = await readUnixAr(file);
// after: validate archive integrity (e.g. checksum) before parsing
if (!(await verifyChecksum(file))) throw new Error('corrupt archive');
const entries = await readUnixAr(file);
Defensive patterns

Strategy: validation

Validate before calling

function hasLongNameTable(records: {name: string}[], longNames?: Uint8Array): boolean {
  return !records.some(r => /^\/\d+$/.test(r.name)) || longNames !== undefined;
}
if (!hasLongNameTable(rawRecords, longNames)) throw new Error('long-name table corrupt or missing');

Type guard

function isPlausibleLongNameTable(t: Uint8Array | undefined): t is Uint8Array {
  return t !== undefined && t.byteLength > 0;
}

Try / catch

try {
  const entries = await readUnixAr(source);
} catch (err) {
  if (err instanceof ArchiveError && /long name/.test(err.message)) {
    throw new Error(`archive long-name table corrupt: ${err.message}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: An archive member whose name is '/NNN' points at an offset in the long-name table that is either immediately followed by a terminator (offset at end of table, or an empty line), producing a zero-length name slice.

Common situations: Corrupted or truncated .deb/.a files during download; archives written by non-conforming tools that pad the long-name table incorrectly; hand-edited or binary-patched archives; fuzz/malicious inputs.

Related errors


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