Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crash when deleting the password in TextFormField with obscureText is true(Use the keyboard's del button) #33642

Closed
scofield-hello opened this issue May 31, 2019 · 53 comments · Fixed by flutter/engine#9322
Labels
a: text input Entering text in a text field or keyboard related problems c: crash Stack traces logged to the console c: regression It was better in the past than it is now engine flutter/engine repository. See also e: labels. platform-android Android applications specifically

Comments

@scofield-hello
Copy link

Form(
      key: formGlobalKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          TextFormField(
              decoration: const InputDecoration(
                hintText: "设置您的密码",
                labelText: "密码",
              ),
              maxLength: 16,
              obscureText: true,
              keyboardType: TextInputType.text,
              focusNode: passwordFocusNode,
              textInputAction: TextInputAction.next,
              controller: passwordController,
              validator: (value) {
                return passwordRegExp.hasMatch(value) ? null : "密码至少6位字符";
              },
              onFieldSubmitted: (value) {
                FocusScope.of(context).requestFocus(confirmFocusNode);
              }),
          TextFormField(
              decoration: const InputDecoration(
                hintText: "再次确认您的密码",
                labelText: "确认密码",
              ),
              maxLength: 16,
              obscureText: true,
              focusNode: confirmFocusNode,
              keyboardType: TextInputType.text,
              textInputAction: TextInputAction.done,
              controller: confirmController,
              validator: (value) {
                if (passwordRegExp.hasMatch(value)) {
                  if (passwordController.text != value) {
                    return "两次输入的密码不一致";
                  }
                } else {
                  return "密码至少6位字符";
                }
                return null;
              },
              onFieldSubmitted: (value) {
                FocusScope.of(context).unfocus();
              }),
          Padding(
              padding: EdgeInsets.only(top: 5.0),
              child: PrimaryButton(text: "下一步", onPressed: _onFormSubmit)),
        ],
      ),
    );

error message:

E/AndroidRuntime(13559): java.lang.IndexOutOfBoundsException: getChars (0 ... 6) ends beyond length 5
E/AndroidRuntime(13559): at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1018)
E/AndroidRuntime(13559): at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:915)
E/AndroidRuntime(13559): at android.text.SpannableStringBuilder.getTextRunCursor(SpannableStringBuilder.java:1270)
E/AndroidRuntime(13559): at android.graphics.Paint.getTextRunCursor(Paint.java:2082)
E/AndroidRuntime(13559): at android.text.TextLine.getOffsetBeforeAfter(TextLine.java:676)
E/AndroidRuntime(13559): at android.text.TextLine.getOffsetToLeftRightOf(TextLine.java:520)
E/AndroidRuntime(13559): at android.text.Layout.getOffsetToLeftRightOf(Layout.java:1244)
E/AndroidRuntime(13559): at android.text.Layout.getOffsetToLeftOf(Layout.java:1190)
E/AndroidRuntime(13559): at android.text.Selection.extendLeft(Selection.java:321)
E/AndroidRuntime(13559): at io.flutter.plugin.editing.InputConnectionAdaptor.sendKeyEvent(InputConnectionAdaptor.java:155)
E/AndroidRuntime(13559): at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:371)
E/AndroidRuntime(13559): at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:78)
E/AndroidRuntime(13559): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(13559): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(13559): at android.app.ActivityThread.main(ActivityThread.java:5418)
E/AndroidRuntime(13559): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(13559): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(13559): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1037)
E/AndroidRuntime(13559): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)


Running flutter doctor...
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel dev, v1.6.5, on Microsoft Windows [Version 10.0.17763.503], locale zh-CN)
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Android Studio (version 3.4)
[!] VS Code, 64-bit edition (version 1.33.1)
X Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[√] Connected device (1 available)

! Doctor found issues in 1 category.

@HansMuller HansMuller added a: text input Entering text in a text field or keyboard related problems f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. c: crash Stack traces logged to the console labels May 31, 2019
@HansMuller
Copy link
Contributor

