Avoid crashing when measuring large text

In: AnnotatedString, String, TextMeasurer paths

fixes: b/341928267
Test: ./gradlew :com:found:found:cAT
Test: ./gradlew :com:ui:ui-text:cAT
(cherry picked from https://android-review.googlesource.com/q/commit:882f214e40dadd753901e69912ee954c65bca726)
(cherry picked from https://android-review.googlesource.com/q/commit:074f0c123338c7ef6794a33dbd05865d98fdecc9)
Merged-In: I7c067c1d2b90484e8fe1f596bf04f84b1ffc0c1a
Change-Id: I7c067c1d2b90484e8fe1f596bf04f84b1ffc0c1a
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/MultiParagraphLayoutCacheTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/MultiParagraphLayoutCacheTest.kt
index 6a51fca..38232c7 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/MultiParagraphLayoutCacheTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/MultiParagraphLayoutCacheTest.kt
@@ -340,4 +340,17 @@
         )
         assertThat(actual.height).isEqualTo(expected.height)
     }
+
+    @Test
+    fun hugeString_doesntCrash() {
+        val text = "A".repeat(100_000)
+        val subject =
+            MultiParagraphLayoutCache(
+                    text = AnnotatedString(text),
+                    style = TextStyle(fontSize = 100.sp),
+                    fontFamilyResolver = fontFamilyResolver,
+                )
+                .also { it.density = density }
+        subject.layoutWithConstraints(Constraints(), LayoutDirection.Ltr)
+    }
 }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/ParagraphLayoutCacheTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/ParagraphLayoutCacheTest.kt
index f38a424..a735780 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/ParagraphLayoutCacheTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/modifiers/ParagraphLayoutCacheTest.kt
@@ -343,6 +343,15 @@
         assertThat(subject.slowCreateTextLayoutResultOrNull(style = style)).isNotNull()
     }
 
+    @Test
+    fun hugeString_doesntCrash() {
+        val text = "A".repeat(100_000)
+        val style = createTextStyle(fontSize = 100.sp)
+        val subject =
+            ParagraphLayoutCache(text, style, fontFamilyResolver).also { it.density = density }
+        subject.layoutWithConstraints(Constraints(), LayoutDirection.Ltr)
+    }
+
     private fun createTextStyle(
         fontSize: TextUnit,
         letterSpacing: TextUnit = TextUnit.Unspecified
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/LayoutUtils.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/LayoutUtils.kt
index 201baaf..faa55b3 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/LayoutUtils.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/LayoutUtils.kt
@@ -28,7 +28,8 @@
     softWrap: Boolean,
     overflow: TextOverflow,
     maxIntrinsicWidth: Float
-): Constraints = Constraints(
+): Constraints =
+    Constraints.fitPrioritizingWidth(
         minWidth = 0,
         maxWidth = finalMaxWidth(constraints, softWrap, overflow, maxIntrinsicWidth),
         minHeight = 0,
diff --git a/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/TextMeasurerTest.kt b/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/TextMeasurerTest.kt
index 404da84..ee33aa8 100644
--- a/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/TextMeasurerTest.kt
+++ b/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/TextMeasurerTest.kt
@@ -348,6 +348,12 @@
             .isEqualTo(TextDecoration.LineThrough)
     }
 
+    @Test
+    fun emptyConstraints_hugeString_dontCrash() {
+        val subject = textMeasurer()
+        subject.measure("A".repeat(100_000), TextStyle.Default)
+    }
+
     private fun textLayoutInput(
         text: AnnotatedString = AnnotatedString("Hello"),
         style: TextStyle = TextStyle.Default,
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
index 533d7eb..5d139e3 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
@@ -282,8 +282,9 @@
 
             // This is a fallback behavior because native text layout doesn't support multiple
             // ellipsis in one text layout.
-            // When softWrap is turned off and overflow is ellipsis, it's expected that each line
-            // that exceeds maxWidth will be ellipsized.
+            // When softWrap is turned off and overflow is ellipsis, it's expected that each
+            // line that exceeds maxWidth will be ellipsized.
+            //
             // For example,
             // input text:
             //     "AAAA\nAAAA"
@@ -304,7 +305,8 @@
             //    width to be passed to Paragraph
             //        if max intrinsic width is between minWidth and maxWidth
             //           we can use it to layout
-            //        else if max intrinsic width is greater than maxWidth, we can only use maxWidth
+            //        else if max intrinsic width is greater than maxWidth, we can only use
+            //           maxWidth
             //        else if max intrinsic width is less than minWidth, we should use minWidth
             val width = if (minWidth == maxWidth) {
                 maxWidth
@@ -314,7 +316,12 @@
 
             val multiParagraph = MultiParagraph(
                 intrinsics = nonNullIntrinsics,
-                constraints = Constraints(maxWidth = width, maxHeight = constraints.maxHeight),
+                constraints = Constraints.fitPrioritizingWidth(
+                    minWidth = 0,
+                    maxWidth = width,
+                    minHeight = 0,
+                    maxHeight = constraints.maxHeight
+                ),
                 // This is a fallback behavior for ellipsis. Native
                 maxLines = finalMaxLines,
                 ellipsis = overflow == TextOverflow.Ellipsis