substring does not support UTF-16

"🍕".substring(0, 1);
> "�"

This issue came up because a user inputted an emoji into a data field. Attempting to render Text("🍕".substring(0, 1)) in Flutter results in:

flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following ArgumentError was thrown during performLayout():
flutter: Invalid argument(s): string is not well-formed UTF-16
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      ParagraphBuilder.addText (dart:ui/text.dart:1157:7)
flutter: #1      TextSpan.build 
package:flutter/…/painting/text_span.dart:172
flutter: #2      TextPainter.layout 
package:flutter/…/painting/text_painter.dart:352
flutter: #3      RenderParagraph._layoutText 
...

Author: Fantashit

3 thoughts on “substring does not support UTF-16

  1. I am having the exact same problem. My case is I want to programmatically delete (backspace) a text input which may have emojis. So far, my workaround is as follows:

    var s = "abc😀";
    var sRunes = s.runes;
    print(String.fromCharCodes(sRunes, 0, sRunes.length-1));

    And make sure users do not input those emojis which have length 4.

  2. See #28404 and dart-lang/language#34, long discussions about making correct String manipulation easier. We will probably close this issue as being one example of the bigger issue.

    @LiteCatDev String.fromCharCodes takes an Iterable of rune values, so you can simplify your code to:

    String runeSubstring({String input, int start, int end}) {
      return String.fromCharCodes(input.runes.toList().sublist(start, end));
    }

Comments are closed.