Skip to content

Flatten whole documents in one native pass and reuse the render bitmap - #162

Open
balazs-szucs wants to merge 32 commits into
Stirling-Tools:mainfrom
balazs-szucs:perf/flatten-file-backed
Open

balazs-szucs wants to merge 32 commits into
Stirling-Tools:mainfrom
balazs-szucs:perf/flatten-file-backed

Conversation

@balazs-szucs

Copy link
Copy Markdown
Collaborator

No description provided.

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

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
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: Stirling-Tools/JPDFium/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0f9b0c8b-a1f0-41cb-96b8-110b277dcb3e
📥 Commits

Reviewing files that changed from the base of the PR and between d6d1d0b and d101c5b.

📒 Files selected for processing: 14
  • jpdfium/build.gradle.kts
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfPage.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/exception/JPDFiumException.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • native/bridge/include/jpdfium.h
  • native/bridge/include/jpdfium_internal.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/src/jpdfium_render.cpp

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

📜 Recent review details
⏰ Context from checks skipped due to timeout: 14
  • GitHub Check: Preflight - pinned PDFium release assets
  • GitHub Check: prep-windows-icu
  • GitHub Check: Flaky-test guard (3× rerun)
  • GitHub Check: Samples E2E Suite (All 88 Feature Samples)
  • GitHub Check: GraalVM Native Image Smoke & E2E Test (Linux x64)
  • GitHub Check: JMH Benchmarks (FFM Downcall Overhead Gate)
  • GitHub Check: Samples E2E (88 features via RunAllSamples)
  • GitHub Check: Native bridge libFuzzer (ASan/UBSan, real PDFium)
  • GitHub Check: CodeQL Analysis (java-kotlin)
  • GitHub Check: CodeQL (java-kotlin)
  • GitHub Check: Java - SpotBugs + Checkstyle + PMD + Spotless
  • GitHub Check: build-natives (darwin-x64, macos-15-intel)
  • GitHub Check: build-natives (windows-arm64, windows-11-arm)
  • GitHub Check: build-natives (windows-x64, windows-latest)
⚠️ CI failures not shown inline: 8

GitHub Actions: CLI / 0_CLI correctness & no-corruption tests.txt: Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

##[group]Run bash native/build-real.sh
 �[36;1mbash native/build-real.sh�[0m
 shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
 env:
   GRAALVM_HOME: /opt/hostedtoolcache/graalvm-jdk-25_linux-x64_bin/25.0.0/x64/graalvm-jdk-25.0.4+7.1
   JAVA_HOME: /opt/hostedtoolcache/graalvm-jdk-25_linux-x64_bin/25.0.0/x64/graalvm-jdk-25.0.4+7.1
   NATIVE_IMAGE_OPTIONS: -H:BuildOutputJSONFile=/tmp/native-image-build-output.json
   GRADLE_ACTION_ID: gradle/actions/setup-gradle
   GRADLE_USER_HOME: /home/runner/.gradle
   GRADLE_BUILD_ACTION_SETUP_COMPLETED: true
   DEVELOCITY_INJECTION_INIT_SCRIPT_NAME: gradle-actions.inject-develocity.init.gradle
   DEVELOCITY_INJECTION_CUSTOM_VALUE: gradle-actions
   GITHUB_DEPENDENCY_GRAPH_ENABLED: false
 ##[endgroup]
 Building Rust dependencies...
 Using cargo 1.99.0 (5f94df478 2026-08-27)
 Building Rust static library (release)...
     Updating crates.io index
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 1/3) - retrying in 15s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 2/3) - retrying in 30s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 ##[error]Process completed with exit code 1.

GitHub Actions: CLI / CLI correctness & no-corruption tests: Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

##[group]Run bash native/build-real.sh
 �[36;1mbash native/build-real.sh�[0m
 shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
 env:
   GRAALVM_HOME: /opt/hostedtoolcache/graalvm-jdk-25_linux-x64_bin/25.0.0/x64/graalvm-jdk-25.0.4+7.1
   JAVA_HOME: /opt/hostedtoolcache/graalvm-jdk-25_linux-x64_bin/25.0.0/x64/graalvm-jdk-25.0.4+7.1
   NATIVE_IMAGE_OPTIONS: -H:BuildOutputJSONFile=/tmp/native-image-build-output.json
   GRADLE_ACTION_ID: gradle/actions/setup-gradle
   GRADLE_USER_HOME: /home/runner/.gradle
   GRADLE_BUILD_ACTION_SETUP_COMPLETED: true
   DEVELOCITY_INJECTION_INIT_SCRIPT_NAME: gradle-actions.inject-develocity.init.gradle
   DEVELOCITY_INJECTION_CUSTOM_VALUE: gradle-actions
   GITHUB_DEPENDENCY_GRAPH_ENABLED: false
 ##[endgroup]
 Building Rust dependencies...
 Using cargo 1.99.0 (5f94df478 2026-08-27)
 Building Rust static library (release)...
     Updating crates.io index
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 1/3) - retrying in 15s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 2/3) - retrying in 30s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 ##[error]Process completed with exit code 1.

GitHub Actions: Corpus Testing / 1_Corpus (generate + native).txt: Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

##[group]Run bash native/build-real.sh
 �[36;1mbash native/build-real.sh�[0m
 shell: /usr/bin/bash -e {0}
 env:
   SEED: 42
   JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   JAVA_HOME_25_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   MAVEN_ARGS: -ntp
   GRADLE_ACTION_ID: gradle/actions/setup-gradle
   GRADLE_USER_HOME: /home/runner/.gradle
   GRADLE_BUILD_ACTION_SETUP_COMPLETED: true
   DEVELOCITY_INJECTION_INIT_SCRIPT_NAME: gradle-actions.inject-develocity.init.gradle
   DEVELOCITY_INJECTION_CUSTOM_VALUE: gradle-actions
   GITHUB_DEPENDENCY_GRAPH_ENABLED: false
 ##[endgroup]
 Building Rust dependencies...
 Using cargo 1.99.0 (5f94df478 2026-08-27)
 Building Rust static library (release)...
     Updating crates.io index
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 1/3) - retrying in 15s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 2/3) - retrying in 30s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 ##[error]Process completed with exit code 1.

GitHub Actions: Corpus Testing / Corpus (generate + native): Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

##[group]Run bash native/build-real.sh
 �[36;1mbash native/build-real.sh�[0m
 shell: /usr/bin/bash -e {0}
 env:
   SEED: 42
   JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   JAVA_HOME_25_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   MAVEN_ARGS: -ntp
   GRADLE_ACTION_ID: gradle/actions/setup-gradle
   GRADLE_USER_HOME: /home/runner/.gradle
   GRADLE_BUILD_ACTION_SETUP_COMPLETED: true
   DEVELOCITY_INJECTION_INIT_SCRIPT_NAME: gradle-actions.inject-develocity.init.gradle
   DEVELOCITY_INJECTION_CUSTOM_VALUE: gradle-actions
   GITHUB_DEPENDENCY_GRAPH_ENABLED: false
 ##[endgroup]
 Building Rust dependencies...
 Using cargo 1.99.0 (5f94df478 2026-08-27)
 Building Rust static library (release)...
     Updating crates.io index
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 1/3) - retrying in 15s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 2/3) - retrying in 30s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 ##[error]Process completed with exit code 1.

GitHub Actions: Bundling / 0_Restricted-env compat (no execstack + hermetic bundle).txt: Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

##[group]Run bash native/build-real.sh
 �[36;1mbash native/build-real.sh�[0m
 shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
 env:
   JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   JAVA_HOME_25_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   MAVEN_ARGS: -ntp
   JEXTRACT_HOME: /home/runner/jextract-install
   GRADLE_ACTION_ID: gradle/actions/setup-gradle
   GRADLE_USER_HOME: /home/runner/.gradle
   GRADLE_BUILD_ACTION_SETUP_COMPLETED: true
   DEVELOCITY_INJECTION_INIT_SCRIPT_NAME: gradle-actions.inject-develocity.init.gradle
   DEVELOCITY_INJECTION_CUSTOM_VALUE: gradle-actions
   GITHUB_DEPENDENCY_GRAPH_ENABLED: false
 ##[endgroup]
 Building Rust dependencies...
 Using cargo 1.99.0 (5f94df478 2026-08-27)
 Building Rust static library (release)...
     Updating crates.io index
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 1/3) - retrying in 15s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 2/3) - retrying in 30s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 ##[error]Process completed with exit code 1.

GitHub Actions: Bundling / Restricted-env compat (no execstack + hermetic bundle): Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

##[group]Run bash native/build-real.sh
 �[36;1mbash native/build-real.sh�[0m
 shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
 env:
   JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   JAVA_HOME_25_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   MAVEN_ARGS: -ntp
   JEXTRACT_HOME: /home/runner/jextract-install
   GRADLE_ACTION_ID: gradle/actions/setup-gradle
   GRADLE_USER_HOME: /home/runner/.gradle
   GRADLE_BUILD_ACTION_SETUP_COMPLETED: true
   DEVELOCITY_INJECTION_INIT_SCRIPT_NAME: gradle-actions.inject-develocity.init.gradle
   DEVELOCITY_INJECTION_CUSTOM_VALUE: gradle-actions
   GITHUB_DEPENDENCY_GRAPH_ENABLED: false
 ##[endgroup]
 Building Rust dependencies...
 Using cargo 1.99.0 (5f94df478 2026-08-27)
 Building Rust static library (release)...
     Updating crates.io index
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 1/3) - retrying in 15s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 cargo build failed (attempt 2/3) - retrying in 30s...
 error: cannot update the lock file /home/runner/work/JPDFium/JPDFium/native/rust/Cargo.lock because --locked was passed to prevent this
 help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
 ##[error]Process completed with exit code 1.

GitHub Actions: Bundling / 1_Bundle verify (symbols, RPATH, linkage, sizes).txt: Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

ithub.com/.extraheader AUTHORIZATION: basic ***
 [command]/usr/bin/git config --local includeIf.gitdir:/home/runner/work/JPDFium/JPDFium/.git.path /home/runner/work/_temp/git-credentials-d110b2ed-8d32-40a3-abbe-4e0387fa9e4f.config
 [command]/usr/bin/git config --local includeIf.gitdir:/home/runner/work/JPDFium/JPDFium/.git/worktrees/*.path /home/runner/work/_temp/git-credentials-d110b2ed-8d32-40a3-abbe-4e0387fa9e4f.config
 [command]/usr/bin/git config --local includeIf.gitdir:/github/workspace/.git.path /github/runner_temp/git-credentials-d110b2ed-8d32-40a3-abbe-4e0387fa9e4f.config
 [command]/usr/bin/git config --local includeIf.gitdir:/github/workspace/.git/worktrees/*.path /github/runner_temp/git-credentials-d110b2ed-8d32-40a3-abbe-4e0387fa9e4f.config
 ##[endgroup]
 ##[group]Fetching the repository
 [command]/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +9293a33609c7484ea95d9f731396395d4901641f:refs/remotes/pull/162/merge
 From https://github.com/Stirling-Tools/JPDFium
  * [new ref]         9293a33609c7484ea95d9f731396395d4901641f -> pull/162/merge
 ##[endgroup]
 ##[group]Determining the checkout info
 ##[endgroup]
 [command]/usr/bin/git sparse-checkout disable
 [command]/usr/bin/git config --local --unset-all extensions.worktreeConfig
 ##[group]Checking out the ref
 [command]/usr/bin/git checkout --progress --force refs/remotes/pull/162/merge
 Note: switching to 'refs/remotes/pull/162/merge'.
 You are in 'detached HEAD' state. You can look around, make experimental
 changes and commit them, and you can discard any commits you make in this
 state without impacting any branches by switching back to a branch.
 If you want to create a new branch to retain commits you create, you may
 do so (now or later) by using -c with the switch command. Example:
   git switch -c <new-branch-name>
 Or undo this operation with:
   git switch -
 Turn off this advice by setting config variable advice.detachedHead to false
 HEAD...

GitHub Actions: Bundling / Bundle verify (symbols, RPATH, linkage, sizes): Flatten whole documents in one native pass and reuse the render bitmap

Conclusion: failure

View job details

##[group]Run ./gradlew cyclonedxBom --no-daemon || echo "cyclonedx plugin not configured — add org.cyclonedx.bom when ready"
 �[36;1m./gradlew cyclonedxBom --no-daemon || echo "cyclonedx plugin not configured — add org.cyclonedx.bom when ready"�[0m
 �[36;1mls -R build/reports/cyclonedx 2>/dev/null | head -n 40 || true�[0m
 shell: /usr/bin/bash -e {0}
 env:
   JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   JAVA_HOME_25_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/25.0.4-1/x64
   MAVEN_ARGS: -ntp
   JEXTRACT_HOME: /home/runner/jextract-install
   GRADLE_ACTION_ID: gradle/actions/setup-gradle
   GRADLE_USER_HOME: /home/runner/.gradle
   GRADLE_BUILD_ACTION_SETUP_COMPLETED: true
   DEVELOCITY_INJECTION_INIT_SCRIPT_NAME: gradle-actions.inject-develocity.init.gradle
   DEVELOCITY_INJECTION_CUSTOM_VALUE: gradle-actions
   GITHUB_DEPENDENCY_GRAPH_ENABLED: false
 ##[endgroup]
 To honour the JVM settings for this build a single-use Daemon process will be forked. For more on this, please refer to https://docs.gradle.org/9.8.1/userguide/gradle_daemon.html#sec:disabling_the_daemon in the Gradle documentation.
 Daemon will be stopped at the end of the build
 > Task :buildSrc:checkKotlinGradlePluginConfigurationErrors SKIPPED
 > Task :buildSrc:generateExternalPluginSpecBuilders UP-TO-DATE
 > Task :buildSrc:extractPrecompiledScriptPluginPlugins UP-TO-DATE
 > Task :buildSrc:compilePluginsBlocks UP-TO-DATE
 > Task :buildSrc:generatePrecompiledScriptPluginAccessors UP-TO-DATE
 > Task :buildSrc:generateScriptPluginAdapters UP-TO-DATE
 > Task :buildSrc:compileKotlin UP-TO-DATE
 > Task :buildSrc:compileJava NO-SOURCE
 > Task :buildSrc:compileGroovy NO-SOURCE
 > Task :buildSrc:pluginDescriptors UP-TO-DATE
 > Task :buildSrc:processResources UP-TO-DATE
 > Task :buildSrc:classes UP-TO-DATE
 > Task :buildSrc:jar UP-TO-DATE
 gradle/actions: Writing build results to /home/runner/work/_temp/.gradle-actions/build-results/__run_7-1792151955198.json
 FAILURE: Buil...
🧰 Additional context used
📚 Code guidelines: 1
.github/CODERABBIT_REVIEW.md — unknown
📓 Path-based instructions: 4
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/src/jpdfium_redact.cpp
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_render.cpp
  • native/bridge/include/jpdfium_internal.h
Enforce meaningful assertions, deterministic concurrency, failure-path cleanup, and explicit native/stub requirements.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
Apply the Java 25 and FFM rules from .github/CODERABBIT_REVIEW.md.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfPage.java
  • jpdfium/src/main/java/stirling/software/jpdfium/exception/JPDFiumException.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
Source excerpt: Use imports rather than package-qualified type names in method bodies and signatures.

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

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java
  • jpdfium/build.gradle.kts
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfPage.java
  • jpdfium/src/main/java/stirling/software/jpdfium/exception/JPDFiumException.java
  • native/bridge/src/jpdfium_redact.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • native/bridge/include/jpdfium.h
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
  • native/bridge/src/jpdfium_render.cpp
  • native/bridge/include/jpdfium_internal.h
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
🔇 Additional comments: 14
jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java: 1

58-83: LGTM!

Also applies to: 85-86, 95-95, 103-103

native/bridge/include/jpdfium.h: 1

47-47: LGTM!

Also applies to: 237-250

native/bridge/include/jpdfium_internal.h: 1

73-116: LGTM!

Also applies to: 154-158

native/bridge/src/jpdfium_redact.cpp: 1

444-465: LGTM!

native/bridge/src/jpdfium_render.cpp: 1

740-778: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/exception/JPDFiumException.java: 1

21-23: LGTM!

Also applies to: 70-74

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java: 1

2691-2811: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java: 1

1465-1484: LGTM!

jpdfium/build.gradle.kts: 1

198-198: LGTM!

Also applies to: 516-517

jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java: 1

1049-1084: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/PdfPage.java: 1

1204-1204: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java: 1

456-477: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java: 1

86-87: LGTM!

jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java: 1

1-224: LGTM!

📝 Summary

Summary by CodeRabbit

  • New Features
    • Added document-wide options to flatten annotations and form fields, or convert pages into raster images.
    • Document status now reflects content changes made during page conversion and flattening.
  • Bug Fixes
    • Invalid DPI values are rejected before full-document flattening begins.
    • Flattening reports when a failure occurs after some document content has already been changed.

The change adds document-wide annotation and image flattening through the native bridge and Java API. It updates page and document state handling, adds partial-mutation error reporting, and introduces native-backed tests and JMH benchmarks. Annotation type lookups now use cached enum data.

Changes: Document-wide flattening

Layer / File(s) Summary
Native flatten operations
native/bridge/include/jpdfium.h, native/bridge/include/jpdfium_internal.h, native/bridge/src/jpdfium_redact.cpp, native/bridge/src/jpdfium_render.cpp, native/bridge/src/jpdfium_stub.cpp
The C ABI adds document-wide annotation and image flattening operations and the CONTENT_MUTATED error. Image flattening validates raster dimensions, reuses a per-document bitmap, and reports whether a failure followed page replacement.
Java bindings and document API
jpdfium/src/main/java/stirling/software/jpdfium/exception/JPDFiumException.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/PdfDocument.java, jpdfium/src/main/java/stirling/software/jpdfium/PdfPage.java, jpdfium/build.gradle.kts
The Java API exposes both native operations. PdfDocument.flatten dispatches by mode, validates inputs, and updates content and page state based on the operation result. PdfPage routes full flattening through its owning document.
Flatten tests and benchmarks
jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java, jpdfium/src/test/java/stirling/software/jpdfium/LifecycleTest.java, jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java, jpdfium/build.gradle.kts
Tests cover batch and per-page results, document state, rendering, form widgets, and partial mutation. JMH benchmarks compare batch and per-page flattening with page traversal, rendering, and selective flattening.

Annotation type lookup

Layer / File(s) Summary
Cached annotation lookups
jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
Numeric code lookup uses a cached index. XFDF tag and FDF name lookup scan cached enum constants.

Priority: ⬇️ Low

Change: Feature

Merge Risk: ⚪ Minimal · up to d101c

No actionable merge-blocking issue remains in the reviewed change. It is ready to merge after normal checks.

Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Description check Warning The pull request has no description. It does not provide the required change summary, checklist responses, validation results, or testing details. Add a description using the repository template. Explain what changed and why, complete the General, Library changes, Native or FFM changes, and Testing checklists, and report the commands and results for the required build and test steps.
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title clearly describes the main changes: document-wide native flattening and render bitmap reuse.
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.
✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • 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.

@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: 1433d14e-61c5-4f56-940e-1a6f2fcfe42f
📥 Commits

Reviewing files that changed from the base of the PR and between 42accec and 7c6f943.

📒 Files selected for processing: 11
  • jpdfium/build.gradle.kts
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/src/jpdfium_render.cpp
  • native/bridge/src/jpdfium_stub.cpp

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: 20
  • GitHub Check: prep-windows-icu
  • GitHub Check: Corpus (generate + native)
  • GitHub Check: CLI correctness & no-corruption tests
  • GitHub Check: CodeQL Analysis (java-kotlin)
  • GitHub Check: CodeQL Analysis (c-cpp)
  • GitHub Check: JMH Benchmarks (FFM Downcall Overhead Gate)
  • GitHub Check: Build & Verify (Compilation) (windows-latest)
  • GitHub Check: Java - SpotBugs + Checkstyle + PMD + Spotless
  • GitHub Check: Samples E2E Suite (All 88 Feature Samples)
  • GitHub Check: Native bridge libFuzzer (ASan/UBSan, real PDFium)
  • GitHub Check: CodeQL (java-kotlin)
  • GitHub Check: Samples E2E (88 features via RunAllSamples)
  • GitHub Check: build-natives (darwin-arm64, macos-14)
  • GitHub Check: build-natives (darwin-x64, macos-15-intel)
  • GitHub Check: build-natives (windows-arm64, windows-11-arm)
  • GitHub Check: GraalVM Native Image Smoke & E2E Test (Linux x64)
  • GitHub Check: build-natives (windows-x64, windows-latest)
  • GitHub Check: Restricted-env compat (no execstack + hermetic bundle)
  • GitHub Check: Flaky-test guard (3× rerun)
  • GitHub Check: build-natives (linux-x64, ubuntu-latest)
🧰 Additional context used
📚 Code guidelines: 1
.github/CODERABBIT_REVIEW.md — configured
📓 Path-based instructions: 4
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/src/jpdfium_stub.cpp
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_render.cpp
Enforce meaningful assertions, deterministic concurrency, failure-path cleanup, and explicit native/stub requirements.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
Apply the Java 25 and FFM rules from .github/CODERABBIT_REVIEW.md.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
Source excerpt: Use imports rather than package-qualified type names in method bodies and signatures.

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

Files:

  • jpdfium/build.gradle.kts
  • native/bridge/src/jpdfium_stub.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • native/bridge/src/jpdfium_redact.cpp
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • native/bridge/include/jpdfium.h
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • native/bridge/src/jpdfium_render.cpp
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java

Comment thread jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java Outdated
Comment thread jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java Outdated
Comment thread jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java Outdated
Comment thread jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java Outdated
Comment thread native/bridge/src/jpdfium_render.cpp Outdated
@balazs-szucs
balazs-szucs requested a review from a team October 14, 2026 12:51
@balazs-szucs
balazs-szucs force-pushed the perf/flatten-file-backed branch from a924595 to 94a25c1 Compare October 14, 2026 13:23
@balazs-szucs
balazs-szucs force-pushed the perf/flatten-file-backed branch from 94a25c1 to dfb4d8e Compare October 14, 2026 14:13

@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: 1

🔇 Additional comments: 9
jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java: 1

58-82: LGTM!

Also applies to: 85-86, 95-95, 103-103

native/bridge/src/jpdfium_render.cpp: 2

588-727: LGTM!


728-743: LGTM!

Also applies to: 753-760

native/bridge/src/jpdfium_stub.cpp: 1

901-908: LGTM!

jpdfium/build.gradle.kts: 1

505-511: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java: 1

1461-1481: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java: 1

5-159: LGTM!

Also applies to: 179-181

jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java: 1

1-221: LGTM!

native/bridge/include/jpdfium.h-224-234: 1

224-234: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

State the partial-failure contract for jpdfium_doc_flatten_annotations.

The header says only the image pass leaves earlier pages changed after a failure. jpdfium_doc_flatten_annotations (jpdfium_redact.cpp Lines 382-386) also returns after earlier pages were flattened, and it skips the generation bump on that path. PdfDocument.flatten already treats both passes as possibly partial. Document the same contract for both functions so raw bridge callers do not assume the annotation pass is atomic.


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: Stirling-Tools/JPDFium/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 299bccfe-c731-423b-9dfc-ae283a44cf5b
📥 Commits

Reviewing files that changed from the base of the PR and between 7c6f943 and dfb4d8e.

📒 Files selected for processing: 10
  • jpdfium/build.gradle.kts
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/src/jpdfium_render.cpp
  • native/bridge/src/jpdfium_stub.cpp

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: 27
  • GitHub Check: build-natives (windows-arm64, windows-11-arm)
  • GitHub Check: build-natives (darwin-x64, macos-15-intel)
  • GitHub Check: build-natives (linux-musl-x64, ubuntu-latest, musl)
  • GitHub Check: build-natives (linux-x64, ubuntu-latest)
  • GitHub Check: build-natives (linux-arm64, ubuntu-24.04-arm)
  • GitHub Check: build-natives (linux-musl-arm64, ubuntu-24.04-arm, musl)
  • GitHub Check: build-natives (darwin-arm64, macos-14)
  • GitHub Check: build-natives (windows-x64, windows-latest)
  • GitHub Check: Restricted-env compat (no execstack + hermetic bundle)
  • GitHub Check: Samples E2E Suite (All 88 Feature Samples)
  • GitHub Check: JMH Benchmarks (FFM Downcall Overhead Gate)
  • GitHub Check: Samples E2E (88 features via RunAllSamples)
  • GitHub Check: GraalVM Native Image Smoke & E2E Test (Linux x64)
  • GitHub Check: Build & Verify (Compilation) (windows-latest)
  • GitHub Check: Bundle verify (symbols, RPATH, linkage, sizes)
  • GitHub Check: Java - SpotBugs + Checkstyle + PMD + Spotless
  • GitHub Check: Flaky-test guard (3× rerun)
  • GitHub Check: build-natives (windows-arm64, windows-11-arm)
  • GitHub Check: build-natives (windows-x64, windows-latest)
  • GitHub Check: CodeQL (java-kotlin)
  • GitHub Check: build-natives (darwin-x64, macos-15-intel)
  • GitHub Check: Native bridge libFuzzer (ASan/UBSan, real PDFium)
  • GitHub Check: Corpus (generate + native)
  • GitHub Check: CLI correctness & no-corruption tests
  • GitHub Check: CodeQL Analysis (c-cpp)
  • GitHub Check: CodeQL (c-cpp)
  • GitHub Check: CodeQL Analysis (java-kotlin)
🧰 Additional context used
📚 Code guidelines: 1
.github/CODERABBIT_REVIEW.md — configured
📓 Path-based instructions: 4
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/src/jpdfium_stub.cpp
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/src/jpdfium_render.cpp
Enforce meaningful assertions, deterministic concurrency, failure-path cleanup, and explicit native/stub requirements.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.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/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.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/bridge/src/jpdfium_stub.cpp
  • jpdfium/build.gradle.kts
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_redact.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • native/bridge/src/jpdfium_render.cpp
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java

Comment thread jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java

@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: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: Stirling-Tools/JPDFium/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 069981eb-34f8-4391-a9f1-11f4d6b63e12
📥 Commits

Reviewing files that changed from the base of the PR and between dfb4d8e and b924671.

📒 Files selected for processing: 11
  • jpdfium/build.gradle.kts
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • native/bridge/include/jpdfium.h
  • native/bridge/include/jpdfium_internal.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/src/jpdfium_render.cpp
  • native/patch-pdfium-objtree-cache.py
  • native/setup-pdfium.sh

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: 26
  • GitHub Check: Bundle verify (symbols, RPATH, linkage, sizes)
  • GitHub Check: Restricted-env compat (no execstack + hermetic bundle)
  • GitHub Check: JMH Benchmarks (FFM Downcall Overhead Gate)
  • GitHub Check: CodeQL Analysis (c-cpp)
  • GitHub Check: Samples E2E Suite (All 88 Feature Samples)
  • GitHub Check: Musl Native Detection (Alpine)
  • GitHub Check: Build & Verify (Compilation) (windows-latest)
  • GitHub Check: Flaky-test guard (3× rerun)
  • GitHub Check: Samples E2E (88 features via RunAllSamples)
  • GitHub Check: build-natives (darwin-arm64, macos-14)
  • GitHub Check: GraalVM Native Image Smoke & E2E Test (Linux x64)
  • GitHub Check: CodeQL Analysis (java-kotlin)
  • GitHub Check: prep-windows-icu
  • GitHub Check: Native bridge libFuzzer (ASan/UBSan, real PDFium)
  • GitHub Check: CLI correctness & no-corruption tests
  • GitHub Check: build-natives (linux-arm64, ubuntu-24.04-arm)
  • 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: Natural System Libvips & Downstream Integration (Linux x64)
  • GitHub Check: build-natives (windows-arm64, windows-11-arm)
  • GitHub Check: Java - SpotBugs + Checkstyle + PMD + Spotless
  • GitHub Check: Corpus (generate + native)
  • GitHub Check: CodeQL (c-cpp)
  • GitHub Check: CodeQL (java-kotlin)
  • GitHub Check: JaCoCo coverage (non-blocking ratchet)
🧰 Additional context used
📚 Code guidelines: 1
.github/CODERABBIT_REVIEW.md — configured
📓 Path-based instructions: 4
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/include/jpdfium.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/src/jpdfium_render.cpp
Enforce meaningful assertions, deterministic concurrency, failure-path cleanup, and explicit native/stub requirements.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.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/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.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/bridge/include/jpdfium_internal.h
  • jpdfium/build.gradle.kts
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/setup-pdfium.sh
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • native/bridge/src/jpdfium_render.cpp
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • native/patch-pdfium-objtree-cache.py
🪛 ast-grep (0.45.3)
native/patch-pdfium-objtree-cache.py

[warning] 15-15: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(path, "r", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)


[warning] 27-27: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(path, "w", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)

🪛 Ruff (0.16.8)
native/patch-pdfium-objtree-cache.py

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

Replace with format specifiers

(UP031)


[warning] 14-14: Boolean default positional argument in function definition

(FBT002)


[warning] 15-15: Unnecessary mode argument

Remove mode argument

(UP015)


[warning] 20-20: for loop variable old overwritten by assignment target

(PLW2901)


[warning] 20-20: for loop variable new overwritten by assignment target

(PLW2901)


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

(UP031)


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

Replace with format specifiers

(UP031)


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

Replace with format specifiers

(UP031)

🔇 Additional comments: 9
jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java: 1

1001-1007: 🎯 Functional Correctness | ⚡ Quick win

Validate dpi before the try block.

If dpi <= 0, docFlattenToImages throws before any native work runs. The finally block still calls invalidateOpenPages(), so every open PdfPage becomes stale although nothing changed. Check dpi before entering the try block.

native/bridge/include/jpdfium.h: 1

236-246: LGTM!

native/bridge/src/jpdfium_render.cpp: 1

738-770: LGTM!

jpdfium/build.gradle.kts: 1

507-510: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java: 1

2691-2811: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java: 1

1461-1481: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java: 1

35-159: LGTM!

native/setup-pdfium.sh: 1

1050-1055: LGTM!

native/patch-pdfium-objtree-cache.py: 1

87-115: 🗄️ Data Integrity & Integration

The patch adds a per-document cache for kReferenceHolder results. Its SetCachedObjectsWithMultipleReferences and cached_objects_with_multiple_references accessors store and return the set. Neither the inspected patch text nor the supplied file summary shows any code that clears the cache on document mutation. The cache is opt-in through JPDFIUM_OBJTREE_CACHE.

Whether a stale set is actually read depends on whether PDFium code calls GetObjectsWithMultipleReferences with kReferenceHolder after the same CPDF_Document is mutated. The PDFium source tree is not in the checkout. The shell search (fd -t d pdfium-src native) returned no PDFium directory. The rg search of native/ matched only native/patch-pdfium-objtree-cache.py, so no caller or mutation path was inspected. The needed premise is the caller and mutation ordering in PDFium, and that evidence is unavailable.

The missing-source limitation does not show the concern is false. It also does not show the risk is real. A reviewer should confirm the PDFium callers and mutation paths before this concern can be classified.

Comment thread native/bridge/include/jpdfium_internal.h Outdated
Comment thread native/bridge/src/jpdfium_redact.cpp
@balazs-szucs

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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: 4


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: Stirling-Tools/JPDFium/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 1946efb2-9913-42f4-b830-883b9ebf67a0
📥 Commits

Reviewing files that changed from the base of the PR and between 21c1f6b and d6d1d0b.

📒 Files selected for processing: 14
  • jpdfium/build.gradle.kts
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • native/bridge/include/jpdfium.h
  • native/bridge/include/jpdfium_internal.h
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/src/jpdfium_render.cpp
  • native/bridge/src/jpdfium_stub.cpp
  • native/patch-pdfium-objtree-cache.py
  • native/setup-pdfium.sh

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
🧰 Additional context used
📚 Code guidelines: 1
.github/CODERABBIT_REVIEW.md — unknown
📓 Path-based instructions: 4
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_stub.cpp
  • native/bridge/src/jpdfium_redact.cpp
  • native/bridge/include/jpdfium.h
  • native/bridge/src/jpdfium_render.cpp
Enforce meaningful assertions, deterministic concurrency, failure-path cleanup, and explicit native/stub requirements.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
Apply the Java 25 and FFM rules from .github/CODERABBIT_REVIEW.md.

⚙️ CodeRabbit configuration file

Files:

  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.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/bridge/include/jpdfium_internal.h
  • jpdfium/build.gradle.kts
  • native/bridge/src/jpdfium_stub.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
  • native/bridge/src/jpdfium_redact.cpp
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java
  • native/bridge/include/jpdfium.h
  • native/setup-pdfium.sh
  • jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java
  • jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java
  • native/patch-pdfium-objtree-cache.py
  • jpdfium/src/main/java/stirling/software/jpdfium/doc/AnnotationType.java
  • native/bridge/src/jpdfium_render.cpp
  • jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java
🪛 ast-grep (0.45.3)
native/patch-pdfium-objtree-cache.py

[warning] 15-15: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(path, "r", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)


[warning] 27-27: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(path, "w", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)

🪛 GitHub Check: Java - SpotBugs + Checkstyle + PMD + Spotless
jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java

[warning] 137-137:
[try] auto-closeable resource page is never referenced in body of corresponding try statement

🪛 GitHub Check: JMH Benchmarks (FFM Downcall Overhead Gate)
jpdfium/src/jmh/java/stirling/software/jpdfium/bench/FlattenPathsBenchmark.java

[warning] 137-137:
[try] auto-closeable resource page is never referenced in body of corresponding try statement

🪛 Ruff (0.16.9)
native/patch-pdfium-objtree-cache.py

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

Replace with format specifiers

(UP031)


[warning] 14-14: Boolean default positional argument in function definition

(FBT002)


[warning] 15-15: Unnecessary mode argument

Remove mode argument

(UP015)


[warning] 20-20: for loop variable old overwritten by assignment target

(PLW2901)


[warning] 20-20: for loop variable new overwritten by assignment target

(PLW2901)


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

(UP031)


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

Replace with format specifiers

(UP031)


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

Replace with format specifiers

(UP031)

🔇 Additional comments: 11
native/bridge/src/jpdfium_render.cpp: 2

730-740: Release the old frame before you allocate a frame of a different size in jpdfium_page_to_image.

Lines 730-734 already destroy the old frame before creation. The remaining defect is different. If FPDFBitmap_Create returns null at Line 736, rasterFrameWidth and rasterFrameHeight are set to the requested size while rasterFrame stays null. Line 740 then returns an error, and no state becomes inconsistent. That path is acceptable.

A separate defect remains. When rasterize_page_into fails after page.reset(), the frame stays cached, so retention is bounded by the 32 MiB rule. No change is needed. Discard this comment.


758-790: LGTM!

native/bridge/include/jpdfium.h: 1

236-245: LGTM!

native/bridge/include/jpdfium_internal.h: 1

109-115: LGTM!

native/bridge/src/jpdfium_redact.cpp: 1

444-463: LGTM!

native/bridge/src/jpdfium_stub.cpp: 1

901-908: LGTM!

jpdfium/build.gradle.kts: 1

189-189: LGTM!

Also applies to: 507-510

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumH.java: 1

2691-2811: LGTM!

jpdfium/src/main/java/stirling/software/jpdfium/panama/JpdfiumLib.java: 1

1461-1481: LGTM!

jpdfium/src/test/java/stirling/software/jpdfium/FlattenApiTest.java: 1

5-159: LGTM!

Also applies to: 179-181, 230-241

native/patch-pdfium-objtree-cache.py: 1

62-65: 🩺 Stability & Availability

The cache is enabled only through JPDFIUM_OBJTREE_CACHE, but the available repository does not include the patched PDFium source or the callers of GetObjectsWithMultipleReferences. The stale-cache behavior therefore cannot be decided from this checkout.

Comment thread jpdfium/src/main/java/stirling/software/jpdfium/PdfDocument.java
Comment thread native/patch-pdfium-objtree-cache.py Outdated
Comment thread native/patch-pdfium-objtree-cache.py Outdated
Comment thread native/setup-pdfium.sh Outdated
@balazs-szucs
balazs-szucs force-pushed the perf/flatten-file-backed branch 2 times, most recently from 2454af4 to 70cd598 Compare October 18, 2026 14:32
_sopen_s opened the staging file with the CRT's default text mode; _fdopen's
"wb" does not switch an already-open descriptor, so every LF in the
serialized PDF gained a CR. The added bytes shifted every offset past the
first stream newline, so readers mis-resolved objects and reloaded page
content streams came back empty (white pages); PDFBox masked it by
reconstructing the xref, and the memory save path never touched the CRT
file stream. Add _O_BINARY to both _sopen_s call sites.
@balazs-szucs
balazs-szucs force-pushed the perf/flatten-file-backed branch from 6e9ad75 to f38ce2f Compare October 18, 2026 16:02
The _sopen_s call fits on two lines once formatted; the dry-run lint job
flagged the hand-wrapped version.
…acked

Resolve the page-to-image rewrite against the batch flatten work: keep upstream's scratch-document generation so a malformed destination page tree cannot trap, import each finished replacement into the destination, and retain the batch pass's append-then-commit rollback plus the shared bounded raster frame. Remove the duplicated TurboJPEG CMake block, document the JPEG-quality switch and retained raster frame, and check the two new exports in CI.
@balazs-szucs
balazs-szucs force-pushed the perf/flatten-file-backed branch from 5b62d3d to 9a4ef21 Compare October 21, 2026 09:03

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.

1 participant