Skip to content

Native-first safe jpdf API with OCR module and text layer writer - #148

Draft
Frooodle wants to merge 112 commits into
mainfrom
feat/native-safe-domain
Draft

Frooodle wants to merge 112 commits into
mainfrom
feat/native-safe-domain

Conversation

@Frooodle

@Frooodle Frooodle commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Summary

A native-first core that the Java binding and the new Python binding (PyJPDFium) share. One stage per commit:

  1. Safe jpdf_* C API (jpdfium_api.h), now at 1.5.
    • A native PDFium domain that serializes every PDFium call.
    • Generation-checked handles, and transactional output.
  2. Java migration. Java reaches PDFium only through generated jpdf_guard_* shims admitted by the same domain, with no Java-side lock.
  3. OCRmyPDF-compatible rasterization and perspective rectification.
  4. Invisible text layer writer (OCRmyPDF's generate_pdf contract) and page text extraction.
  5. Optional OCR module, libjpdfium_ocr.
    • PP-OCRv6 small on ONNX Runtime 1.30 (CPU). The OpenCV and Clipper steps are ported so its output matches the official PaddleOCR 3.7 pipeline bit for bit.
    • Models are pinned by digest in profiles.
  6. Bidi and quad layout in the text layer writer. Right-to-left and mixed-direction text, and rotated or skewed lines.
  7. Packaging fixes.
    • The OCR module and its runtime now stage to native/dist/ocr-<platform>, outside the core bundle, so the core's size budget holds.
    • check-native-symbols.sh no longer fails spuriously under pipefail.
  8. A balanced OCR profile that caps detection at 1600 px: about 2x faster and 3-4x less memory at equal accuracy on 300 dpi pages.

Design notes are in docs/design/: ARCHITECTURE.md, NATIVE_ABI.md, TEXT_LAYER.md, OCR.md, RASTER.md, TESTING.md.

Testing

  • Native suite: ctest against real PDFium, 11 of 11, including OCR with both profiles.
  • Sanitizers: ASan+UBSan and TSan clean on the bridge. ONNX Runtime's own leak and worker-thread races are suppressed, nothing of ours.
  • Mutation testing: layout mutations of the text layer writer each fail the native or PyJPDFium suites.
  • Static checks: clang-format, clang-tidy and cppcheck clean on the changed files.
  • Cross-checks in PyJPDFium:
    • OCRmyPDF's own graft and rasterizer;
    • four independent text extractors;
    • the official PaddleOCR pipeline, run offline.

Notes

  • build-qpdf-native-crypto.sh and build-harfbuzz-no-glib.sh fetch upstream's latest release without a pinned version or digest. They were not run here and should be pinned separately.
  • The OCR module is not wired into the Java natives jars yet.

@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • Incremental review skipped - (🔄 Check again to try again)
📝 Summary

Summary by CodeRabbit

  • New Features
    • Added optional OCR support with PP-OCRv6 profiles for recognizing text in images.
    • Added APIs for PDF page rendering, rasterization, image loading and rectification, and invisible text layers.
    • Added batch PDF range extraction and file-based repair operations.
  • Bug Fixes
    • Improved text extraction for negative fractional and exponent-formatted coordinates and escaped font names.
    • Redaction results now prevent saving when analysis is incomplete; byte output uses a full rewrite.
    • PDF edits to rotation and page boxes are now tracked as content changes.
  • Reliability
    • Native PDF operations now share process-wide serialization and lifecycle handling.
    • File publishing validates staged output and reports when durability cannot be confirmed.
    • PDF split and merge workflows now use staged outputs and avoid direct-write fallbacks.

The pull request adds a native PDFium execution domain, guarded Java bindings, and safe native APIs for PDF, image, rendering, text-layer, and file-output operations. It also adds optional OCR support and updates Java PDF workflows, tests, CI, and design documentation.

Changes: JPDFium native platform

Layer / File(s) Summary
Native runtime and guarded bindings
native/bridge/src/runtime/*, native/bridge/src/legacy/*, jpdfium/src/main/java/.../panama/*
The native domain manages PDFium lifecycle, serialized admission, resource counts, and timing statistics. Generated legacy shims and Java bindings route calls through native guards.
Safe APIs and transactional output
native/bridge/include/*, native/bridge/src/objects/*, native/bridge/src/pdf/*, native/bridge/src/images/*, native/bridge/src/output/*, native/bridge/src/textlayer/*, native/rust/*
The bridge adds safe document, page, bitmap, rendering, rasterization, text-layer, image, and transactional output APIs. The Rust layer adds streaming PNG and zlib encoding and PNG decoding.
Optional OCR module
native/ocr/*, native/CMakeLists.txt, native/build-real.sh
The optional module adds a versioned OCR API, digest-pinned profiles and ONNX Runtime assets, OCR processing, packaging, and native tests.
Java workflows and validation
jpdfium/src/main/java/stirling/software/jpdfium/*, jpdfium/src/test/*, .github/*, docs/*
Merge and split use staged output and durable publication. Redaction, text parsing, page geometry, runtime bindings, tests, CI checks, notices, and design documentation also change.

Priority: ➖ Normal

Merge Risk: 🔵 Low · up to 590bd

The change is broad but mostly sound. A few native edge cases remain: an unexpected exception while saving to bytes can terminate the process, some valid PNG loads use extra memory, and there is minor OCR parity drift and documentation inaccuracy. These are worth fixing soon but are not likely to cause widespread failures.

Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Description check Warning The description gives a detailed summary, testing claims, and notes, but it omits the required Checklist section and contains inconsistencies. The description states API version 1.4 and references des… Add the complete repository checklist with accurate selections. Correct the API version to 1.5, update the design-document references to match the changes, and ensure all testing and compatibility claims match the submitted files and execut…
Passed Passed checks: 3 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly summarizes the primary changes: the native-first safe JPDF API, OCR module, and text-layer writer.
Full details: Description check

Explanation

The description gives a detailed summary, testing claims, and notes, but it omits the required Checklist section and contains inconsistencies. The description states API version 1.4 and references design files not shown in the changes, while the changes indicate API version 1.5 and only different design files.

Resolution

Add the complete repository checklist with accurate selections. Correct the API version to 1.5, update the design-document references to match the changes, and ensure all testing and compatibility claims match the submitted files and executed commands.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread native/bridge/src/output/output_transaction.cpp Fixed
Comment thread native/bridge/tests/api_guards.cpp Fixed
Comment thread native/bridge/src/pdf/api_text.cpp Fixed
Comment thread native/bridge/src/textlayer/text_layer.cpp Fixed
Comment thread native/bridge/tests/api_text_layer.cpp Fixed
@balazs-szucs
balazs-szucs force-pushed the feat/native-safe-domain branch from 4c16c24 to ba5903b Compare October 11, 2026 18:41

@coderabbitai coderabbitai 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.

Actionable comments posted: 14


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: Stirling-Tools/JPDFium/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 9f3402db-0fd8-4474-bdf5-abe9a841e39e
📥 Commits

Reviewing files that changed from the base of the PR and between 0d0945a and ba5903b.

📒 Files selected for processing (99)
  • .github/scripts/check-native-symbols.sh
  • .github/workflows/corpus.yml
  • .gitignore
  • NOTICE
  • docs/concurrency.md
  • docs/configuration.md
  • docs/design/DESIGN.md
  • docs/design/JAVA_MIGRATION.md
  • docs/design/JAVA_MIGRATION_INVENTORY.md
  • jpdfium/build.gradle.kts
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/PdfiumDomainBenchmark.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/FastLinks.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/FontLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/NativeDomain.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/PdfiumRuntime.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/Symbols.java
  • jpdfium/src/main/resources/META-INF/native-image/com.stirling/jpdfium/reachability-metadata.json
  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/AbiHandshakeTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainConsistencyTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainEntryStackTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainLeakTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/FastLinkFallbackTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/NestedTeardownContextTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/PdfiumRuntimeTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/RuntimeShutdownTest.java
  • native/CMakeLists.txt
  • native/bridge/include/jpdfium.h
  • native/bridge/include/jpdfium_api.h
  • native/bridge/include/jpdfium_core.h
  • native/bridge/include/jpdfium_internal.h
  • native/bridge/src/images/api_bitmap.cpp
  • native/bridge/src/images/pixels.cpp
  • native/bridge/src/images/pixels.h
  • native/bridge/src/jpdfium_document.cpp
  • native/bridge/src/jpdfium_render.cpp
  • native/bridge/src/legacy/guards_bridge.cpp
  • native/bridge/src/legacy/guards_pdfium.cpp
  • native/bridge/src/objects/module_objects.h
  • native/bridge/src/objects/object_table.h
  • native/bridge/src/objects/objects.cpp
  • native/bridge/src/objects/objects.h
  • native/bridge/src/output/image_writer.cpp
  • native/bridge/src/output/image_writer.h
  • native/bridge/src/output/output_transaction.cpp
  • native/bridge/src/output/output_transaction.h
  • native/bridge/src/pdf/api_document.cpp
  • native/bridge/src/pdf/api_raster.cpp
  • native/bridge/src/pdf/api_render.cpp
  • native/bridge/src/pdf/api_text.cpp
  • native/bridge/src/runtime/api_module.cpp
  • native/bridge/src/runtime/api_runtime.cpp
  • native/bridge/src/runtime/api_status.cpp
  • native/bridge/src/runtime/api_status.h
  • native/bridge/src/runtime/domain.cpp
  • native/bridge/src/runtime/domain.h
  • native/bridge/src/runtime/guard.cpp
  • native/bridge/src/runtime/guard.h
  • native/bridge/src/runtime/pdfium_core_stub.cpp
  • native/bridge/src/textlayer/api_text_layer.cpp
  • native/bridge/src/textlayer/text_layer.cpp
  • native/bridge/src/textlayer/text_layer.h
  • native/bridge/tests/api_guards.cpp
  • native/bridge/tests/api_image.cpp
  • native/bridge/tests/api_object_table.cpp
  • native/bridge/tests/api_raster.cpp
  • native/bridge/tests/api_safety.cpp
  • native/bridge/tests/api_text_layer.cpp
  • native/build-real.sh
  • native/licenses/CLIPPER-BSL-1.0.txt
  • native/ocr/fetch-onnxruntime.sh
  • native/ocr/include/jpdfium_ocr.h
  • native/ocr/onnxruntime.version
  • native/ocr/profiles/pp-ocrv6-small-balanced.profile
  • native/ocr/profiles/pp-ocrv6-small.profile
  • native/ocr/src/api_ocr.cpp
  • native/ocr/src/cv_compat.cpp
  • native/ocr/src/cv_compat.h
  • native/ocr/src/engine.cpp
  • native/ocr/src/engine.h
  • native/ocr/src/ort_session.cpp
  • native/ocr/src/ort_session.h
  • native/ocr/src/paddle.cpp
  • native/ocr/src/paddle.h
  • native/ocr/src/profile.cpp
  • native/ocr/src/sha256.cpp
  • native/ocr/tests/lsan.supp
  • native/ocr/tests/make_golden.py
  • native/ocr/tests/ocr_engine.cpp
  • native/ocr/tests/ocr_geometry.cpp
  • native/ocr/tests/ocr_golden.inc
  • native/ocr/tests/tsan.supp
  • native/ocr/tools/fetch_profile.py
  • native/rust/jpdfium-impl/Cargo.toml
  • native/rust/jpdfium-impl/src/lib.rs
  • native/tools/downcall_inventory.py
  • native/tools/gen_guards.py
💤 Files with no reviewable changes (3)
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainEntryStackTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainLeakTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/NestedTeardownContextTest.java

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Review details
⏰ Context from checks skipped due to timeout. (13)
  • GitHub Check: build-natives (darwin-x64, macos-15-intel)
  • GitHub Check: build-natives (linux-x64, ubuntu-latest)
  • GitHub Check: build-natives (windows-x64, windows-latest)
  • GitHub Check: build-natives (windows-arm64, windows-11-arm)
  • GitHub Check: build-natives (darwin-arm64, macos-14)
  • GitHub Check: build-natives (linux-arm64, ubuntu-24.04-arm)
  • GitHub Check: Corpus tests (shard 1/4)
  • GitHub Check: Corpus tests (shard 0/4)
  • GitHub Check: Corpus tests (shard 3/4)
  • GitHub Check: Corpus tests (shard 2/4)
  • GitHub Check: Native bridge libFuzzer (ASan/UBSan, real PDFium)
  • GitHub Check: CLI correctness & no-corruption tests
  • GitHub Check: JMH Benchmarks (FFM Downcall Overhead Gate)
🧰 Additional context used
📚 Code guidelines (1)
.github/CODERABBIT_REVIEW.md — configured
📓 Path-based instructions (5)
Apply the native ownership, C ABI, C++23, engine integration, memory, and SIMD rules from .github/CODERABBIT_REVIEW.md.

⚙️ CodeRabbit configuration file

Files:

  • native/bridge/include/jpdfium_internal.h
  • native/bridge/src/jpdfium_render.cpp
  • native/bridge/src/objects/objects.cpp
  • native/bridge/src/textlayer/api_text_layer.cpp
  • native/bridge/src/objects/module_objects.h
  • native/bridge/src/runtime/guard.h
  • native/ocr/src/sha256.cpp
  • native/bridge/src/runtime/pdfium_core_stub.cpp
  • native/ocr/tests/ocr_geometry.cpp
  • native/bridge/include/jpdfium_core.h
  • native/bridge/src/output/output_transaction.h
  • native/bridge/src/runtime/guard.cpp
  • native/ocr/src/engine.cpp
  • native/bridge/tests/api_raster.cpp
  • native/bridge/include/jpdfium.h
  • native/bridge/src/pdf/api_text.cpp
  • native/bridge/src/images/pixels.h
  • native/ocr/tests/ocr_engine.cpp
  • native/bridge/src/runtime/api_status.h
  • native/bridge/src/runtime/domain.h
  • native/bridge/src/jpdfium_document.cpp
  • native/bridge/src/runtime/domain.cpp
  • native/bridge/tests/api_object_table.cpp
  • native/bridge/tests/api_safety.cpp
  • native/bridge/tests/api_image.cpp
  • native/ocr/src/ort_session.h
  • native/bridge/src/output/output_transaction.cpp
  • native/bridge/src/runtime/api_status.cpp
  • native/ocr/src/profile.cpp
  • native/bridge/src/runtime/api_module.cpp
  • native/bridge/src/images/pixels.cpp
  • native/bridge/src/pdf/api_raster.cpp
  • native/ocr/src/paddle.h
  • native/bridge/src/pdf/api_render.cpp
  • native/bridge/src/textlayer/text_layer.h
  • native/bridge/src/pdf/api_document.cpp
  • native/bridge/tests/api_guards.cpp
  • native/ocr/src/api_ocr.cpp
  • native/bridge/src/runtime/api_runtime.cpp
  • native/ocr/src/ort_session.cpp
  • native/bridge/src/objects/objects.h
  • native/ocr/src/cv_compat.h
  • native/ocr/src/engine.h
  • native/bridge/src/output/image_writer.cpp
  • native/bridge/tests/api_text_layer.cpp
  • native/ocr/include/jpdfium_ocr.h
  • native/ocr/src/paddle.cpp
  • native/bridge/src/output/image_writer.h
  • native/ocr/src/cv_compat.cpp
  • native/bridge/src/images/api_bitmap.cpp
  • native/bridge/src/objects/object_table.h
  • native/bridge/include/jpdfium_api.h
  • native/bridge/src/textlayer/text_layer.cpp
  • native/bridge/src/legacy/guards_bridge.cpp
Check target-scoped flags, exported ABI, reproducibility, sanitizer instrumentation, dependency compatibility, and portable CPU targets.

⚙️ CodeRabbit configuration file

Files:

  • native/CMakeLists.txt
Enforce meaningful assertions, deterministic concurrency, failure-path cleanup, and explicit native/stub requirements.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/panama/RuntimeShutdownTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/FastLinkFallbackTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/AbiHandshakeTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainConsistencyTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/PdfiumRuntimeTest.java
Apply the Java 25 and FFM rules from .github/CODERABBIT_REVIEW.md.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/main/java/stirling/software/jpdfium/panama/FontLib.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/RuntimeShutdownTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/PdfiumDomainBenchmark.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/FastLinkFallbackTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/FastLinks.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/AbiHandshakeTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/Symbols.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainConsistencyTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/NativeDomain.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/PdfiumRuntime.java
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/PdfiumRuntimeTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
Source excerpt: Use imports rather than package-qualified type names in method bodies and signatures.

📄 CodeRabbit inference engine (.github/CODERABBIT_REVIEW.md)

Files:

  • native/ocr/tests/tsan.supp
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/FontLib.java
  • docs/configuration.md
  • docs/design/JAVA_MIGRATION_INVENTORY.md
  • native/bridge/include/jpdfium_internal.h
  • native/bridge/src/jpdfium_render.cpp
  • native/rust/jpdfium-impl/Cargo.toml
  • docs/concurrency.md
  • native/licenses/CLIPPER-BSL-1.0.txt
  • native/ocr/onnxruntime.version
  • docs/design/DESIGN.md
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/RuntimeShutdownTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • native/bridge/src/objects/objects.cpp
  • NOTICE
  • native/ocr/tests/ocr_golden.inc
  • native/build-real.sh
  • native/ocr/profiles/pp-ocrv6-small.profile
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/PdfiumDomainBenchmark.java
  • jpdfium/build.gradle.kts
  • native/bridge/src/textlayer/api_text_layer.cpp
  • native/bridge/src/objects/module_objects.h
  • native/bridge/src/runtime/guard.h
  • native/ocr/src/sha256.cpp
  • native/ocr/profiles/pp-ocrv6-small-balanced.profile
  • native/ocr/fetch-onnxruntime.sh
  • native/bridge/src/runtime/pdfium_core_stub.cpp
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/FastLinkFallbackTest.java
  • native/ocr/tests/ocr_geometry.cpp
  • native/bridge/include/jpdfium_core.h
  • jpdfium/src/main/resources/META-INF/native-image/com.stirling/jpdfium/reachability-metadata.json
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/FastLinks.java
  • native/ocr/tests/lsan.supp
  • docs/design/JAVA_MIGRATION.md
  • native/bridge/src/output/output_transaction.h
  • native/bridge/src/runtime/guard.cpp
  • native/ocr/src/engine.cpp
  • native/bridge/tests/api_raster.cpp
  • native/bridge/include/jpdfium.h
  • native/bridge/src/pdf/api_text.cpp
  • native/bridge/src/images/pixels.h
  • native/ocr/tests/ocr_engine.cpp
  • native/bridge/src/runtime/api_status.h
  • native/bridge/src/runtime/domain.h
  • native/tools/downcall_inventory.py
  • native/bridge/src/jpdfium_document.cpp
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/AbiHandshakeTest.java
  • native/bridge/src/runtime/domain.cpp
  • native/bridge/tests/api_object_table.cpp
  • native/bridge/tests/api_safety.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/Symbols.java
  • native/bridge/tests/api_image.cpp
  • native/ocr/src/ort_session.h
  • native/bridge/src/output/output_transaction.cpp
  • native/bridge/src/runtime/api_status.cpp
  • native/ocr/src/profile.cpp
  • native/bridge/src/runtime/api_module.cpp
  • native/bridge/src/images/pixels.cpp
  • native/bridge/src/pdf/api_raster.cpp
  • native/ocr/src/paddle.h
  • native/bridge/src/pdf/api_render.cpp
  • native/bridge/src/textlayer/text_layer.h
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainConsistencyTest.java
  • native/bridge/src/pdf/api_document.cpp
  • native/bridge/tests/api_guards.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/NativeDomain.java
  • native/ocr/src/api_ocr.cpp
  • native/bridge/src/runtime/api_runtime.cpp
  • native/CMakeLists.txt
  • native/ocr/tools/fetch_profile.py
  • native/ocr/src/ort_session.cpp
  • native/bridge/src/objects/objects.h
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • native/ocr/src/cv_compat.h
  • native/ocr/src/engine.h
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/PdfiumRuntime.java
  • native/bridge/src/output/image_writer.cpp
  • native/bridge/tests/api_text_layer.cpp
  • native/ocr/tests/make_golden.py
  • native/ocr/include/jpdfium_ocr.h
  • native/ocr/src/paddle.cpp
  • native/bridge/src/output/image_writer.h
  • native/tools/gen_guards.py
  • native/ocr/src/cv_compat.cpp
  • native/rust/jpdfium-impl/src/lib.rs
  • native/bridge/src/images/api_bitmap.cpp
  • native/bridge/src/objects/object_table.h
  • native/bridge/include/jpdfium_api.h
  • jpdfium/src/test/java/stirling/software/jpdfium/panama/PdfiumRuntimeTest.java
  • native/bridge/src/textlayer/text_layer.cpp
  • native/bridge/src/legacy/guards_bridge.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
🪛 ast-grep (0.45.3)
native/tools/downcall_inventory.py

[warning] 79-79: XPath query is request-/variable-derived; use parameterized XPath to prevent injection.
Context: DOWNCALL.findall(text)
Note: [CWE-643] Improper Neutralization of Data within XPath Expressions ('XPath Injection').

(xpath-injection-python)


[warning] 81-81: XPath query is request-/variable-derived; use parameterized XPath to prevent injection.
Context: JEXTRACT.findall(text)
Note: [CWE-643] Improper Neutralization of Data within XPath Expressions ('XPath Injection').

(xpath-injection-python)

native/ocr/tools/fetch_profile.py

[warning] 69-69: Request-controlled URL passed to urlopen; validate against an allowlist to prevent SSRF.
Context: urllib.request.urlopen(url, timeout=120)
Note: [CWE-918] Server-Side Request Forgery (SSRF).

(urlopen-unsanitized-data)

native/tools/gen_guards.py

[warning] 148-148: Regex pattern passed to re is built from a non-literal (variable, call, concatenation, or f-string) value. If that value is attacker-controlled it can introduce a malicious pattern with catastrophic backtracking (ReDoS). Use a hardcoded literal pattern, or validate/escape untrusted input with re.escape() and bound the regex complexity before compiling.
Context: re.search(r"\b%s\s*([^;{])\s(noexcept|JPDFIUM_NOEXCEPT)?\s*{" % name, stub)
Note: [CWE-1333] Inefficient Regular Expression Complexity.

(redos-non-literal-regex-python)


[error] 180-180: Command coming from incoming request
Context: subprocess.run(["clang-format", "-i", str(OUT_BRIDGE), str(OUT_PDFIUM)], check=True)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

🪛 Clippy (1.98.1)
native/rust/jpdfium-impl/src/lib.rs

[warning] 735-735: this function has too many arguments (8/7)

(warning)

🪛 LanguageTool
docs/design/JAVA_MIGRATION.md

[grammar] ~57-~57: Use a hyphen to join words.
Context: ...diting, save, redaction) each get coarse safe operations, one family per chang...

(QB_NEW_EN_HYPHEN)

🪛 Ruff (0.16.8)
native/tools/downcall_inventory.py

[warning] 94-96: Unparenthesized implicit string concatenation in collection

Did you forget a comma?

(ISC004)


[warning] 98-101: Unparenthesized implicit string concatenation in collection

Did you forget a comma?

(ISC004)

native/ocr/tools/fetch_profile.py

[warning] 44-44: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 47-47: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 50-50: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 69-70: Use a single with statement with multiple contexts instead of nested with statements

(SIM117)


[warning] 75-75: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 85-85: Avoid specifying long messages outside the exception class

(TRY003)

native/tools/gen_guards.py

[warning] 68-68: for loop variable param overwritten by assignment target

(PLW2901)


[warning] 148-148: Use format specifiers instead of percent format

Replace with format specifiers

(UP031)


[error] 180-180: subprocess call: check for execution of untrusted input

(S603)


[error] 180-180: Starting a process with a partial executable path

(S607)

🔇 Additional comments (81)
native/bridge/src/pdf/api_document.cpp (1)

25-156: LGTM!

native/bridge/src/pdf/api_render.cpp (1)

1-189: LGTM!

native/bridge/src/pdf/api_raster.cpp (1)

1-311: LGTM!

native/bridge/src/pdf/api_text.cpp (1)

1-105: LGTM!

native/bridge/src/images/pixels.h (1)

1-41: LGTM!

native/bridge/src/images/pixels.cpp (1)

14-74: LGTM!

native/bridge/src/output/image_writer.cpp (1)

16-115: LGTM!

native/bridge/src/output/image_writer.h (1)

1-74: LGTM!

native/bridge/tests/api_safety.cpp (1)

1-487: LGTM!

native/bridge/tests/api_text_layer.cpp (1)

1-592: LGTM!

native/bridge/tests/api_image.cpp (1)

1-203: LGTM!

native/bridge/tests/api_raster.cpp (1)

1-348: LGTM!

native/bridge/src/textlayer/api_text_layer.cpp (1)

12-32: LGTM!

native/bridge/src/textlayer/text_layer.cpp (1)

1-1216: LGTM!

native/bridge/src/textlayer/text_layer.h (1)

1-73: LGTM!

native/rust/jpdfium-impl/Cargo.toml (1)

16-17: LGTM!

native/bridge/src/output/output_transaction.h (1)

1-57: LGTM!

native/build-real.sh (1)

37-41: LGTM!

.gitignore (1)

80-80: LGTM!

NOTICE (1)

46-56: LGTM!

native/licenses/CLIPPER-BSL-1.0.txt (1)

1-26: LGTM!

native/ocr/fetch-onnxruntime.sh (1)

1-46: LGTM!

native/ocr/include/jpdfium_ocr.h (1)

1-103: LGTM!

native/ocr/onnxruntime.version (1)

1-8: LGTM!

native/ocr/profiles/pp-ocrv6-small-balanced.profile (1)

1-20: LGTM!

native/ocr/profiles/pp-ocrv6-small.profile (1)

1-20: LGTM!

native/ocr/src/api_ocr.cpp (2)

134-318: LGTM!


102-110: 🎯 Functional Correctness

No unsupported pixel format reaches read_bitmap.

The API defines only JPDF_PIXEL_RGBA8, JPDF_PIXEL_RGB8, and JPDF_PIXEL_GRAY8. read_bitmap converts each format correctly to BGR. Rendered and decoded bitmaps validate or assign one of these formats, and rectification preserves the source format. The proposed BGR and larger-pixel cases do not exist in this API.

native/ocr/src/cv_compat.cpp (1)

106-417: LGTM!

Also applies to: 419-713, 719-925

native/ocr/src/engine.cpp (1)

16-127: LGTM!

native/ocr/src/engine.h (1)

1-79: LGTM!

native/ocr/src/ort_session.cpp (1)

1-161: LGTM!

native/ocr/src/ort_session.h (1)

1-44: LGTM!

native/ocr/src/paddle.cpp (1)

1-467: LGTM!

native/ocr/src/paddle.h (1)

1-96: LGTM!

native/ocr/src/profile.cpp (1)

1-183: LGTM!

native/ocr/src/sha256.cpp (1)

1-106: LGTM!

native/ocr/tests/lsan.supp (1)

1-2: LGTM!

native/ocr/tests/make_golden.py (1)

1-120: LGTM!

native/ocr/tests/ocr_engine.cpp (1)

1-220: LGTM!

native/ocr/tests/ocr_geometry.cpp (1)

1-243: LGTM!

native/ocr/tests/ocr_golden.inc (1)

1-36: LGTM!

native/ocr/tests/tsan.supp (1)

1-2: LGTM!

native/ocr/tools/fetch_profile.py (1)

1-93: LGTM!

jpdfium/build.gradle.kts (1)

370-375: LGTM!

Also applies to: 390-392, 409-414

jpdfium/src/main/java/stirling/software/jpdfium/panama/FastLinks.java (1)

27-29: LGTM!

Also applies to: 50-51, 67-70

jpdfium/src/main/java/stirling/software/jpdfium/panama/FontLib.java (1)

5-5: LGTM!

Also applies to: 27-28

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java (1)

16-18: LGTM!

Also applies to: 44-46

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java (1)

76-88: LGTM!

Also applies to: 97-98, 130-130

jpdfium/src/main/java/stirling/software/jpdfium/panama/NativeDomain.java (1)

1-322: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/panama/PdfiumRuntime.java (2)

108-142: LGTM!

Also applies to: 206-212


69-106: 🩺 Stability & Availability

Do not require a single-entry render wrapper for this path.

PdfiumRuntime requires documents to be used by one thread at a time. No Java Cleaner or finalizer path closes these resources. A concurrent close or structural mutation therefore violates the documented threading contract. The stale-pointer behavior may occur under unsupported concurrent use, but it is not an actionable defect in the supported API.

jpdfium/src/main/java/stirling/software/jpdfium/panama/Symbols.java (1)

18-20: LGTM!

Also applies to: 51-89, 101-101, 111-111

jpdfium/src/main/resources/META-INF/native-image/com.stirling/jpdfium/reachability-metadata.json (1)

156-166: LGTM!

Also applies to: 232-246

jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java (1)

320-328: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/panama/AbiHandshakeTest.java (1)

14-71: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/panama/DomainConsistencyTest.java (1)

77-114: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/panama/FastLinkFallbackTest.java (1)

10-11: LGTM!

Also applies to: 33-44

jpdfium/src/test/java/stirling/software/jpdfium/panama/PdfiumRuntimeTest.java (1)

8-149: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/panama/RuntimeShutdownTest.java (1)

16-16: LGTM!

Also applies to: 27-27

native/CMakeLists.txt (1)

120-153: LGTM!

Also applies to: 234-253, 690-749, 782-785, 833-895

native/bridge/src/runtime/pdfium_core_stub.cpp (1)

1-26: LGTM!

native/bridge/src/objects/objects.cpp (1)

1-16: LGTM!

native/bridge/src/objects/objects.h (1)

1-75: LGTM!

native/bridge/src/objects/module_objects.h (1)

1-32: LGTM!

native/bridge/src/runtime/domain.h (1)

1-97: LGTM!

native/bridge/src/runtime/guard.h (1)

1-28: LGTM!

native/tools/gen_guards.py (1)

1-188: LGTM!

native/bridge/src/legacy/guards_bridge.cpp (1)

1-693: LGTM!

native/bridge/src/jpdfium_document.cpp (1)

223-238: LGTM!

Also applies to: 331-335

native/bridge/src/jpdfium_render.cpp (1)

284-288: LGTM!

native/bridge/tests/api_guards.cpp (1)

1-290: LGTM!

native/bridge/include/jpdfium.h (1)

53-54: LGTM!

Also applies to: 101-104

native/bridge/include/jpdfium_api.h (1)

1-433: LGTM!

native/bridge/include/jpdfium_core.h (1)

1-13: LGTM!

native/bridge/include/jpdfium_internal.h (1)

22-22: LGTM!

Also applies to: 378-381

native/bridge/src/runtime/api_status.cpp (1)

1-66: LGTM!

native/bridge/src/runtime/api_status.h (1)

1-41: LGTM!

native/bridge/src/objects/object_table.h (1)

1-170: LGTM!

native/bridge/src/runtime/api_runtime.cpp (1)

1-207: LGTM!

native/bridge/tests/api_object_table.cpp (1)

1-143: LGTM!

Comment thread .github/scripts/check-native-symbols.sh Outdated
Comment thread docs/design/DESIGN.md Outdated
Comment thread native/bridge/src/images/api_bitmap.cpp Outdated
Comment thread native/bridge/src/images/api_bitmap.cpp
Comment thread native/bridge/src/runtime/guard.cpp
Comment thread native/build-real.sh
Comment thread native/ocr/src/cv_compat.cpp Outdated
Comment thread native/rust/jpdfium-impl/src/lib.rs Outdated
Comment thread native/tools/downcall_inventory.py Outdated
@balazs-szucs
balazs-szucs force-pushed the feat/native-safe-domain branch from ba5903b to 5258f03 Compare October 11, 2026 19:18

@coderabbitai coderabbitai 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.

Actionable comments posted: 5


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: Stirling-Tools/JPDFium/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 34f2e118-3eab-4c6c-9e2c-d07fdb63a46b
📥 Commits

Reviewing files that changed from the base of the PR and between ba5903b and 3ef95c0.

📒 Files selected for processing (18)
  • .github/scripts/check-native-symbols.sh
  • .github/workflows/ci.yml
  • docs/concurrency.md
  • docs/design/DESIGN.md
  • docs/design/JAVA_MIGRATION_INVENTORY.md
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/PdfiumDomainBenchmark.java
  • native/bridge/src/images/api_bitmap.cpp
  • native/bridge/src/jpdfium_document.cpp
  • native/bridge/src/jpdfium_image.cpp
  • native/bridge/src/output/output_transaction.cpp
  • native/bridge/src/runtime/api_module.cpp
  • native/bridge/src/runtime/guard.cpp
  • native/build-real.sh
  • native/ocr/src/cv_compat.cpp
  • native/ocr/src/engine.h
  • native/ocr/src/ort_session.cpp
  • native/rust/jpdfium-impl/src/lib.rs
  • native/tools/downcall_inventory.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Review details
⏰ Context from checks skipped due to timeout. (15)
  • GitHub Check: Native bridge libFuzzer (ASan/UBSan, real PDFium)
  • GitHub Check: CLI correctness & no-corruption tests
  • GitHub Check: Flaky-test guard (3× rerun)
  • GitHub Check: Build & Verify (Compilation) (windows-latest)
  • GitHub Check: GraalVM Native Image Smoke & E2E Test (Linux x64)
  • GitHub Check: CodeQL Analysis (java-kotlin)
  • GitHub Check: Java - SpotBugs + Checkstyle + PMD + Spotless
  • GitHub Check: JMH Benchmarks (FFM Downcall Overhead Gate)
  • GitHub Check: Samples E2E Suite (All 88 Feature Samples)
  • GitHub Check: Samples E2E (88 features via RunAllSamples)
  • GitHub Check: Corpus (generate + native)
  • GitHub Check: build-natives (windows-arm64, windows-11-arm)
  • GitHub Check: build-natives (windows-x64, windows-latest)
  • GitHub Check: Restricted-env compat (no execstack + hermetic bundle)
  • GitHub Check: CodeQL Analysis (c-cpp)
🧰 Additional context used
📚 Code guidelines (1)
.github/CODERABBIT_REVIEW.md — configured
📓 Path-based instructions (3)
Apply the native ownership, C ABI, C++23, engine integration, memory, and SIMD rules from .github/CODERABBIT_REVIEW.md.

⚙️ CodeRabbit configuration file

Files:

  • native/ocr/src/ort_session.cpp
  • native/bridge/src/runtime/guard.cpp
  • native/bridge/src/jpdfium_image.cpp
  • native/bridge/src/output/output_transaction.cpp
  • native/ocr/src/cv_compat.cpp
  • native/bridge/src/runtime/api_module.cpp
  • native/bridge/src/images/api_bitmap.cpp
  • native/bridge/src/jpdfium_document.cpp
  • native/ocr/src/engine.h
Apply the Java 25 and FFM rules from .github/CODERABBIT_REVIEW.md.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/PdfiumDomainBenchmark.java
Source excerpt: Use imports rather than package-qualified type names in method bodies and signatures.

📄 CodeRabbit inference engine (.github/CODERABBIT_REVIEW.md)

Files:

  • docs/design/DESIGN.md
  • docs/design/JAVA_MIGRATION_INVENTORY.md
  • native/ocr/src/ort_session.cpp
  • native/bridge/src/runtime/guard.cpp
  • native/bridge/src/jpdfium_image.cpp
  • native/bridge/src/output/output_transaction.cpp
  • docs/concurrency.md
  • native/build-real.sh
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/PdfiumDomainBenchmark.java
  • native/ocr/src/cv_compat.cpp
  • native/tools/downcall_inventory.py
  • native/bridge/src/runtime/api_module.cpp
  • native/bridge/src/images/api_bitmap.cpp
  • native/bridge/src/jpdfium_document.cpp
  • native/ocr/src/engine.h
  • native/rust/jpdfium-impl/src/lib.rs
🪛 ast-grep (0.45.3)
native/tools/downcall_inventory.py

[warning] 79-79: XPath query is request-/variable-derived; use parameterized XPath to prevent injection.
Context: DOWNCALL.findall(text)
Note: [CWE-643] Improper Neutralization of Data within XPath Expressions ('XPath Injection').

(xpath-injection-python)


[warning] 81-81: XPath query is request-/variable-derived; use parameterized XPath to prevent injection.
Context: JEXTRACT.findall(text)
Note: [CWE-643] Improper Neutralization of Data within XPath Expressions ('XPath Injection').

(xpath-injection-python)

🪛 Clippy (1.98.1)
native/rust/jpdfium-impl/src/lib.rs

[warning] 735-735: this function has too many arguments (8/7)

(warning)

🪛 Ruff (0.16.8)
native/tools/downcall_inventory.py

[warning] 94-96: Unparenthesized implicit string concatenation in collection

Did you forget a comma?

(ISC004)


[warning] 98-101: Unparenthesized implicit string concatenation in collection

Did you forget a comma?

(ISC004)

🔇 Additional comments (11)
native/build-real.sh (1)

61-85: LGTM!

native/ocr/src/cv_compat.cpp (1)

1-927: LGTM!

native/tools/downcall_inventory.py (1)

1-120: LGTM!

native/ocr/src/ort_session.cpp (1)

1-161: LGTM!

native/ocr/src/engine.h (1)

1-113: LGTM!

native/bridge/src/runtime/guard.cpp (1)

14-15: LGTM!

Also applies to: 18-21, 28-31

native/bridge/src/jpdfium_document.cpp (1)

332-333: 🎯 Functional Correctness

The authority is intentionally process-scoped. jpdfium_core.h states that the first authority claim wins for the process lifetime. The safe runtime is also documented as final after shutdown, and jpdf_runtime_init() rejects an existing legacy owner. Therefore, switching from the legacy bridge to the safe runtime after jpdfium_destroy() is not a supported transition, so clearing g_pdfiumAuthority would violate the ownership contract.

native/bridge/src/images/api_bitmap.cpp (1)

1-257: LGTM!

Also applies to: 285-512

native/bridge/src/output/output_transaction.cpp (2)

1-101: LGTM!

Also applies to: 108-218, 248-265


219-246: 🗄️ Data Integrity & Integration

Do not treat the Windows durable path as equivalent to POSIX file-and-directory sync.

finalize() flushes the staging-file contents on Windows with _commit when durable_ is enabled. However, publish() relies on MoveFileExW(..., MOVEFILE_WRITE_THROUGH), whose documented durability guarantee does not clearly cover same-volume rename metadata. JPDF_WRITE_DURABLE may therefore return JPDF_OK without establishing that the replacement survives power loss. Use a documented Windows mechanism for durable publication, or narrow the durability guarantee.

native/rust/jpdfium-impl/src/lib.rs (1)

635-678: LGTM!

Also applies to: 698-909, 911-1063

Comment thread jpdfium/src/jmh/java/stirling/software/jpdfium/bench/PdfiumDomainBenchmark.java Outdated
Comment thread native/bridge/src/images/api_bitmap.cpp Outdated
Comment thread native/bridge/src/output/output_transaction.cpp
Comment thread native/rust/jpdfium-impl/src/lib.rs
Comment thread native/rust/jpdfium-impl/src/lib.rs Outdated
@balazs-szucs
balazs-szucs force-pushed the feat/native-safe-domain branch from 2d066ce to c0d09c9 Compare October 11, 2026 22:43
Comment thread jpdfium/src/main/java/stirling/software/jpdfium/doc/PdfLinks.java Fixed
while (end < json.length() && (json.charAt(end) == '-' || Character.isDigit(json.charAt(end)))) end++;
if (end == idx) return 0;
return Integer.parseInt(json.substring(idx, end));
return Integer.parseInt(json, idx, end, 10);
…main

Resolve the 20261019 PDFium pin bump against the native safe-domain work: adopt EPDFPage_ApplyRedactions while keeping the RAII text/annotation handles, retain both exact-export checking and nm retries, keep both member-level API exclusions and both new downcall metadata entries, restore the Arena import used by the rotation lookup, and regenerate the legacy PDFium guards against the new headers.
Track every long-lived PDFium handle type in shutdown accounting and fail guard generation when an open/close pair is missing or unbalanced. Register document and page identity so a raw close and a bridge close cannot decrement twice.

Only consult the guard refusal after a zero result (always for void), and remove the misleading downcallCritical alias. Replace std::timed_mutex with a plain mutex and a try_lock backoff, with shutdown taking the same bounded wait.

Use ONNX Runtime global thread pools with per-session threads disabled, disable spinning, memory patterns and the session arena. Pin shipped OCR profiles to compiled-in SHA-256 digests, accept a caller-supplied digest for custom profiles, and refuse duplicate profile roles. Specialize the OCR bitmap conversion per pixel format.

Make durable output use F_FULLFSYNC on macOS, report the Windows MoveFileExW error, remove stale staging files from dead processes, and document that publication does not preserve hard links, ACLs, xattrs or ownership. Update the design notes and Java downcall inventory.
Symbols.downcallCritical is part of the released Java surface; japicmp refuses its removal. Keep it as a deprecated alias of downcall for binary compatibility while every binding uses the clearer name.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants