mozilla/pdf.js · error · FormatError

writing to an offset that is not empty

Error message

writing to an offset that is not empty

What it means

Thrown by CFFOffsetTracker.setEntryLocation while writing a 5-byte offset placeholder. The placeholder must be the sentinel byte 0x1d followed by four zero bytes; if those bytes are already non-zero, writing would silently corrupt already-emitted data, so the sanity check aborts.

Source

Thrown at src/core/cff_parser.js:1480

    }
    const data = output.data;
    const dataOffset = this.offsets[key];
    const size = 5;
    for (let i = 0, ii = values.length; i < ii; ++i) {
      const offset0 = i * size + dataOffset;
      const offset1 = offset0 + 1;
      const offset2 = offset0 + 2;
      const offset3 = offset0 + 3;
      const offset4 = offset0 + 4;
      // It's easy to screw up offsets so perform this sanity check.
      if (
        data[offset0] !== 0x1d ||
        data[offset1] !== 0 ||
        data[offset2] !== 0 ||
        data[offset3] !== 0 ||
        data[offset4] !== 0
      ) {
        throw new FormatError("writing to an offset that is not empty");
      }
      const value = values[i];
      data[offset0] = 0x1d;
      data[offset1] = (value >> 24) & 0xff;
      data[offset2] = (value >> 16) & 0xff;
      data[offset3] = (value >> 8) & 0xff;
      data[offset4] = value & 0xff;
    }
  }
}

// Takes a CFF and converts it to the binary representation.
class CFFCompiler {
  constructor(cff) {
    this.cff = cff;
  }

  compile() {

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Report the issue to pdf.js with the offending font — this is an internal compiler invariant failure.
  2. Verify that offsetTracker.offset() is applied consistently and that placeholders are emitted exactly once per tracked key.
  3. If patching, ensure no code path writes into the placeholder region between track() and setEntryLocation().

Example fix

// before (internal: placeholder region already non-zero)
tracker.setEntryLocation('Subrs', [len], output); // throws

// after (ensure placeholders are zero when written)
if (
  data[offset0] === 0x1d &&
  data[offset1] === 0 &&
  data[offset2] === 0 &&
  data[offset3] === 0 &&
  data[offset4] === 0
) {
  tracker.setEntryLocation('Subrs', [len], output);
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify the placeholder is still empty before writing.
function placeholderIsEmpty(data, offset0) {
  return (
    data[offset0] === 0x1d &&
    data[offset0 + 1] === 0 &&
    data[offset0 + 2] === 0 &&
    data[offset0 + 3] === 0 &&
    data[offset0 + 4] === 0
  );
}

Type guard

function isPlaceholderEmpty(data, offset0) {
  return data[offset0] === 0x1d && data[offset0 + 1] === 0 &&
    data[offset0 + 2] === 0 && data[offset0 + 3] === 0 &&
    data[offset0 + 4] === 0;
}

Try / catch

try {
  tracker.setEntryLocation(key, values, output);
} catch (e) {
  // Placeholder region was non-zero; internal offset corruption.
  throw new Error(`Offset placeholder for '${key}' was not empty`);
}

Prevention

When it happens

Trigger: During CFF compilation, setEntryLocation computes offset positions and finds the target bytes are not the expected 0x1d,0,0,0,0 pattern. This means the placeholder region was overwritten or the computed offset points at the wrong location — an internal compiler state bug.

Common situations: A pdf.js internal bug in offset arithmetic (wrong outputLength, double offset adjustment); a malformed font that drives compileDict to emit overlapping placeholders; regressions after changes to the DataBuilder/compileIndex logic.

Related errors


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/e083f0476c1f96cf. Report an issue: GitHub.