CC @justinmc @GaryQian

@justinmc
Copy link
Contributor

I couldn't reproduce this. @scofield-hello Can you confirm whether my code and gif below is what you are doing when you see the crash?

password_crash

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Demo Home Page'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Form(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    TextFormField(
                        decoration: const InputDecoration(
                          hintText: "设置您的密码",
                          labelText: "密码",
                        ),
                        maxLength: 16,
                        obscureText: true,
                        keyboardType: TextInputType.text,
                        focusNode: FocusNode(),
                        textInputAction: TextInputAction.next,
                        validator: (value) {
                          return null;
                        },
                        onFieldSubmitted: (value) {
                        }),
                    TextFormField(
                        decoration: const InputDecoration(
                          hintText: "再次确认您的密码",
                          labelText: "确认密码",
                        ),
                        maxLength: 16,
                        obscureText: true,
                        focusNode: FocusNode(),
                        keyboardType: TextInputType.text,
                        textInputAction: TextInputAction.done,
                        validator: (value) {
                          return null;
                        },
                        onFieldSubmitted: (value) {
                          FocusScope.of(context).unfocus();
                        }),
                    Padding(
                        padding: EdgeInsets.only(top: 5.0),
                        child: FlatButton(child: Text("下一步"), onPressed: () {}),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

@justinmc justinmc added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 31, 2019
@GaryQian
Copy link
Contributor

GaryQian commented Jun 1, 2019

I have found that changing the keyboard language can make a difference. Maybe change to a chinese keyboard?

@scofield-hello
Copy link
Author

I tested it again, it only happened when i use TextEditingController with a defalt text.

  final TextEditingController passwordController = TextEditingController(text: "123456");
  
  Widget build(BuildContext context) {
   ......
  }

@no-response no-response bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jun 3, 2019
@scofield-hello
Copy link
Author

@justinmc you can try TextEditingController with a default text

@anythingth2
Copy link

anythingth2 commented Jun 3, 2019

My app also crashed with this error message
E/AndroidRuntime( 9438): FATAL EXCEPTION: main E/AndroidRuntime( 9438): Process: com.meclaim, PID: 9438 E/AndroidRuntime( 9438): java.lang.IndexOutOfBoundsException: getChars (0 ... 457) ends beyond length 456 E/AndroidRuntime( 9438): at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1309) E/AndroidRuntime( 9438): at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:1191) E/AndroidRuntime( 9438): at android.text.SpannableStringBuilder.getTextRunCursor(SpannableStringBuilder.java:1563) E/AndroidRuntime( 9438): at android.graphics.Paint.getTextRunCursor(Paint.java:2542) E/AndroidRuntime( 9438): at android.text.TextLine.getOffsetBeforeAfter(TextLine.java:769) E/AndroidRuntime( 9438): at android.text.TextLine.getOffsetToLeftRightOf(TextLine.java:612) E/AndroidRuntime( 9438): at android.text.Layout.getOffsetToLeftRightOf(Layout.java:1682) E/AndroidRuntime( 9438): at android.text.Layout.getOffsetToLeftOf(Layout.java:1628) E/AndroidRuntime( 9438): at android.text.Selection.extendLeft(Selection.java:321) E/AndroidRuntime( 9438): at io.flutter.plugin.editing.InputConnectionAdaptor.sendKeyEvent(InputConnectionAdaptor.java:155) E/AndroidRuntime( 9438): at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:436) E/AndroidRuntime( 9438): at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:85) E/AndroidRuntime( 9438): at android.os.Handler.dispatchMessage(Handler.java:106) E/AndroidRuntime( 9438): at android.os.Looper.loop(Looper.java:166) E/AndroidRuntime( 9438): at android.app.ActivityThread.main(ActivityThread.java:6737) E/AndroidRuntime( 9438): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime( 9438): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441) E/AndroidRuntime( 9438): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

I found this error when using voice-to-text by google keyboard.

@justinmc
Copy link
Contributor

justinmc commented Jun 3, 2019

I tried with a controller and default text and couldn't reproduce it. I also tried a Chinese keyboard, but it doesn't seem to allow Chinese characters to be typed in the field anyway.

I was able to reproduce it using voice typing though! In a plain TextField(), I entered "hello world" with my voice, then deleted a few characters with the keyboard, and got this crash:

D/AndroidRuntime(11208): Shutting down VM
E/AndroidRuntime(11208): FATAL EXCEPTION: main
E/AndroidRuntime(11208): Process: com.example.password_deletion_crash, PID: 11208
E/AndroidRuntime(11208): java.lang.IndexOutOfBoundsException: getChars (0 ... 11) ends beyond length 10
E/AndroidRuntime(11208): 	at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1321)
E/AndroidRuntime(11208): 	at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:1202)
E/AndroidRuntime(11208): 	at android.text.SpannableStringBuilder.getTextRunCursor(SpannableStringBuilder.java:1574)
E/AndroidRuntime(11208): 	at android.graphics.Paint.getTextRunCursor(Paint.java:2503)
E/AndroidRuntime(11208): 	at android.text.TextLine.getOffsetBeforeAfter(TextLine.java:788)
E/AndroidRuntime(11208): 	at android.text.TextLine.getOffsetToLeftRightOf(TextLine.java:631)
E/AndroidRuntime(11208): 	at android.text.Layout.getOffsetToLeftRightOf(Layout.java:1733)
E/AndroidRuntime(11208): 	at android.text.Layout.getOffsetToLeftOf(Layout.java:1679)
E/AndroidRuntime(11208): 	at android.text.Selection.extendLeft(Selection.java:392)
E/AndroidRuntime(11208): 	at io.flutter.plugin.editing.InputConnectionAdaptor.sendKeyEvent(InputConnectionAdaptor.java:152)
E/AndroidRuntime(11208): 	at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:436)
E/AndroidRuntime(11208): 	at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:85)
E/AndroidRuntime(11208): 	at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(11208): 	at android.os.Looper.loop(Looper.java:193)
E/AndroidRuntime(11208): 	at android.app.ActivityThread.main(ActivityThread.java:6718)
E/AndroidRuntime(11208): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(11208): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/AndroidRuntime(11208): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

@scofield-hello
Copy link
Author

@justinmc you can try the code bellow, thank you for helping me.

class PwdInitializeForm extends StatefulWidget {
  PwdInitializeForm({Key key, this.onSubmit}) : super(key: key);

  final ArgsVoidCallback onSubmit;

  @override
  _PwdInitializeFormState createState() => _PwdInitializeFormState();
}

class _PwdInitializeFormState extends State<PwdInitializeForm> {
  final GlobalKey<FormState> formGlobalKey = GlobalKey();
  final TextEditingController passwordController = TextEditingController(text: "123456");
  final TextEditingController confirmController = TextEditingController(text: "123456");
  final FocusNode passwordFocusNode = FocusNode();
  final FocusNode confirmFocusNode = FocusNode();
  final RegExp passwordRegExp = RegExp(r'[0-9a-zA-Z]{6,16}');

  @override
  Widget build(BuildContext context) {
    return Form(
      key: formGlobalKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          TextFormField(
              decoration: const InputDecoration(
                hintText: "设置您的密码",
                labelText: "密码",
              ),
              maxLength: 16,
              obscureText: true,
              keyboardType: TextInputType.text,
              focusNode: passwordFocusNode,
              textInputAction: TextInputAction.next,
              controller: passwordController,
              validator: (value) {
                return passwordRegExp.hasMatch(value) ? null : "密码至少6位字符";
              },
              onFieldSubmitted: (value) {
                FocusScope.of(context).requestFocus(confirmFocusNode);
              }),
          TextFormField(
              decoration: const InputDecoration(
                hintText: "再次确认您的密码",
                labelText: "确认密码",
              ),
              maxLength: 16,
              obscureText: true,
              focusNode: confirmFocusNode,
              keyboardType: TextInputType.text,
              textInputAction: TextInputAction.done,
              controller: confirmController,
              validator: (value) {
                if (passwordRegExp.hasMatch(value)) {
                  if (passwordController.text != value) {
                    return "两次输入的密码不一致";
                  }
                } else {
                  return "密码至少6位字符";
                }
                return null;
              },
              onFieldSubmitted: (value) {
                FocusScope.of(context).unfocus();
              }),
          Padding(
              padding: EdgeInsets.only(top: 5.0),
              child: PrimaryButton(text: "下一步", onPressed: _onFormSubmit)),
        ],
      ),
    );
  }

  void _onFormSubmit() {
    var formState = formGlobalKey.currentState;
    if (formState.validate()) {
      formState.save();
      if (widget.onSubmit != null) {
        var pwd = passwordController.text;
        var rePwd = confirmController.text;
        var pwdInitializeData = PwdInitializeData(pwd: pwd, rePwd: rePwd);
        widget.onSubmit(pwdInitializeData);
      }
    }
  }
}

@qiaolin-pan
Copy link

qiaolin-pan commented Jun 4, 2019

@justinmc Only crashes when running for the first time, but hot restart works well .
try the code bellow: flutter run -> crash

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Demo Home Page'),
        ),
        body: Center(
          child: TextFormField(
              controller: TextEditingController(text: 'aaaa'),
              decoration: const InputDecoration(
                hintText: "设置您的密码",
                labelText: "密码",
              ),
              maxLength: 16,
              obscureText: true,
              keyboardType: TextInputType.text,
              focusNode: FocusNode(),
              textInputAction: TextInputAction.next,
              validator: (value) {
                return null;
              },
              onFieldSubmitted: (value) {}),
        ),
      ),
    );
  }
}

@justinmc
Copy link
Contributor

justinmc commented Jun 5, 2019

Can anyone reproduce this on the master channel? I can't reproduce it using the code samples above. The voice typing crash isn't even happening anymore...

@qiaolin-pan
Copy link

qiaolin-pan commented Jun 6, 2019

@justinmc I am sure it still happens on the master channel,I can use the above example code to reproduce every time. Please note that it only crashes when you flutter run.

  1. using the code samples above
  2. flutter run (not hot restart)
  3. delete the password and it will crash
    I don't know if it will happen on the Android emulator, but it will happen on my real Android device.

@qiaolin-pan
Copy link

qiaolin-pan commented Jun 6, 2019

@scofield-hello I did not use Sogou Input keyboard, but it also crashed. 我用的是华为自带的键盘输入法。
你能不能试试我上面的代码,然后按照我写的步骤尝试一下,看看会不会闪退。只有flutter run会闪退。

@scofield-hello
Copy link
Author

@pakyo-pan 我在两台手机上测试了,一台是VIVO手机, 用的VIVO输入法,不用flutter run也会闪退。
在小米8上,默认使用小米安全键盘,没有闪退

@scofield-hello
Copy link
Author

@justinmc I have tested it on two devices with two different Input Keyboard app, one crashed and the other one was just fine. can you try some different kind of Input Keyboard app ?

@justinmc
Copy link
Contributor

justinmc commented Jun 6, 2019

I was just able to reproduce the voice typing crash on a Samsung Galaxy S6 on master. I said some words, pressed the "X" button to close voice typing and return to the original keyboard, and then I pressed delete twice. Seems to consistently crash. Also to note, the delete key on the voice typing keyboard doesn't seem to work at all, which may be related.

I still couldn't reproduce the crash just by deleting the existing text or typing and deleting. I tried the default Chinese keyboard on the S6, and I made sure I directly ran "flutter run" rather than hot reloading. I will try again on a Huawei phone later.

@GaryQian Do you have any idea where to start based on the stack trace above? It's coming from Android (SpannableStringBuilder.java) and only mentions one line from Flutter (io.flutter.plugin.editing.InputConnectionAdaptor.sendKeyEvent(InputConnectionAdaptor.java:152)).

@GaryQian
Copy link
Contributor

GaryQian commented Jun 7, 2019

flutter/engine#8956 this PR deals with handling of backspace on Android. It may be a good place to start looking. I do remember that this code path was only triggered for certain keyboards (gboard chinese used this code path, not gboard english). This issue may be relevant too: #23496

@justinmc
Copy link
Contributor

justinmc commented Jun 7, 2019

Thank you for the pointers!

@dmskys
Copy link

dmskys commented Jun 11, 2019

I also had the same problem, and only had 8.1 Android on the Millet phone.
Keyboard defaults to millet safety keyboard
My operation step is to input the user name, click the password, click the user name to delete, delete two characters and start flashing back.
I found no flicker without using millet safety keyboard
Gif graphs are a little bit more likely to take some time to wait
1560263785907

[✓] Flutter (Channel beta, v1.6.3, on Mac OS X 10.14.5 18F132, 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.1)
[✓] Android Studio (version 3.4)
[✓] VS Code (version 1.35.0)
[✓] Connected device (2 available)

E/AndroidRuntime(14015): Process: com.example.demo, PID: 14015
E/AndroidRuntime(14015): java.lang.IndexOutOfBoundsException: getChars (0 ... 11) ends beyond length 10
E/AndroidRuntime(14015): at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1309)
E/AndroidRuntime(14015): at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:1191)
E/AndroidRuntime(14015): at android.text.SpannableStringBuilder.getTextRunCursor(SpannableStringBuilder.java:1563)
E/AndroidRuntime(14015): at android.graphics.Paint.getTextRunCursor(Paint.java:2509)
E/AndroidRuntime(14015): at android.text.TextLine.getOffsetBeforeAfter(TextLine.java:769)
E/AndroidRuntime(14015): at android.text.TextLine.getOffsetToLeftRightOf(TextLine.java:612)
E/AndroidRuntime(14015): at android.text.Layout.getOffsetToLeftRightOf(Layout.java:1682)
E/AndroidRuntime(14015): at android.text.Layout.getOffsetToLeftOf(Layout.java:1628)
E/AndroidRuntime(14015): at android.text.Selection.extendLeft(Selection.java:321)
E/AndroidRuntime(14015): at io.flutter.plugin.editing.InputConnectionAdaptor.sendKeyEvent(InputConnectionAdaptor.java:155)
E/AndroidRuntime(14015): at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:436)
E/AndroidRuntime(14015): at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:85)
E/AndroidRuntime(14015): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(14015): at android.os.Looper.loop(Looper.java:176)
E/AndroidRuntime(14015): at android.app.ActivityThread.main(ActivityThread.java:6651)
E/AndroidRuntime(14015): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(14015): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
E/AndroidRuntime(14015): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
I/zygote64(14015): Do partial code cache collection, code=61KB, data=41KB
I/zygote64(14015): After code cache collection, code=61KB, data=41KB
I/zygote64(14015): Increasing code cache capacity to 256KB
I/Process (14015): Sending signal. PID: 14015 SIG: 9
Lost connection to device.

@ck227
Copy link

ck227 commented Jun 13, 2019

any solution here?

@GaryQian
Copy link
Contributor

flutter/engine#9322 This may be part of the solution.

@ck227
Copy link

ck227 commented Jun 14, 2019

i downgrade my flutter version from 1.6.3 beta to 1.2.1 stable, issue solved.

@justinmc justinmc added the c: regression It was better in the past than it is now label Jun 17, 2019
@justinmc
Copy link
Contributor

Tagging this as a regression since the old version fixed this.

@GaryQian GaryQian reopened this Jun 26, 2019
@GaryQian GaryQian added platform-android Android applications specifically engine flutter/engine repository. See also e: labels. and removed f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels Jun 26, 2019
@GaryQian
Copy link
Contributor

I tried it on a Huawei P8 and was not able to repro, but we are currently working on obtaining a more complete suite of test Huawei and Xiaomi devices in order to better deal with issues like this.

I believe this can indeed happen, but it seems it is on a very specific subset of devices and configurations. I will try to figure out what those conditions are. In the meantime, if you have any additional information on what devices/environments this repros on, it would be very helpful!

@scofield-hello
Copy link
Author

scofield-hello commented Jul 2, 2019

@GaryQian Thank you for helping us. My client told me the problem still exists on Huawei honour V8, it may help you to solve the problem.

@GaryQian
Copy link
Contributor

GaryQian commented Jul 2, 2019

We are currently sourcing the appropriate devices needed to properly reproduce this. We have tried on a few modern Huawei flagships, but did not see this crash. We are working on obtaining older Huawei devices with Chinese firmware.

Do you think you could check if this crash happens when obscureText is set to false? This can help me narrow it down so that I can fix this without a full repro.

@qiaolin-pan
Copy link

@GaryQian This crash does not happen when obscureText is set to false.

@qiaolin-pan
Copy link

is there any progress?

@githubjin
Copy link

githubjin commented Jul 8, 2019

I tried on XiaoMi 5s
image

image

This exception occurs on my login page with two TextFormFields, ObscureText of first is set to false, the other obscureText is set to true. I filled the two TextFormFields one by one, then switched to first one and pressed on delete button, crashed!!!

@GaryQian
Copy link
Contributor

GaryQian commented Jul 8, 2019

Thanks for the additional data points, I should be able to repro this (hopefully) by tomorrow as we have acquired the exact devices and configurations mentioned here.

I suspect this is caused by certain glyphs being condensed into one single obscured "dot", making the underlying text buffer longer than the actual displayed text.

@GaryQian
Copy link
Contributor

GaryQian commented Jul 9, 2019

I have been able to repro on a Huawei Nova 4 VCE-AL00

@CaiJingLong
Copy link
Contributor

CaiJingLong commented Jul 9, 2019

I'm also meet the problem on android device.
I'm use the new latest version of stable.

flutter doctor -v
[✓] Flutter (Channel stable, v1.7.8+hotfix.2, on Mac OS X 10.13.6 17G65, locale zh-Hans-CN)
    • Flutter version 1.7.8+hotfix.2 at /Users/cai/fluttersdk/flutter
    • Framework revision 2e540931f7 (7 days ago), 2019-07-02 09:31:07 -0700
    • Engine revision b1cb0d9e9b
    • Dart version 2.4.0


[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/cai/Library/Android/sdk
    • Android NDK at /Users/cai/Library/Android/sdk/ndk-bundle
    • Platform android-Q, build-tools 28.0.3
    • ANDROID_HOME = /Users/cai/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 10.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.1, Build version 10B61
    • CocoaPods version 1.7.1

[✓] iOS tools - develop for iOS devices
    • ios-deploy 1.9.4

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 36.0.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[✓] IntelliJ IDEA Ultimate Edition (version 2018.2.5)
    • IntelliJ at /Users/cai/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 31.3.3
    • Dart plugin version 182.5215

[✓] VS Code (version 1.36.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.2.0

[✓] Connected device (1 available)
    • MI 8 • b6ec3684 • android-arm64 • Android 9 (API 28)

• No issues found!
D/AndroidRuntime(27135): Shutting down VM
E/AndroidRuntime(27135): FATAL EXCEPTION: main
E/AndroidRuntime(27135): Process: top.kikt.example, PID: 27135
E/AndroidRuntime(27135): java.lang.IndexOutOfBoundsException: getChars (0 ... 2) ends beyond length 1
E/AndroidRuntime(27135): 	at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1321)
E/AndroidRuntime(27135): 	at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:1202)
E/AndroidRuntime(27135): 	at android.text.SpannableStringBuilder.getTextRunCursor(SpannableStringBuilder.java:1574)
E/AndroidRuntime(27135): 	at android.graphics.Paint.getTextRunCursor(Paint.java:2503)
E/AndroidRuntime(27135): 	at android.text.TextLine.getOffsetBeforeAfter(TextLine.java:788)
E/AndroidRuntime(27135): 	at android.text.TextLine.getOffsetToLeftRightOf(TextLine.java:631)
E/AndroidRuntime(27135): 	at android.text.Layout.getOffsetToLeftRightOf(Layout.java:1733)
E/AndroidRuntime(27135): 	at android.text.Layout.getOffsetToLeftOf(Layout.java:1679)
E/AndroidRuntime(27135): 	at android.text.Selection.extendLeft(Selection.java:392)
E/AndroidRuntime(27135): 	at io.flutter.plugin.editing.InputConnectionAdaptor.sendKeyEvent(InputConnectionAdaptor.java:174)
E/AndroidRuntime(27135): 	at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:436)
E/AndroidRuntime(27135): 	at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:85)
E/AndroidRuntime(27135): 	at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(27135): 	at android.os.Looper.loop(Looper.java:201)
E/AndroidRuntime(27135): 	at android.app.ActivityThread.main(ActivityThread.java:6806)
E/AndroidRuntime(27135): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(27135): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
E/AndroidRuntime(27135): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

@GaryQian
Copy link
Contributor

flutter/engine#9734 The problem seems to be deeper within Huawei's fork of Android. The PR above should prevent crashing, but introduces a much less serious bug where deletion will delete more characters than expected when the text is longer than the initial contents.

@CaiJingLong
Copy link
Contributor

CaiJingLong commented Jul 10, 2019

I upgrade version to 1.7.8+hotfix.3. And run will crash.

It seems to be caused by the "security keyboard".
It can also be seen through my recording screen: In the state of the security keyboard, it is a black screen, and even the recording screen of the system can not get the state of the current screen.
So I guess maybe flutter can't get the current state or keyboard focus monitor, which causes the text length of flutter to get the input box is incorrect.

My record video url: https://drive.google.com/file/d/1jJRTjHvXu1bmSaannWfEtlGD8Q-VTMoJ/view?usp=sharing

And I not use the security keyboard, no crash.

No crash video: https://drive.google.com/file/d/1tUrJoEptlSCjAUThqUvJ3PHtePczpFLD/view?usp=sharing

@yohom
Copy link

yohom commented Jul 10, 2019

When this bug is fixed, can it be merged into version 1.7? @GaryQian

@GaryQian
Copy link
Contributor

Some keyboards will trigger the engine's version of backspace handling. Turns out it is not unique to Huawei devices, but the fix above should prevent this particular crash in all devices.

1.7 is already released. I can see if it can be hotfixed, but it is unlikely to make it into the 1.7 stable release, especially since this is an engine change.

@ryanheise
Copy link

FYI, I encountered this bug on the Pixel 3a when switching to the Google Japanese Input keyboard and then either pressing space or backspace, but it went away after running flutter upgrade today (beta channel).

@robin12210325
Copy link

version error ,use 1.5,The latest 1.7 will report this error.

@GaryQian
Copy link
Contributor

The fix has landed. Please check the master and dev channels to get the fix. Closing this issue. Please let me know if anyone is still experiencing the crash and I will be happy to repoen.

There is a new known bug where backspace will delete too many characters, but we should track that separately. #36007

@kf6gpe
Copy link
Contributor

kf6gpe commented Jul 22, 2019

This issue has been patched into the latest stable release, which is baking in the beta channel presently. We anticipate pushing a release with this patched fix to the stable channel later this week.

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: text input Entering text in a text field or keyboard related problems c: crash Stack traces logged to the console c: regression It was better in the past than it is now engine flutter/engine repository. See also e: labels. platform-android Android applications specifically
Projects
None yet
Development

Successfully merging a pull request may close this issue.