Skip to content

Fix 3 crashes#760

Open
RankoR wants to merge 3 commits intoreadium:developfrom
RankoR:crash-fixes
Open

Fix 3 crashes#760
RankoR wants to merge 3 commits intoreadium:developfrom
RankoR:crash-fixes

Conversation

@RankoR
Copy link
Contributor

@RankoR RankoR commented Mar 1, 2026

These 3 commits fix 3 crashes occurring in production:

Invocations on zero-size WebView:

          Fatal Exception: java.lang.IllegalStateException: Check failed.
       at org.readium.navigator.web.internals.webview.WebViewScrollController.moveToProgression(WebViewScrollController.kt:111)
       at org.readium.navigator.web.reflowable.resource.ReflowableResourceKt$ReflowableResource$1$3$1.invokeSuspend$lambda$0$0$0$0(ReflowableResource.kt:200)
       at org.readium.navigator.web.reflowable.resource.ReflowableResourceKt$ReflowableResource$1$3$1.$r8$lambda$hRiAUJQolcOVqg3AKXicl-UOMLY()
       at org.readium.navigator.web.reflowable.resource.ReflowableResourceKt$ReflowableResource$1$3$1$$ExternalSyntheticLambda2.invoke(D8$$SyntheticClass)
       at org.readium.navigator.web.internals.webview.WebViewUtilKt$invokeOnReadyToBeDrawn$1$1.onComplete(WebViewUtil.kt:21)
       at WV.w13.a(chromium-SystemWebViewGoogle6432.aab-stable-763207903:3)
       at WV.yf.run(chromium-SystemWebViewGoogle6432.aab-stable-763207903:7)
       at android.os.Handler.handleCallback(Handler.java:995)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loopOnce(Looper.java:273)
       at android.os.Looper.loop(Looper.java:363)
       at android.app.ActivityThread.main(ActivityThread.java:10060)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
        

Unwrapping null value

          Fatal Exception: java.lang.NullPointerException:
       at org.readium.navigator.web.internals.pager.RenditionScrollState.onDocumentResized(RenditionScrollState.kt:186)
       at org.readium.navigator.web.reflowable.ReflowableWebRenditionKt.ReflowableWebRendition$lambda$0$0$1$6$0(ReflowableWebRendition.kt:192)
       at org.readium.navigator.web.reflowable.ReflowableWebRenditionKt.$r8$lambda$FfybFSxmbaLw0iWhus9SI57h6Ns()
       at org.readium.navigator.web.reflowable.ReflowableWebRenditionKt$$ExternalSyntheticLambda5.invoke(D8$$SyntheticClass)
       at org.readium.navigator.web.reflowable.resource.ReflowableResourceKt$ReflowableResource$1$3$1.invokeSuspend$lambda$0$0$1(ReflowableResource.kt:242)
       at org.readium.navigator.web.reflowable.resource.ReflowableResourceKt$ReflowableResource$1$3$1.$r8$lambda$1pJbUrRI6K0N9_6scFN-5KJ957o()
       at org.readium.navigator.web.reflowable.resource.ReflowableResourceKt$ReflowableResource$1$3$1$$ExternalSyntheticLambda1.invoke(D8$$SyntheticClass)
       at org.readium.navigator.web.internals.webapi.DelegatingDocumentApiListener.onDocumentResized(DocumentStateApi.kt:25)
       at org.readium.navigator.web.internals.webapi.DocumentStateApi$onDocumentResized$1.invokeSuspend(DocumentStateApi.kt:57)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
       at android.os.Handler.handleCallback(Handler.java:995)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loopOnce(Looper.java:273)
       at android.os.Looper.loop(Looper.java:363)
       at android.app.ActivityThread.main(ActivityThread.java:10060)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
        

Reading from an already closed ZIP file

          Fatal Exception: org.chromium.base.JniAndroid$UncaughtExceptionException: Native stack trace:
#00 pc 0x00000000066fb53f /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#01 pc 0x0000000001a62163 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#02 pc 0x0000000007de1c17 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#03 pc 0x0000000007de1f6f /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#04 pc 0x00000000037c4783 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#05 pc 0x0000000003064fbb /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#06 pc 0x0000000003064f73 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#07 pc 0x0000000001b0ee1f /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#08 pc 0x0000000001b0d463 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#09 pc 0x0000000001b06b77 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#10 pc 0x0000000001b0671f /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#11 pc 0x0000000001b06647 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#12 pc 0x0000000001a99613 /data/app/~~SFPHmmTiCtBJSXcA_1Ta7w==/com.google.android.webview-aWGzr_MBnA2Bq5y7kqXC3A==/base.apk (offset 0xdb8000)
#13 pc 0x00000000000b3ecf /apex/com.android.runtime/lib64/bionic/libc.so
#14 pc 0x00000000000471f3 /apex/com.android.runtime/lib64/bionic/libc.so

       at org.chromium.base.JniAndroid.handleException(chromium-SystemWebViewGoogle6432.aab-stable-755913203:21)
       
          Caused by java.lang.IllegalStateException: zip file closed
       at java.util.zip.ZipFile.ensureOpen(ZipFile.java:925)
       at java.util.zip.ZipFile.getInputStream(ZipFile.java:417)
       at org.readium.r2.shared.util.zip.FileZipContainer$Entry.stream(FileZipContainer.kt:124)
       at org.readium.r2.shared.util.zip.FileZipContainer$Entry.readRange(FileZipContainer.kt:104)
       at org.readium.r2.shared.util.zip.FileZipContainer$Entry.access$readRange(FileZipContainer.kt:45)
       at org.readium.r2.shared.util.zip.FileZipContainer$Entry$read$2.invokeSuspend(FileZipContainer.kt:85)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
       at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:124)
       at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)
       

} else {
requestLayout()
setNextLayoutListener {
invokeOnWebViewUpToDate(block)
Copy link
Contributor

Choose a reason for hiding this comment

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

This being recursive, if the webview is detached or something similar, won't this will loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, this will loop. Do you have any suggestions better than limiting max recursion?

Copy link
Member

@qnga qnga Mar 18, 2026

Choose a reason for hiding this comment

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

I think you could use coroutine cancellation with a scope got from the composition.

@qnga
Copy link
Member

qnga commented Mar 18, 2026

Sorry for the delay, I've been overwhelmed.

Could you make your case for the third fix? What makes you think this is the right fix? I thought ZipFile was thread-safe. Isn't it up to the caller to make sure it doesn't call read after close ?

Regarding the crash in onDocumentResized, I think the coroutine scope in DelegatingDocumentApiListener should be cancelled when the resource leaves the composition. Maybe with a callbackFlow collected in LaunchedEffect.

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