Fix selection related crashes when a word is overflowing
Positioning of selection behaviors would try to look up non-visible text offsets when maxLines is set and text is overflowing. This change adds more checks to avoid looking up offsets that aren't visible.
Test: ./gradlew :com:f:f:cAT
Test: ./gradlew :com:f:f:tDUT
Fixes: b/221580975
Fixes: b/300502152
Change-Id: I4e5348fadaa06998c6f4b06aef28e741c888831f
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
index 9ed470a..915309a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
@@ -363,6 +363,7 @@
// affects multiple text selection when selected text is configured with maxLines=1
// and overflow=clip.
val handlePosition = startSelectable.getHandlePosition(selection, isStartHandle = true)
+ if (handlePosition.isUnspecified) return@let null
val position = containerCoordinates.localPositionOf(handleCoordinates, handlePosition)
position.takeIf {
draggingHandle == Handle.SelectionStart || visibleBounds.containsInclusive(it)
@@ -371,6 +372,7 @@
this.endHandlePosition = endLayoutCoordinates?.let { handleCoordinates ->
val handlePosition = endSelectable.getHandlePosition(selection, isStartHandle = false)
+ if (handlePosition.isUnspecified) return@let null
val position = containerCoordinates.localPositionOf(handleCoordinates, handlePosition)
position.takeIf {
draggingHandle == Handle.SelectionEnd || visibleBounds.containsInclusive(it)
@@ -780,11 +782,11 @@
}
val otherSelectable =
selectionRegistrar.selectableMap[otherSelectableId] ?: return@let null
+ val handlePosition = otherSelectable.getHandlePosition(selection, !isStartHandle)
+ if (handlePosition.isUnspecified) return@let null
convertToContainerCoordinates(
otherSelectable.getLayoutCoordinates()!!,
- getAdjustedCoordinates(
- otherSelectable.getHandlePosition(selection, !isStartHandle)
- )
+ getAdjustedCoordinates(handlePosition)
)
} ?: return false