Skip to content

Honor undecodable-font OCR routing in per-page extraction - #431

Open
yzxcj797 wants to merge 1 commit into
firecrawl:mainfrom
yzxcj797:fix/extract-pages-type3-garble-ocr
Open

Honor undecodable-font OCR routing in per-page extraction#431
yzxcj797 wants to merge 1 commit into
firecrawl:mainfrom
yzxcj797:fix/extract-pages-type3-garble-ocr

Conversation

@yzxcj797

@yzxcj797 yzxcj797 commented Aug 19, 2026

Copy link
Copy Markdown

Summary

Detection correctly routes a page to OCR when its used fonts cannot map back to Unicode, including custom-encoded Type3 fonts without ToUnicode. extract_pages_markdown did not consume that font-resource signal. A custom Type3 encoding can map every byte to plausible ASCII letters, so its wrong output could pass output-text heuristics and be returned with needs_ocr=false.

This change routes the existing detection font gate through the shared page_ocr_signals analysis pass:

  • no additional page scan is performed;
  • the page receives suspected_garbled_text;
  • untrusted native markdown is suppressed;
  • Type3 fonts with ToUnicode and pages with another decodable font remain exempt, matching detection.

Fixes #428.

Testing

  • Added the issue's deterministic stdlib-generated Type3 fixture and regression.
  • The regression failed on clean main: detection flagged the page while per-page extraction returned needs_ocr=false.
  • With the fix, both APIs agree the page needs OCR and the reason is suspected_garbled_text.
  • cargo test — 987 unit, 3 CLI, 163 integration, and 2 documentation tests pass
  • cargo fmt --all -- --check — passes
  • cargo clippy — no new warnings; existing pristine-main findings are unchanged
  • git diff --check — passes

Summary by cubic

Per-page extraction now honors the detector’s undecodable-font OCR gate so extraction and detection agree. Previously, pages using Identity-H/V or custom-encoded Type3 fonts without ToUnicode could return trusted markdown with needs_ocr=false; now they return needs_ocr with reason suspected_garbled_text and suppress markdown.

Review notes

  • Routes the undecodable-font signal through the shared page_ocr_signals; its return now includes (template image, undecodable fonts, vector text).
  • Applies OCR reason suspected_garbled_text and suppresses native markdown when undecodable fonts are used.
  • Keeps exemptions: Type3 with ToUnicode or pages that also use any decodable font still extract natively.
  • Uses the same analysis pass; no extra page scanning or performance cost.
  • Adds a deterministic Type3 fixture and regression to verify extraction matches detection on needs_ocr.

Written for commit 15e07c1. Summary will update on new commits.

Review in cubic

extract_pages_markdown ignored the font-resource gate that
classify_pdf/detect_pdf_type use to flag pages whose used fonts cannot
map back to Unicode (Identity-H/V or custom-encoded Type3, both without
ToUnicode). A custom Type3 Encoding can map every byte to a plausible
ASCII letter - e.g. a Caesar-shifted alphabet - so the extracted
markdown passes the cipher/CID/encoding heuristics and the per-page
result returned needs_ocr=false with the wrong native text while
detection correctly routed the same page to OCR with
suspected_garbled_text.

Route the same Phase-3 signal through the shared page_ocr_signals
analysis pass (no extra page scan), add the matching OCR reason, and
suppress the untrusted markdown. The fixture is the deterministic
stdlib-only reproduction from firecrawl#428 (fictional text, no third-party
content).

Fixes firecrawl#428

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Shadow auto-approve: would auto-approve. Fixes extract_pages_markdown to honor the detector's undecodable-font OCR gate (Type3 without ToUnicode), so extraction and detection agree on needs_ocr; adds a regression test with a deterministic fixture.

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant