Status Update
Comments
se...@google.com <se...@google.com> #2
androidx.compose.foundation.text.TextLinkScope.LinksComposables(TextLinkScope.kt:157)
so...@google.com <so...@google.com> #3
Thanks for the report! Do you have a sample repro project that you can share with us?
lu...@meta.com <lu...@meta.com> #4
so...@google.com <so...@google.com> #5
Debug notes:
According to the indices in the similar crash in a different bug report, this happens when the length is 1. E.g. we have a paragraph [0, 20) and we're looking for a paragraph for an index 20. This could only be the case if the original range that we're looking for is [20, 20) otherwise we would crash earlier in all our precondition checks. In BS we only have a single iteration (low = 0, high = 0, mid = 0, paragraph[0].end <= 0 is true
-> low = 1
-> return -2
).
In this bug length 3, so this would happen if the paragraphs are [0, 5), [5, 7), [7, 10) and we're looking for a text range [10, 10). BS iterations:
-
low = 0, high = 2, mid = 1, parInfoList[1].end = 7 <= 10 is true -> low = 2
-
low = 2, high = 2, mid = 2, parInfoList[2].end = 10 <= 10 is true -> low 3
-
return -4
So for LinkAnnotation this is covered by the
The fix should be available in the next cherry-pick 1.7.5 as we guard against zero-length annotation. It's already available in alpha release (1.8.0-alpha04)
so...@google.com <so...@google.com> #6
Debug notes: on a second look though we wouldn't crash for a zero-width range since getPathForRange
would simply be an empty path Path().
so...@google.com <so...@google.com> #7
It's hard to say how we hit that code path without a minimum repro.
lu...@meta.com <lu...@meta.com> #8
ap...@google.com <ap...@google.com> #9
Project: platform/frameworks/support
Branch: androidx-main
Author: Anastasia Soboleva <
Link:
Add more debug info into findParagraphByIndex
Expand for full commit details
Add more debug info into findParagraphByIndex
Bug: 356080063, 374115892
Test: N/A
Change-Id: I9d7eef189bb5e8aa5a9b56e8fc2642a2634a2a45
Files:
- M
compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt
Hash: d24dad0b0db0cc7bf4c6062f40fadd38c04d4d43
Date: Tue Oct 22 14:28:01 2024
lu...@meta.com <lu...@meta.com> #10
java.lang.IndexOutOfBoundsException: Index -4 out of bounds for length 3
======== getPathForRange =========
mechanical keyboards I've been using the Keychron K2 HE over the last few weeks, and while Hall Effect keyboards are primarily focused on gaming... this is the best of both worlds.
start - end: 183 - 204
ParagraphInfo(paragraph=androidx.compose.ui.text.AndroidParagraph@ba21324, startIndex=0, endIndex=21, startLineIndex=0, endLineIndex=1, top=0.0, bottom=33.0)
0 - 21
ParagraphInfo(paragraph=androidx.compose.ui.text.AndroidParagraph@7af4e8d, startIndex=21, endIndex=22, startLineIndex=1, endLineIndex=2, top=33.0, bottom=56.0)
21 - 22
ParagraphInfo(paragraph=androidx.compose.ui.text.AndroidParagraph@da19842, startIndex=22, endIndex=182, startLineIndex=2, endLineIndex=5, top=56.0, bottom=169.0)
22 - 182
It seems MultiParagrash.paragraphInfoList has one paragragh missing since the max index is 182 while the text has 204 characters, and [183, 204] is the url annotation "
so...@google.com <so...@google.com> #11
That's really helpful, thanks for further debugging. Looks quite suspicious given that we have a normalization function that creates the paragraphs coverage of the text.
You asked in AnnotatedString
and use it? And perhaps what editions and at which stage you perform if any. Thanks!
lu...@meta.com <lu...@meta.com> #12
Managed to repro one case consistently within our product. Traced down to below line of code in Multiparagraph.kt, which break and return early when building the paragraphInfoList
Could you please share how you build your AnnotatedString and use it?
For the case I could consistently repro: it's a multi-line text with a link at the end:
"Today's Above Avalon Daily:
- Netflix 3Q24 Earnings
- Netflix and the Scripted Content High Road
- Disney Moves Away From App Store In-App Purchase
aboveavalon.com/notes…"
It worked fine when above text first rendered, but when I try to quote it which will re-render with a quote UI page, the crash will happen.
lu...@meta.com <lu...@meta.com> #13
Following with above comment: if disable the "maxlines" check the crash is gone. The given value of "maxLines" is 5 but text has 7 lines, I don't know how it's calculated and I'm not sure if we set it to 5 when creating the BasicText. Do you think "maxlines" is safely taken care of in MutliParagraph?
so...@google.com <so...@google.com> #14
Thanks, that's really helpful. Fix is on the way.
ap...@google.com <ap...@google.com> #15
Project: platform/frameworks/support
Branch: androidx-main
Author: Anastasia Soboleva <
Link:
Fix IndexOutOfBound crash with link annotation
Expand for full commit details
Fix IndexOutOfBound crash with link annotation
When we create nodes for link annotations, we should only be looking within the last visible line and not the full text.
In findParagraphByIndex we need to make sure that the index is within the visible lines. For that we check that it's not greater than last line's end.
Bug: 372390054
Fixes: 374115892
Test: existing tests + demo
Change-Id: I3b1f69541b19c630530846a604c832eb7384847e
Files:
- M
compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextLinkTest.kt
- M
compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt
- M
compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextLinkScope.kt
- M
compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
- M
compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt
Hash: 976480616ef1735b4b03eef61626f19588710fde
Date: Fri Oct 25 09:00:38 2024
so...@google.com <so...@google.com> #16
Fixed, a cherry-pick to stable 1.7.x release requested
lu...@meta.com <lu...@meta.com> #17
Nice, thank you for the quick fix!
pr...@google.com <pr...@google.com> #18
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.ui:ui-text:1.8.0-alpha05
androidx.compose.ui:ui-text-android:1.8.0-alpha05
androidx.compose.ui:ui-text-jvmstubs:1.8.0-alpha05
androidx.compose.ui:ui-text-linuxx64stubs:1.8.0-alpha05
na...@google.com <na...@google.com> #19
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.foundation:foundation:1.8.0-alpha06
androidx.compose.foundation:foundation-android:1.8.0-alpha06
androidx.compose.foundation:foundation-jvmstubs:1.8.0-alpha06
androidx.compose.foundation:foundation-linuxx64stubs:1.8.0-alpha06
androidx.compose.ui:ui-text:1.8.0-alpha06
androidx.compose.ui:ui-text-android:1.8.0-alpha06
androidx.compose.ui:ui-text-jvmstubs:1.8.0-alpha06
androidx.compose.ui:ui-text-linuxx64stubs:1.8.0-alpha06
so...@google.com <so...@google.com>
ap...@google.com <ap...@google.com> #21
Project: platform/frameworks/support
Branch: androidx-main
Author: Anastasia Soboleva <
Link:
Fix IndexOutOfBound crash with link annotation
Expand for full commit details
Fix IndexOutOfBound crash with link annotation
When we create nodes for link annotations, we should only be looking within the last visible line and not the full text.
In findParagraphByIndex we need to make sure that the index is within the visible lines. For that we check that it's not greater than last line's end.
In this change compared to the previous attempt to fix this issue (aosp/3320137) I remove an early return to keep the link's Box composable in composition since early return causes all sorts of issues, e.g. the retaining of the focus.
Bug: 372390054
Fixes: 374115892
Test: new tests + demo
Change-Id: Ic96d2868e3edd1ca11d718670fd494a8d402e086
Files:
- M
compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextLinkTest.kt
- M
compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextLinkScope.kt
- M
compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
- M
compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/MultiParagraph.kt
Hash: be7605af63fcd036dd037a67a1b18f2166598f6e
Date: Fri Oct 25 09:00:38 2024
pr...@google.com <pr...@google.com> #22
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.foundation:foundation:1.8.0-alpha07
androidx.compose.foundation:foundation-android:1.8.0-alpha07
androidx.compose.foundation:foundation-jvmstubs:1.8.0-alpha07
androidx.compose.foundation:foundation-linuxx64stubs:1.8.0-alpha07
androidx.compose.ui:ui-text:1.8.0-alpha07
androidx.compose.ui:ui-text-android:1.8.0-alpha07
androidx.compose.ui:ui-text-jvmstubs:1.8.0-alpha07
androidx.compose.ui:ui-text-linuxx64stubs:1.8.0-alpha07
Description
- Jetpack Compose component used: BasicText
- Android Studio Build: N/A
- Kotlin version: 1.9
- Devices/Android versions reproduced on: Samsung a306B
- Keyboard (i.e. Gboard, Samsung, etc): Samsung
If this is a bug in the library, we would appreciate if you could attach:
- Sample project to trigger the issue.
- A screenrecord or screenshots showing the issue (if UI related).
- Stack trace (if applicable)
FATAL EXCEPTION: main
Process: com.instagram.barcelona, PID: 19463
java.lang.IndexOutOfBoundsException: Index -4 out of bounds for length 3
at jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
at java.util.Objects.checkIndex(Objects.java:359)
at java.util.ArrayList.get(ArrayList.java:434)
at androidx.compose.ui.text.MultiParagraphKt.findParagraphsByRange-Sb-Bc2M(MultiParagraph.kt:973)
at androidx.compose.ui.text.MultiParagraph.getPathForRange(MultiParagraph.kt:447)
at androidx.compose.ui.text.TextLayoutResult.getPathForRange(TextLayoutResult.kt:562)
at androidx.compose.foundation.text.TextLinkScope.pathForRangeInRangeCoordinates(TextLinkScope.kt:118)
at androidx.compose.foundation.text.TextLinkScope.shapeForRange(TextLinkScope.kt:103)
at androidx.compose.foundation.text.TextLinkScope.LinksComposables(TextLinkScope.kt:157)
at androidx.compose.foundation.text.TextLinkScope$LinksComposables$2.invoke(Unknown Source:10)
at androidx.compose.foundation.text.TextLinkScope$LinksComposables$2.invoke(Unknown Source:10)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:192)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2825)
at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:3139)
at com.instagram.compose.core.ui.IgClickableTextKt.IgClickableText-0fM_ruI(IgClickableText.kt:147)
at com.instagram.compose.core.ui.IgAccessibleClickableTextKt.IgAccessibleClickableText-oLbMNUE(IgAccessibleClickableText.kt:62)
at com.instagram.compose.core.ui.IgAccessibleClickableTextKt$IgAccessibleClickableText$2.invoke(Unknown Source:50)
at com.instagram.compose.core.ui.IgAccessibleClickableTextKt$IgAccessibleClickableText$2.invoke(Unknown Source:10)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:192)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2825)
at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:3116)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3607)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3552)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:948)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1206)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:132)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:616)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:585)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1299)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1309)
at android.view.Choreographer.doCallbacks(Choreographer.java:923)
at android.view.Choreographer.doFrame(Choreographer.java:847)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1283)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.facebook.appperf.messagequeue.interceptor.MessageQueueBase.deliverMessage(MessageQueueBase.java:84)
at com.facebook.appperf.messagequeue.interceptor.MessageQueueLooper.loopOnce(MessageQueueLooper.java:40)
at com.facebook.appperf.messagequeue.interceptor.MessageQueueLooper.loop(MessageQueueLooper.java:28)
at com.facebook.appperf.messagequeue.interceptor.MessageQueueLooper.install(MessageQueueLooper.java:22)
at com.facebook.appperf.messagequeue.interceptor.MessageQueueBase.run(MessageQueueBase.java:56)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
at Z.init(1729180395740-03614ed2-4e79-0972-f931-dc9e5d69c1b8)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@2d3377f, androidx.compose.ui.platform.MotionDurationScaleImpl@a11834c, StandaloneCoroutine{Cancelling}@83e3f95, AndroidUiDispatcher@c1ea8aa]