Skip to content

[Bug] CJK PDFs render blank and index empty: PDF.js CMap/font assets are not bundled #130

Description

@mrsibe

Symptom

CJK PDFs (Chinese / Japanese / Korean) fail in two places at once:

  • Reader: the canvas has no glyphs for CJK runs; the text layer is missing the same text.
  • Ingestion: PdfLoader.getTextContent() silently drops every CJK run, so chunks contain only the Latin/ASCII text. Anything the model could retrieve from that document is therefore wrong or empty — this is a plausible part of why notebook chat "does not retrieve or cite indexed knowledge" for CJK sources.

The only signal is a warning, not an exception:

Warning: loadFont - translateFont failed:
"UnknownErrorException: Ensure that the `cMapUrl` API parameter is provided."
Warning: Error during font loading:
Ensure that the `cMapUrl` API parameter is provided.

Because it is a warning, both paths "succeed" with missing text.

Root cause

PDF.js treats predefined CMaps, standard fonts and the wasm image decoders as external assets fetched by filename (${cMapUrl}${name}.bcmap). KnowNote never passed any of the three to getDocument:

  • PdfLoader.ts — getDocument({ data, password })
  • PdfSourceReader.tsx — getDocument({ data })

pdfjs-dist ships the files (cmaps/, standard_fonts/, wasm/), but nothing references them.

Reproduced on main with noembed-jis7.pdf (non-embedded Japanese font):

extracted text CJK present
no cMapUrl "ABC 1231" ❌
cMapUrl + cMapPacked "ABCあいうえお123 1" ✅

Scope

  1. Bundle pdfjs-dist/{cmaps,standard_fonts,wasm} as real files (electron-builder extraResources → resources/pdfjs/, outside app.asar).
  2. Pass cMapUrl + cMapPacked: true to both getDocument call sites.
  3. Pass standardFontDataUrl and wasmUrl too — PDF.js exposes all three as one contract.
  4. Renderer reads them through a dedicated knownote-asset:// protocol (the renderer must not receive filesystem paths, same rule as knownote-doc://). Main reads them as filesystem paths.
  5. CSP: allow the scheme in connect-src; add 'wasm-unsafe-eval' for wasm compilation. The scripting boundary from security(pdf): remediate GHSA-hq66-cqwq-w95j before v1.4 (pdfjs-dist 5.7.284 in affected range) #121 is unaffected — that forbids JS eval/inline script, and script-src still has no 'unsafe-eval'.
  6. Verify the packaged layout, not just npm run dev.

Acceptance

Renderer

  • the same CJK PDF renders CJK on the canvas
  • no cMapUrl / font-loading warnings in the console
  • the text layer is selectable and shows CJK

Ingestion / retrieval

  • getTextContent() on the same PDF returns correct CJK
  • document blocks and chunks contain correct CJK
  • a distinctive CJK sentence from the document is retrieved by Retriever

Packaging

  • npm run build:unpack ships resources/pdfjs/{cmaps,standard_fonts,wasm}
  • npm run smoke:packaged passes on the packaged app

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:infraBuild, packaging, CI, dependenciesarea:provenanceSource location, citations, document structurebugSomething isn't working

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions