Skip to content
18 changes: 18 additions & 0 deletions patches/react-native-pdf/details.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,21 @@
- Upstream PR/issue: https://github.com/wonday/react-native-pdf/issues/1009, https://github.com/wonday/react-native-pdf/pull/1011
- E/App issue: https://github.com/Expensify/App/issues/81225
- PR introducing patch: https://github.com/Expensify/App/pull/87416


### [react-native-pdf+7.0.2+004+point-pdfiumandroid-to-already-closed-fix.patch](react-native-pdf+7.0.2+004+point-pdfiumandroid-to-already-closed-fix.patch)

- Reason:

```
This patch completes the "Already closed" crash fix that patch 002 started.

Patch 002 sets AlreadyClosedBehavior.IGNORE so a render that races with PDF view teardown is ignored instead of throwing. That config is only honored by pdfiumandroid methods that route their closed-state check through handleAlreadyClosed(). In io.legere:pdfiumandroid 1.0.35, PdfDocument.openPage()/openTextPage() are the only document methods that do NOT use that helper — they guard with an unconditional check(!isClosed) { "Already closed" } that always throws, regardless of the configured behavior. PdfiumCore.renderPageBitmap() calls openPage(), and the barteksc RenderingHandler only catches PageRenderingException, so the IllegalStateException is uncaught on the renderer thread and crashes the app.

Since io.legere:pdfiumandroid is a published artifact (not vendored into node_modules), it cannot be patched with patch-package directly. Instead this patch makes react-native-pdf's Android build.gradle depend on a JitPack fork that makes openPage()/openTextPage() honor handleAlreadyClosed() like every other PdfDocument method, and excludes the io.legere:pdfiumandroid that com.github.zacharee:AndroidPdfViewer pulls in transitively. The exclude is required: the fork is published under a different Maven coordinate (com.github.Expensify:PdfiumAndroidKt) but ships the same io.legere.pdfiumandroid.* classes, so without it both the original (via AndroidPdfViewer) and the fork land on the classpath and the build fails :checkDuplicateClasses. AndroidPdfViewer links against the fork's identical classes unchanged. With IGNORE set, openPage()/openTextPage() return a page bound to the closed document whose operations all no-op via the existing doc.isClosed guards, so the closed-document render is silently dropped instead of crashing. The fork only changes Kotlin (the prebuilt native libs are unchanged) and should be raised upstream so the pin can eventually be dropped.
```

- Fork carrying the fix: https://github.com/Expensify/PdfiumAndroidKt/commit/e6c06c2905d1adf8b76f28c7440a2006033ca4c8 (tag `expensify-already-closed-fix-v1`)
- Upstream library: https://github.com/johngray1965/PdfiumAndroidKt
- E/App issue: https://github.com/Expensify/App/issues/93839
- PR introducing patch: https://github.com/Expensify/App/pull/94894
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
diff --git a/node_modules/react-native-pdf/android/build.gradle b/node_modules/react-native-pdf/android/build.gradle
index 7a70e6e..0e94f9c 100644
--- a/node_modules/react-native-pdf/android/build.gradle
+++ b/node_modules/react-native-pdf/android/build.gradle
@@ -141,8 +141,14 @@ dependencies {
}
// NOTE: The original repo at com.github.barteksc is abandoned by the maintainer; there will be no more updates coming from that repo.
// The repo from zacharee is based on PdfiumAndroidKt, a much newer fork of PdfiumAndroid, with better maintenance and updated native libraries.
- implementation 'com.github.zacharee:AndroidPdfViewer:4.0.1'
- // Depend on PdfiumAndroidKt directly so this can be updated independently of AndroidPdfViewer as updates are provided.
- implementation 'io.legere:pdfiumandroid:1.0.35'
+ // E/App #93839: AndroidPdfViewer pulls io.legere:pdfiumandroid 1.0.35 transitively, whose
+ // PdfDocument.openPage/openTextPage throw "Already closed" instead of honoring AlreadyClosedBehavior.IGNORE
+ // (set by patch 002), crashing the renderer thread when a render races PDF view teardown. Depend on a
+ // JitPack fork that fixes those two methods and exclude the original, so the two coordinates don't ship the
+ // same io.legere.pdfiumandroid.* classes twice. See details.md / patch 004.
+ implementation('com.github.zacharee:AndroidPdfViewer:4.0.1') {
+ exclude group: 'io.legere', module: 'pdfiumandroid'
+ }
+ implementation 'com.github.Expensify:PdfiumAndroidKt:e6c06c2905d1adf8b76f28c7440a2006033ca4c8'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Use the fork's published module coordinate

For Android builds, this dependency is resolving the JitPack root aggregate for a multi-module repo, not the pdfiumandroid AAR that replaces io.legere:pdfiumandroid. The fork's jitpack.yml only publishes the :pdfiumandroid module, and JitPack's module coordinate for that is com.github.Expensify.PdfiumAndroidKt:pdfiumandroid:<sha>; with the current root coordinate Gradle either cannot resolve the artifact or may pull the aggregate instead of the class-compatible library after the original transitive dependency has been excluded.

Useful? React with 👍 / 👎.

implementation 'com.google.code.gson:gson:2.13.2'
}
Loading