Skip to content

Conversation

@dansunhappy
Copy link

Description

fix in iOS paste emoji crash
1 Test code

import 'package:flutter/material.dart';

class MyTextField extends StatelessWidget {
//  MediaQuery
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextField(
          maxLines: null,
        ),
      ),
    );
  }
}

void main() async {
  runApp(MaterialApp(
    home: MyTextField(),
  ));
}
  1. environment
    device:iOS 12 ,iPhone
    keyboard setting : english & emoji
    image

  2. analyze

main() {
  String a='𐐷';
  print(a.codeUnits.map((v)=> v.toRadixString(16)));
  String b='宋';
  print(b.codeUnits.map((v)=> v.toRadixString(16)));
}

https://en.wikipedia.org/wiki/UTF-16 @dnfield one character may be two code units.
try this code,

Related Issues

Replace this paragraph with a list of issues related to this PR from our issue database. Indicate, which of these issues are resolved or fixed by this PR.

Tests

I added the following tests:

Replace this with a list of the tests that you added as part of this PR. A change in behaviour with no test covering it
will likely get reverted accidentally sooner or later. PRs must include tests for all changed/updated/fixed behaviors. See Test Coverage.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require Flutter developers to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (Please read Handling breaking changes). Replace this with a link to the e-mail where you asked for input on this proposed change.
  • No, this is not a breaking change.

@dnfield dnfield added a: typography Text rendering, possibly libtxt platform-ios iOS applications specifically engine flutter/engine related. See also e: labels. f: inspector Part of widget inspector in framework. labels Apr 23, 2019
@dnfield
Copy link
Contributor

dnfield commented Apr 23, 2019

I've tried this locally on an iPhone 8. I can't seem to get the cursor to land in the middle of an emoji as you're showing here. What version of Flutter are you using? I'm on master.

@dnfield
Copy link
Contributor

dnfield commented Apr 23, 2019

Scratch that - I managed to reproduce it with some dragging around. With a rainbow flag emoji, there was no crash (but I did end up with a separate rainbow and flag character :D). With a two code point emoji (one of the smiley faces), it crashed.

@dnfield dnfield closed this Apr 23, 2019
@dnfield dnfield reopened this Apr 23, 2019
@dnfield
Copy link
Contributor

dnfield commented Apr 23, 2019

This actually is hitting on multiple bugs - /cc @justinmc @GaryQian @goderbauer who have all been involved in things related to this.

  • We shouldn't have the cursor be able to land in the middle of an emoji.
  • We shouldn't crash if the platform receives a message like this on iOS.

Right now I think a higher priority is to fix the crash on the engine side.

assert(isNormalized);
if(text.isNotEmpty && start > 0 && start < text.length ){
final int startCodeUnit = text.codeUnitAt(start);
if( startCodeUnit & 0x8C00 == 0x8C00 ){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we're in a multi-byte character that has more than two bytes? e.g. the rainbow flag emoji is four codepoints:

🏳 U+1F3F3
️ U+FE0F
‍ U+200D
🌈 U+1F308

In testing this issue, I was able to successfully land inside those codepoints, type a character, and split the flag into a blank flag with a rainbow. I don't think this logic would fix that scenario.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main() {
  String a='🌈';
  print(a.codeUnits.map((v)=> v.toRadixString(16)));
}

result is (d83c, df08), two characters, same as '𐐷'.

flutter using UTF-16 to handle character,

You can read the wikipedia carefully, only 2 cases, one case is 2 bytes, and the other case is 4 bytes. In flutter, it is 1 character and 2 characters. There are no other situations.

https://en.wikipedia.org/wiki/UTF-16

Copy link

@songfei songfei Apr 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am so sorry, I'm wrong.

Multi-byte characters do exist, like :

 👨‍👩‍👧  (U+1F468, U+200D, U+1F469, U+200D, U+1F467) 
 🇨🇳  (U+1F1E8, U+1F1F3)

Above code is not working.
I am try to find a new way.

@dnfield
Copy link
Contributor

dnfield commented Apr 23, 2019

See #30851 (comment) for the iOS stack trace

@dnfield
Copy link
Contributor

dnfield commented Apr 23, 2019

Crash is due to iOS not tolerating invalid UTF-8 code sequence when decoding or encoding JSON.

Looking to see if we can make platform side more resilient (Android already handles this better). We should definitely fix this on the framework side too.

@dansunhappy
Copy link
Author

I've tried this locally on an iPhone 8. I can't seem to get the cursor to land in the middle of an emoji as you're showing here. What version of Flutter are you using? I'm on master.

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel dev, v1.4.18, on Mac OS X 10.14.4 18E226, locale zh-Hans-CN)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.2)
[✓] Android Studio (version 3.3)
[!] IntelliJ IDEA Community Edition (version 2018.3.3)
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] Connected device (2 available)

@songfei
Copy link

songfei commented Apr 24, 2019

“make sure the cursor be NOT able to land in the middle of an emoji.” is better,

@dnfield
Copy link
Contributor

dnfield commented Apr 25, 2019

I'm going to close this in favor of flutter/engine#8747

Thanks for your help in diagnosing this issue!

@dnfield dnfield closed this Apr 25, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

a: typography Text rendering, possibly libtxt engine flutter/engine related. See also e: labels. f: inspector Part of widget inspector in framework. platform-ios iOS applications specifically

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants