react-native-pdf icon indicating copy to clipboard operation
react-native-pdf copied to clipboard

Crash on Android 15 (SDK 35) with 16KB page alignment: libpdfiumandroid.so fails to load due to missing hash section

Open abitling opened this issue 9 months ago • 36 comments

When using react-native-pdf v6.7.7 on a device running Android 15 (SDK 35) with 16KB page alignment, the app crashes upon mounting the <Pdf /> component. The crash is due to a native library loading failure:

java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH/DT_GNU_HASH in "/.../libpdfiumandroid.so" (new hash type from the future?)

Complete Stack Trace :

Native libraries failed to load
	java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH/DT_GNU_HASH in "/data/app/.../libpdfiumandroid.so" (new hash type from the future?)
		at java.lang.Runtime.loadLibrary0(Runtime.java:1081)
		at java.lang.Runtime.loadLibrary0(Runtime.java:1003)
		at java.lang.System.loadLibrary(System.java:1765)
		at io.legere.pdfiumandroid.PdfiumCore._init_$lambda$28(PdfiumCore.kt:534)
		at io.legere.pdfiumandroid.PdfiumCore.$r8$lambda$XuqcpolvQXrnr4u5D9FnuN1EJQY(Unknown Source:0)
		at io.legere.pdfiumandroid.PdfiumCore$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
		at java.lang.Thread.run(Thread.java:1012)

Environment :

  • react-native: 0.79.2
  • react-native-pdf: 6.7.7
  • Node: v24.2.0
  • npm: v11.3.0
  • buildToolsVersion: 35.0.0
  • minSdkVersion: 24
  • compileSdkVersion: 35
  • targetSdkVersion: 35
  • ndkVersion: 27.1.12297006
  • kotlinVersion: 2.0.21
  • Device: Android 15 emulator with 16KB memory page size (required for Google Play compliance as of mid-2025)
  • Crash occurs consistently when <Pdf /> component is mounted

Possible Cause : The issue seems related to libpdfiumandroid.so not being built correctly for 16KB page size devices, leading to a missing or invalid dynamic hash section (DT_HASH/DT_GNU_HASH). This may stem from misaligned native libraries or build tool incompatibilities with Android 15+.

What I've Tried :

  • Using latest NDK and build tools
  • Works fine on older Android versions (< SDK 34)

Suggested Action : Please confirm if the bundled libpdfiumandroid.so supports 16KB page alignment and is compatible with Android 15 (SDK 35). If not, guidance or fixes to rebuild it with proper section headers and alignment would be greatly appreciated.

abitling avatar Jun 24 '25 07:06 abitling

I have written a script to audit the lib files (.so) and check the elf segment alignment. It works fine on Apple M1 machine. I am sharing the script here.

#!/usr/bin/env python3
import sys
import zipfile
import struct
import os

PAGE_SIZE = 16384  # 16KB

def is_elf_segment_aligned(elf_path, page_size=PAGE_SIZE):
    not_aligned = []
    with open(elf_path, 'rb') as f:
        # Check ELF magic
        if f.read(4) != b'\x7fELF':
            return False, "Not an ELF file", []
        f.seek(0)
        e_ident = f.read(16)
        elf_class = e_ident[4]
        if elf_class == 1:
            elf_hdr_fmt = '<HHIIIIIHHHHHH'
            phdr_fmt = '<IIIIIIII'
            elf_hdr_size = 52
            phdr_size = 32
        elif elf_class == 2:
            elf_hdr_fmt = '<HHIQQQIHHHHHH'
            phdr_fmt = '<IIQQQQQQ'
            elf_hdr_size = 64
            phdr_size = 56
        else:
            return False, "Unknown ELF class", []

        f.seek(16)
        elf_hdr = struct.unpack(elf_hdr_fmt, f.read(elf_hdr_size - 16))
        if elf_class == 1:
            e_phoff = elf_hdr[4]
            e_phentsize = elf_hdr[7]
            e_phnum = elf_hdr[8]
        else:
            e_phoff = elf_hdr[4]
            e_phentsize = elf_hdr[7]
            e_phnum = elf_hdr[8]

        for i in range(e_phnum):
            f.seek(e_phoff + i * e_phentsize)
            phdr = struct.unpack(phdr_fmt, f.read(phdr_size))
            if elf_class == 1:
                p_type, p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_flags, p_align = phdr
            else:
                p_type, p_flags, p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_align = phdr
            if p_type == 1:  # PT_LOAD
                if (p_offset % page_size != 0) or (p_vaddr % page_size != 0):
                    not_aligned.append({'segment': i, 'offset': p_offset, 'vaddr': p_vaddr})
        if not_aligned:
            msg = f"{len(not_aligned)} segment(s) not aligned"
            return False, msg, not_aligned
        return True, "All loadable segments are aligned", []

def check_apk_elf_alignment(apk_path):
    with zipfile.ZipFile(apk_path, 'r') as apk:
        elf_files = [f for f in apk.namelist() if f.startswith('lib/') and f.endswith('.so')]
        if not elf_files:
            print("😕 No ELF files found in APK.")
            return
        for elf_file in elf_files:
            with apk.open(elf_file) as ef:
                tmp_path = f'/tmp/{os.path.basename(elf_file)}'
                with open(tmp_path, 'wb') as out:
                    out.write(ef.read())
                aligned, msg, _ = is_elf_segment_aligned(tmp_path)
                print(f"{elf_file}: {'✅ Aligned' if aligned else '❌ Not aligned'} ({msg})")
                os.remove(tmp_path)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python3 check_apk_elf_alignment.py <your.apk>")
        sys.exit(1)
    check_apk_elf_alignment(sys.argv[1])

And my output had the following which corresponds to react-native-pdf:

lib/arm64-v8a/libpdfium.so: ✅ Aligned (All loadable segments are aligned)
lib/arm64-v8a/libpdfiumandroid.so: ❌ Not aligned (1 segment(s) not aligned)
lib/armeabi-v7a/libpdfium.so: ✅ Aligned (All loadable segments are aligned)
lib/armeabi-v7a/libpdfiumandroid.so: ✅ Aligned (All loadable segments are aligned)
lib/x86/libpdfium.so: ✅ Aligned (All loadable segments are aligned)
lib/x86/libpdfiumandroid.so: ✅ Aligned (All loadable segments are aligned)
lib/x86_64/libpdfium.so: ❌ Not aligned (1 segment(s) not aligned)
lib/x86_64/libpdfiumandroid.so: ✅ Aligned (All loadable segments are aligned)

Out of the above it seems libpdfiumandroid.so corresponding to arm64-v8a abi is causing the crash.

abitling avatar Jun 24 '25 08:06 abitling

Tried patching to use the latest versions of io.legere:pdfiumandroid and com.google.code.gson:gson which certainly fixes the problem as the latest one's are already 16KB page size aligned. Refer the patch below :

diff --git a/node_modules/react-native-pdf/android/build.gradle b/node_modules/react-native-pdf/android/build.gradle
index 3dfe1dc..db111c8 100644
--- a/node_modules/react-native-pdf/android/build.gradle
+++ b/node_modules/react-native-pdf/android/build.gradle
@@ -126,6 +126,6 @@ dependencies {
     // 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.24'
-    implementation 'com.google.code.gson:gson:2.8.5'
+    implementation 'io.legere:pdfiumandroid:1.0.32'
+    implementation 'com.google.code.gson:gson:2.11.0'
 }

abitling avatar Jun 24 '25 09:06 abitling

@mrbrentkelly Please release the latest code to npm.

xgtz421 avatar Jul 29 '25 08:07 xgtz421

Hi, Thanks @abitling for your patch, it's work !

@wonday, Any chance to get it released on npm ?

LaGregance avatar Jul 30 '25 06:07 LaGregance

Thank you @abitling

lanceturbes avatar Aug 08 '25 19:08 lanceturbes

@abitling patch is worked 🚀

also, it could be better to release a new version of this react-native-pdf library

omerkarakose avatar Aug 15 '25 08:08 omerkarakose

Thank you for the patch!

Kureev avatar Aug 21 '25 11:08 Kureev

👋 I'm working on the support of 16Kb, and I see this PR fixes this since last month, but we are just missing the release. Can we move forward and release it? Thanks!

dprevost-LMI avatar Aug 22 '25 12:08 dprevost-LMI

Same here, what's the ETA for the release?

elkinjosetm avatar Sep 03 '25 15:09 elkinjosetm

Play Console has given a warning page size 16KB so when will there be a new release of this library?

huybui21 avatar Sep 05 '25 04:09 huybui21

you can force install the master branch code instead of relying on a release update with command

npm install 'wonday/react-native-pdf'

so, your node_modules/react-native-pdf/android/build.gradle will receive the current repository code that is already fixed.

you can also fix the package install last commit to avoid breaking changes with:

npm i "git+https://[email protected]/wonday/react-native-pdf.git#b0b074fc60c86c4f2e10deab6676d7c2a15be43d"

rayllandersotero avatar Sep 15 '25 14:09 rayllandersotero

you can force install the master branch code instead of relying on a release update with command

npm install 'wonday/react-native-pdf' so, your node_modules/react-native-pdf/android/build.gradle will receive the current repository code that is already fixed.

you can also fix the package install last commit to avoid breaking changes with:

npm i "git+https://[email protected]/wonday/react-native-pdf.git#b0b074fc60c86c4f2e10deab6676d7c2a15be43d"

We are doing expo dev builds. We're on Expo 53/Rn 0.79.5

When I try either of these npm installs, I get this error when doing a new prebuild and expo run:android.

`

Task :app:compileDebugKotlin FAILED e: org.jetbrains.kotlin.util.FileAnalysisException: While analysing C:/PROJECTS/vision-paragon-mobile/android/app/src/main/java/com/blackknight/paragon/android/MainActivity.kt:14:3: java.lang.IllegalArgumentException: source must not be null ... 35 more

e: file:///C:/Users/maxmann/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.2.0/fdfc65fbc42fda253a26f61dac3c0aca335fae96/kotlin-stdlib-2.2.0.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_module Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.2.0, expected version is 2.0.0. ....

  • What went wrong: Execution failed for task ':app:compileDebugKotlin'.

A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction Internal compiler error. See log for more details `

maxmann74 avatar Sep 16 '25 14:09 maxmann74

I'm also waiting for this to be fixed. Can the version be released to npm please?

FreTimmerman avatar Sep 17 '25 08:09 FreTimmerman

Any news?

gvamvoukas avatar Sep 23 '25 11:09 gvamvoukas

Hi, any updates ?

olitynskyi-mtb avatar Sep 23 '25 12:09 olitynskyi-mtb

It's look like this project is abandoned...

LaGregance avatar Sep 23 '25 12:09 LaGregance

Any updates?

ebaraniuk-mtb avatar Sep 23 '25 12:09 ebaraniuk-mtb

still waiting for updates

vladimirSoftesis avatar Sep 23 '25 12:09 vladimirSoftesis

yes, we need to handle this as soon as possible

simonecorsato avatar Sep 23 '25 13:09 simonecorsato

any updates?

dpercheklii-mtb avatar Sep 23 '25 13:09 dpercheklii-mtb

any updates ?

DanilSoftesis avatar Sep 23 '25 13:09 DanilSoftesis

FYI: Not sure that hammering will open people to move faster.

dprevost-LMI avatar Sep 23 '25 14:09 dprevost-LMI

Any updates?

cristiankrein avatar Sep 23 '25 17:09 cristiankrein

Thank you @abitling very much!!

DhruvKalpeshThakar avatar Sep 24 '25 07:09 DhruvKalpeshThakar

Any updates?

Titmdeveloper avatar Sep 25 '25 06:09 Titmdeveloper

What is happening, why there is no new update?

chavanRk avatar Sep 26 '25 10:09 chavanRk

As a backup plan, I've commented out the use of this package in my expo app and am going to just use expo-sharing, which will prompt the user to share/open the PDF on their device.

import * as Sharing from 'expo-sharing'; //save file to file system... then share await Sharing.shareAsync(filepath, { mimeType: fileInfo.mimeType });

maxmann74 avatar Sep 26 '25 20:09 maxmann74

Could you please provide any guidance, workaround, or an estimated timeline for a 16 KB-compatible release? Any help would be greatly appreciated.

Can't you track 16KB issue? The fix is already in main branch. Just install main branch not waiting for release.

talaikis avatar Sep 27 '25 06:09 talaikis

Could you please provide any guidance, workaround, or an estimated timeline for a 16 KB-compatible release? Any help would be greatly appreciated.

Can't you track 16KB issue? The fix is already in main branch. Just install main branch not waiting for release.

I tried this.. it doesn't work. See my post above.

maxmann74 avatar Sep 29 '25 16:09 maxmann74

Could you please provide any guidance, workaround, or an estimated timeline for a 16 KB-compatible release? Any help would be greatly appreciated.

Can't you track 16KB issue? The fix is already in main branch. Just install main branch not waiting for release.

I tried this.. it doesn't work. See my post above.

I found solution, please check : https://github.com/wonday/react-native-pdf/issues/965#issuecomment-3346515105

Siddhantshelake avatar Sep 29 '25 16:09 Siddhantshelake