{"record":{"id":"2a2a6c98a2f72f7e","repo":"mozilla/pdf.js","slug":"unexpected-eof-in-bcmap","errorCode":null,"errorMessage":"unexpected EOF in bcmap","messagePattern":"unexpected EOF in bcmap","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/binary_cmap.js","lineNumber":78,"sourceCode":"class BinaryCMapStream extends Stream {\n  tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE);\n\n  constructor(data) {\n    super(\n      /* arrayBuffer = */ data,\n      /* start = */ 0,\n      /* length = */ data.length,\n      /* dict = */ null\n    );\n  }\n\n  readNumber() {\n    let n = 0;\n    let last;\n    do {\n      const b = this.getByte();\n      if (b < 0) {\n        throw new FormatError(\"unexpected EOF in bcmap\");\n      }\n      last = !(b & 0x80);\n      n = (n << 7) | (b & 0x7f);\n    } while (!last);\n    return n;\n  }\n\n  readSigned() {\n    const n = this.readNumber();\n    return n & 1 ? ~(n >>> 1) : n >>> 1;\n  }\n\n  readHex(num, size) {\n    num.set(this.getBytes(size + 1));\n  }\n\n  readHexNumber(num, size) {\n    let last;","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/binary_cmap.js#L60-L96","documentation":"Thrown by BinaryCMapStream.readNumber() (binary_cmap.js:78) when getByte() returns a negative value while decoding a variable-length, 7-bit-encoded integer from a binary CMap (.bcmap) stream. Binary CMaps are the packed CMap resources PDF.js fetches from cMapUrl to map character codes for CJK (Chinese/Japanese/Korean) fonts. The error means the byte stream ended before a complete integer could be read, so the resource is truncated or corrupt.","triggerScenarios":"BinaryCMapReader.process() parses a .bcmap file (loaded via cMapUrl for a PDF using CJK fonts) whose data is shorter than its encoding declares, or whose leading bytes were consumed and a subsequent record expected more bytes than remain. Concretely: getByte() returning -1 (EOF) inside the do/while loop of readNumber() while a 7-bit varint is only partially read.","commonSituations":"cMapUrl pointing at an incomplete/edited CMap distribution; a CDN or reverse proxy truncating the .bcmap response (wrong Content-Length, gzip issue, partial range request); the fetch landing an HTML 404/500 page whose body is then parsed as binary CMap bytes; an outdated bcmap format shipped with a newer PDF.js build.","solutions":["Verify cMapUrl points to a complete, matching PDF.js CMap distribution (the 'external/bcmaps' folder of the same release) and that cMapPacked is left at its default true.","Confirm the .bcmap file is served whole: fetch it directly, compare byte length to the source file, and check for proxy/CDN truncation or double-gzip.","If a 404/HTML page is being served for the CMap, fix the URL/path so the correct binary resource resolves.","Update PDF.js and its bundled CMaps to the same version so the bcmap format the reader expects matches the files shipped."],"exampleFix":"// before: cMapUrl missing or wrong, packed CMap truncated\ngetDocument({ data, /* cMapUrl omitted */ });\n\n// after: ship the matching packed CMap set and reference it\nimport { GlobalWorkerOptions } from 'pdfjs-dist';\ngetDocument({\n  data,\n  cMapUrl: 'https://mycdn.example.com/pdfjs/cmaps/',\n  cMapPacked: true, // default; ensures .bcmap files are fetched as binary\n}).promise;","handlingStrategy":"validation","validationCode":"// Before getDocument, ensure packed CMaps are reachable and complete.\n// Ship the cmaps folder from the SAME pdfjs-dist release you bundle.\nconst cMapUrl = new URL('cmaps/', import.meta.url).href; // local, complete copy\nconst params = { data, cMapUrl, cMapPacked: true };\n// Optionally HEAD-check a known bcmap to confirm the dir is served:\n// fetch(new URL('GBK-EUC-H.bcmap', cMapUrl), { method: 'HEAD' })\n//   .then(r => { if (!r.ok) throw new Error('CMap dir unreachable'); });","typeGuard":null,"tryCatchPattern":"// CMap errors are caught internally and degrade font mapping; if you must surface them,\n// wrap the rendering task and check for FormatError-like messages.\ntry {\n  await page.render({ canvasContext, viewport }).promise;\n} catch (err) {\n  if (/bcmap|EOF/i.test(err?.message)) {\n    console.warn('CJK CMap resource problem; text may not map correctly', err);\n  } else throw err;\n}","preventionTips":["Bundle the cmaps directory from the exact pdfjs-dist release your app uses.","Keep cMapPacked at its default true and serve .bcmap files as binary (Content-Type application/octet-stream).","Self-host CMaps rather than relying on a third-party CDN that may truncate responses.","Pin your pdfjs-dist version so the bcmap format and reader stay aligned."],"tags":["cmap","cjk-fonts","binary-cmap","corrupt-resource","font","eof"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}