New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 766925 link

Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Sep 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 3
Type: Bug

Blocking:
issue 766680



Sign in to add a comment

[FATAL:PlainTextRange.h(54)] Check failed: IsNotNull() in InputMethodController::SetComposition()

Project Member Reported by rlanday@chromium.org, Sep 20 2017

Issue description

Chrome Version: 63.0.3220.0
OS: Android

What steps will reproduce the problem?
(1) Load the attached file (sample_minimized.html) onto a DCHECK-enabled Android device and open it in Chrome
(2) Long press and hit "select all"
(3) Type some text using the Swype keyboard

This DCHECK gets hit:
[FATAL:PlainTextRange.h(54)] Check failed: IsNotNull() in InputMethodController::SetComposition

right here when InputMethodController::SetComposition() tries to call AddImeTextSpans():
https://chromium.googlesource.com/chromium/src/+/703c6b6cf1bcd212168721e72bc79b4afacb370e/third_party/WebKit/Source/core/editing/InputMethodController.cpp#747

The fix might just be to check if the PlainTextRange is valid before trying to call AddImeTextSpans(). However, I think the root of the issue is that InsertIncrementalTextCommand is behaving oddly.

If I force a non-incremental text replacement (e.g. by making NeedsIncrementalInsertion() in InputMethodController.cpp return false), the bug does not occur, and all characters I type go inside the <a> element. However, with an incremental text insertion, the first character goes inside the <a> (assume I'm trying to type "Hello"):

<a>H</a>

So right now the composition is on "H". Then when I type the second character ("e"), Swype tries to replace the composition range with "He". This triggers an incremental text insert. InsertIncrementalTextCommand figures out we only need to insert the the "e" and sets the "ending selection" for the edit command (basically, the text that's going to be replaced) as a caret selection right after the "H":

<a>H|</a>

Now InsertTextCommand::DoApply() comes along and starts trying to insert the "e" (the incremental update computed by InsertIncrementalTextCommand). This goes fine until we run start_position (the start of the "ending selection") through PositionAvoidingSpecialElementBoundary():
https://chromium.googlesource.com/chromium/src/+/be35f28174767a1cd71f3614e1f3ec6ce4e1f0e8/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp#231

This moves the start position to be immediately *after* the <a> element.

The description of this method is "Operations use this function to avoid inserting content into an anchor when at the start or the end of that anchor, as in NSTextView." So I think we have two problems here:

1. This means the behavior of InsertIncrementalTextCommand is different from the behavior of InsertTextCommand in this situation (the first character goes in the <a> element, and all subsequent characters go outside, which I don't think is intended).

2. After the text is inserted *outside* the <a> element, the composition range now spans multiple text nodes, and in particular, is no longer contained in the <a> element we're expecting it to be contained in when we create the PlainTextRange to pass to AddImeTextSpans(). So I think that's why we're hitting an error there.
 
sample_minimized.html
414 bytes View Download
Note: the issue only repros in Swype and not Gboard because Swype directly issues a setComposingText() call to replace the selection. Gboard does a few additional commands to delete the selected text before replacing it.
Blocking: 766680
Attaching another case that triggers problem 2 (since it makes the composition underline span multiple nodes). This definitely needs a fix of its own.
incremental_tests.html
63 bytes View Download
Project Member

Comment 4 by bugdroid1@chromium.org, Sep 21 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/abadaa9269ad0ede8d1dec0ba672c9f93bb8f689

commit abadaa9269ad0ede8d1dec0ba672c9f93bb8f689
Author: Ryan Landay <rlanday@chromium.org>
Date: Thu Sep 21 17:39:25 2017

Fix Android composition underlines when word spans multiple nodes

If an Android IME tries to call InputMethodController::SetComposition() with a
non-empty list of composition marker on a range where the parent node of the
start position of the range doesn't contain the whole composition range, we fail
to properly construct the PlainTextRange we use to figure out where to put the
markers. This makes a DCHECK fail in debug builds, and fails to add the
composition underlines in release builds. This CL fixes the issue by properly
finding the root editable element to construct the PlainTextRange.

Note that the composition underline shows gaps between each text node. This is
a UI decision that we may want to revisit or revise at some point.

Bug:  766925 
Change-Id: I25c3293b50f66d15c13cab0b54dcfee3b6abd4f2
Reviewed-on: https://chromium-review.googlesource.com/676189
Reviewed-by: Changwan Ryu <changwan@chromium.org>
Commit-Queue: Ryan Landay <rlanday@chromium.org>
Cr-Commit-Position: refs/heads/master@{#503495}
[modify] https://crrev.com/abadaa9269ad0ede8d1dec0ba672c9f93bb8f689/third_party/WebKit/Source/core/editing/InputMethodController.cpp
[modify] https://crrev.com/abadaa9269ad0ede8d1dec0ba672c9f93bb8f689/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp

Comment 5 by yosin@chromium.org, Sep 22 2017

Status: Fixed (was: Untriaged)
Mark Fixed per #c4

Sign in to add a comment