Repository: superlistapp/super_editor (dart)

Issue:
[BUG] - [AttributedText] - Character lookup logic is wrong
`AttributedText` supports looking up characters and placeholders by index. The implementation is wrong for character lookup. It pulls characters from the plain text, not the text with placeholders, which can lead to the wrong characters being returned, and exceptions trying to access indices beyond the end of the text string.

Pull request description:
[AttributedText] - Fix incorrect character lookup by index (Resolves #2531)

We need to lookup text characters while accounting for placeholders. Previously were were looking up characters in the plain text string.

Patch:
diff --git a/attributed_text/lib/src/attributed_text.dart b/attributed_text/lib/src/attributed_text.dart
index 11e77b52a0..a554282aa7 100644
--- a/attributed_text/lib/src/attributed_text.dart
+++ b/attributed_text/lib/src/attributed_text.dart
@@ -119,13 +119,13 @@ class AttributedText {
   late final String _textWithPlaceholders;
 
   /// Returns the character or placeholder at offset zero.
-  Object get first => placeholders[0] ?? _text[0];
+  Object get first => placeholders[0] ?? _textWithPlaceholders[0];
 
   /// Returns the character or placeholder at the given [offset].
-  Object operator [](int offset) => placeholders[offset] ?? _text[offset];
+  Object operator [](int offset) => placeholders[offset] ?? _textWithPlaceholders[offset];
 
   /// Returns the character or placeholder at the end of this `AttributedText`.
-  Object get last => placeholders[length - 1] ?? _text[length - 1];
+  Object get last => placeholders[length - 1] ?? _textWithPlaceholders[length - 1];
 
   /// Returns a plain-text version of this `AttributedText`.
   ///


Test patch:
diff --git a/attributed_text/test/attributed_text_placeholders_test.dart b/attributed_text/test/attributed_text_placeholders_test.dart
index f17f2a00dc..3022a05641 100644
--- a/attributed_text/test/attributed_text_placeholders_test.dart
+++ b/attributed_text/test/attributed_text_placeholders_test.dart
@@ -81,6 +81,26 @@ void main() {
       });
     });
 
+    test("reports characters and placeholders at indices", () {
+      final text1 = AttributedText("HelloWorld", null, {
+        0: const _FakePlaceholder("one"),
+        6: const _FakePlaceholder("two"),
+        12: const _FakePlaceholder("three"),
+      });
+
+      expect(text1.first, const _FakePlaceholder("one"));
+      expect(text1[1], "H");
+      expect(text1[6], const _FakePlaceholder("two"));
+      expect(text1[11], "d");
+      expect(text1.last, const _FakePlaceholder("three"));
+
+      final text2 = AttributedText("Hello World", null, {
+        0: const _FakePlaceholder("one"),
+      });
+      expect(text2[11], "d");
+      expect(text2.last, "d");
+    });
+
     test("reports plain text value", () {
       expect(
         AttributedText("", null, {