{"record":{"id":"1fa2b7ad9bf6324c","repo":"mozilla/pdf.js","slug":"invalid-first-and-n-parameters-for-objstm-stream","errorCode":null,"errorMessage":"invalid first and n parameters for ObjStm stream","messagePattern":"invalid first and n parameters for ObjStm stream","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/xref.js","lineNumber":966,"sourceCode":"          xrefEntry !== undefined,\n          'fetchUncompressed: The \"xrefEntry\" cannot be undefined.'\n        );\n      }\n      this.#cacheMap.set(num, xrefEntry);\n    }\n    return xrefEntry;\n  }\n\n  fetchCompressed(ref, xrefEntry, suppressEncryption = false) {\n    const tableOffset = xrefEntry.offset;\n    const stream = this.fetch(Ref.get(tableOffset, 0));\n    if (!(stream instanceof BaseStream)) {\n      throw new FormatError(\"bad ObjStm stream\");\n    }\n    const first = stream.dict.get(\"First\");\n    const n = stream.dict.get(\"N\");\n    if (!Number.isInteger(first) || !Number.isInteger(n)) {\n      throw new FormatError(\"invalid first and n parameters for ObjStm stream\");\n    }\n    let parser = new Parser({\n      lexer: new Lexer(stream),\n      xref: this,\n      allowStreams: true,\n    });\n    const nums = new Array(n);\n    const offsets = new Array(n);\n    // read the object numbers to populate cache\n    for (let i = 0; i < n; ++i) {\n      const num = parser.getObj();\n      if (!Number.isInteger(num)) {\n        throw new FormatError(\n          `invalid object number in the ObjStm stream: ${num}`\n        );\n      }\n      const offset = parser.getObj();\n      if (!Number.isInteger(offset)) {","sourceCodeStart":948,"sourceCodeEnd":984,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/xref.js#L948-L984","documentation":"A FormatError from XRef.fetchCompressed when an Object Stream's /First or /N dictionary entries are not integers. /N declares how many objects the stream contains and /First the byte offset where object data begins; without both as integers the stream cannot be interpreted. The stream object itself was valid, but its descriptive header is corrupt.","triggerScenarios":"An ObjStm whose stream dict is missing /First or /N, has them as floats/strings, or where encryption produced garbage values; a writer bug that wrote fractional or null values.","commonSituations":"Damaged object-stream headers from faulty generators; post-processing that stripped dict entries; partial decryption corruption.","solutions":["Repair with qpdf --object-streams=generate or mutool clean to rebuild object streams.","Re-export from the originating application.","Wrap per-object access in try/catch and degrade gracefully for the affected page.","If authoring, always emit integer /N and /First in ObjStm dicts."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await doc.getPage(n);\n} catch (e) {\n  if (e instanceof pdfjsLib.FormatError) {\n    // mark page unreadable, continue with the rest\n  }\n}","preventionTips":["Pre-validate PDFs with qpdf/mutool before handing to pdf.js.","Catch FormatError at page boundaries to localize damage.","If you generate PDFs, conform ObjStm /Type /N /First headers."],"tags":["objstm","corruption","format-error","xref"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}