Bug 199960

Summary: [iOS] ASSERTION FAILURE: !isMissingPostLayoutData in WebKit::EditorState::postLayoutData()
Product: WebKit Reporter: Daniel Bates <dbates>
Component: WebKit Misc.Assignee: Daniel Bates <dbates>
Status: RESOLVED FIXED    
Severity: Normal CC: aperez, berto, cgarcia, darin, ews-watchlist, gustavo, mcatanzaro, megan_gardner, simon.fraser, thorton, webkit-bug-importer, wenson_hsieh
Priority: P2 Keywords: InRadar, PlatformOnly
Version: WebKit Local Build   
Hardware: iPhone / iPad   
OS: iOS 12   
URL: data:text/html,<textarea%20placeholder="Type%20w%20then%20press%20backspace"%20onkeydown="document.getElementById('output').value%20=%20document.getElementById('output').value%20+%20'\n'"></textarea><textarea%20id="output"%20readonly></textarea>
See Also: https://bugs.webkit.org/show_bug.cgi?id=200399
https://bugs.webkit.org/show_bug.cgi?id=200400
https://bugs.webkit.org/show_bug.cgi?id=209570
Bug Depends on: 201608    
Bug Blocks: 209570    
Attachments:
Description Flags
Patch and layout test
none
Patch and layout test
none
Patch and layout test - encoded in enum
none
Patch and layout test
none
Patch and layout test
none
Patch and layout test
none
Patch and layout test
none
Patch
none
Patch
none
To Land
none
To Land
none
To Land
none
Attempt to fix GTK none

Daniel Bates
Reported 2019-07-19 14:28:42 PDT
Steps to reproduce: (Use the software keyboard) 1. Visit <data:text/html,<textarea%20placeholder="Type%20w%20then%20press%20backspace"%20onkeydown="document.getElementById('output').value%20=%20document.getElementById('output').value%20+%20'\n'"></textarea><textarea%20id="output"%20readonly></textarea>>. 2. Focus the first textarea and press w then press the backspace. Then the WebContent process will crash because the ASSERT_WITH_MESSAGE(!isMissingPostLayoutData, "Attempt to access post layout data before receiving it") fails in WebKit::EditorState::postLayoutData().
Attachments
Patch and layout test (8.24 KB, patch)
2019-07-19 14:54 PDT, Daniel Bates
no flags
Patch and layout test (8.39 KB, patch)
2019-07-19 15:29 PDT, Daniel Bates
no flags
Patch and layout test - encoded in enum (27.44 KB, patch)
2019-07-22 14:29 PDT, Daniel Bates
no flags
Patch and layout test (27.80 KB, patch)
2019-07-22 14:35 PDT, Daniel Bates
no flags
Patch and layout test (27.79 KB, patch)
2019-07-22 14:49 PDT, Daniel Bates
no flags
Patch and layout test (28.39 KB, patch)
2019-07-26 10:54 PDT, Daniel Bates
no flags
Patch and layout test (28.41 KB, patch)
2019-08-22 14:58 PDT, Daniel Bates
no flags
Patch (27.37 KB, patch)
2020-03-18 13:51 PDT, Daniel Bates
no flags
Patch (31.50 KB, patch)
2020-03-18 13:55 PDT, Daniel Bates
no flags
To Land (27.61 KB, patch)
2020-03-24 16:04 PDT, Daniel Bates
no flags
To Land (27.60 KB, patch)
2020-03-24 19:54 PDT, Daniel Bates
no flags
To Land (28.60 KB, patch)
2020-03-24 23:14 PDT, Daniel Bates
no flags
Attempt to fix GTK (34.31 KB, patch)
2020-03-25 00:21 PDT, Daniel Bates
no flags
Radar WebKit Bug Importer
Comment 1 2019-07-19 14:28:57 PDT
Daniel Bates
Comment 2 2019-07-19 14:30:07 PDT
Backtrace has the form: ASSERTION FAILED: Attempt to access post layout data before receiving it !isMissingPostLayoutData /Volumes/.../OpenSource/Source/WebKit/Shared/EditorState.h(150) : const WebKit::EditorState::PostLayoutData &WebKit::EditorState::postLayoutData() const 1 0x111c5e1c9 WTFCrash 2 0x11684e6db WebKit::EditorState::postLayoutData() const 3 0x11773b7f9 -[WKContentView(WKInteraction) _characterBeforeCaretSelection] ... 17 0x11774033d WTF::BlockPtr<void (WebEvent*, bool)>::operator()(WebEvent*, bool) const 18 0x117740195 -[WKContentView(WKInteraction) _didHandleKeyEvent:eventWasHandled:] 19 0x116d28319 WebKit::PageClientImpl::doneWithKeyEvent(WebKit::NativeWebKeyboardEvent const&, bool) 20 0x116b689f9 WebKit::WebPageProxy::didReceiveEvent(unsigned int, bool) 21 0x11750f848 void IPC::callMemberFunctionImpl<WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(unsigned int, bool), std::__1::tuple<unsigned int, bool>, 0ul, 1ul>(WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool), std::__1::tuple<unsigned int, bool>&&, std::__1::integer_sequence<unsigned long, 0ul, 1ul>) 22 0x11750f780 void IPC::callMemberFunction<WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(unsigned int, bool), std::__1::tuple<unsigned int, bool>, std::__1::integer_sequence<unsigned long, 0ul, 1ul> >(std::__1::tuple<unsigned int, bool>&&, WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool)) 23 0x1174f4e2e void IPC::handleMessage<Messages::WebPageProxy::DidReceiveEvent, WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(unsigned int, bool)>(IPC::Decoder&, WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(unsigned int, bool)) 24 0x1174ecfdc WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) 25 0x1162a26f9 IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::Decoder&) 26 0x1169e7f64 WebKit::AuxiliaryProcessProxy::dispatchMessage(IPC::Connection&, IPC::Decoder&) 27 0x116c4a5fa WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) 28 0x116234e19 IPC::Connection::dispatchMessage(IPC::Decoder&) 29 0x11622d969 IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >) 30 0x116233cab IPC::Connection::dispatchIncomingMessages() 31 0x116254425 IPC::Connection::enqueueIncomingMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >)::$_11::operator()()
Daniel Bates
Comment 3 2019-07-19 14:30:27 PDT
^^^ the ... is UIKit
Daniel Bates
Comment 4 2019-07-19 14:32:45 PDT
This assertion failure only happens in Modern WebKit (read not Legacy WebKit). The reason is that Modern WebKit tries to avoid performing a layout as part of gathering editor state as a performance optimization. Legacy has no such optimization and performs a layout after handling every keydown and keyup.
Daniel Bates
Comment 5 2019-07-19 14:33:47 PDT
Also does not happen on Mac because WebCore performs text insertion/deletion and updates layout in same even loop iteration as keydown.
Daniel Bates
Comment 6 2019-07-19 14:35:50 PDT
Doesn't occur with a hardware keyboard attached on iOS because we force layout in WebPage::platformEditorState():<https://trac.webkit.org/browser/trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm?rev=247573#L224>
Daniel Bates
Comment 7 2019-07-19 14:39:18 PDT
^^^^ though this is the editor state computed when we call to UI process to interpret the key event. But this info is out-of-date since layout can change as a result of JavaScript and editor state the UI process does not have the most up-to-date details by the time the Web process tells it that the key event has been processed.
Daniel Bates
Comment 8 2019-07-19 14:44:38 PDT
We might be able to get away with ^^^^. So, not having the most up-to-date info. I coded up a fix (forthcoming) so that UI process has the most up-to-date info.
Daniel Bates
Comment 9 2019-07-19 14:54:51 PDT
Created attachment 374498 [details] Patch and layout test
Simon Fraser (smfr)
Comment 10 2019-07-19 15:09:25 PDT
Comment on attachment 374498 [details] Patch and layout test View in context: https://bugs.webkit.org/attachment.cgi?id=374498&action=review > Source/WebKit/WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:44 > + page.corePage()->focusController().focusedOrMainFrame().document()->updateLayout(); Be aware that this can run arbitrary script and destroy frames, nodes etc.
Daniel Bates
Comment 11 2019-07-19 15:11:30 PDT
Comment on attachment 374498 [details] Patch and layout test Let me think about this some more. Don't want to have this explode with security bugs. Maybe go with the stale data....
Daniel Bates
Comment 12 2019-07-19 15:29:56 PDT
Created attachment 374508 [details] Patch and layout test
Daniel Bates
Comment 13 2019-07-19 16:27:36 PDT
Going to re-encode the fix in terms of an new editorState() enum.
Daniel Bates
Comment 14 2019-07-22 14:29:30 PDT
Created attachment 374635 [details] Patch and layout test - encoded in enum
Daniel Bates
Comment 15 2019-07-22 14:32:56 PDT
The patch also removes m_isEditorStateMissingPostLayoutData in WebPage.h. This ivar has been unused since r221064 (bug #175370). Also we haven't been using IncludePostLayoutDataHint::No since the last reference to it was removed in r244494 (bug #197145).
Daniel Bates
Comment 16 2019-07-22 14:35:11 PDT
Created attachment 374637 [details] Patch and layout test
Daniel Bates
Comment 17 2019-07-22 14:49:05 PDT
Created attachment 374638 [details] Patch and layout test
Daniel Bates
Comment 18 2019-07-22 19:18:57 PDT
Forgot the expected results. Could probably use auto more at least on lines I touched. Could size the enum class to char, but since not a store type there's little value. I guess more efficient register passing and stack pack if register spill, but we're not even close to having enough args to matter.
Daniel Bates
Comment 19 2019-07-22 19:26:59 PDT
Comment on attachment 374638 [details] Patch and layout test View in context: https://bugs.webkit.org/attachment.cgi?id=374638&action=review > Source/WebKit/WebProcess/WebPage/WebPage.cpp:1015 > + Ref<Frame> frame = m_page->focusController().focusedOrMainFrame(); FYI scope of ref here is generous. Could move to above updateLayout(). I thought to be generous 😀 > Source/WebKit/WebProcess/WebPage/WebPage.cpp:1017 > + if (shouldPerformLayout == ShouldPerformLayout::Default) The ::No is only used internal to this function. There are no outside callers. Could just remove this enumerator and internally store a Boolean. Enum class could then be sized to bool (doesn't matter though), but gives less options for people to shoot themselves in the 🦶 (that's what matters). Opinions?
Daniel Bates
Comment 20 2019-07-26 10:54:40 PDT
Created attachment 374973 [details] Patch and layout test Removed enumerator ShouldPerformLayout::No; only ::Default and ::Yes now.
Daniel Bates
Comment 21 2019-08-22 14:58:22 PDT
Created attachment 377056 [details] Patch and layout test
Daniel Bates
Comment 22 2020-03-18 13:51:16 PDT
Daniel Bates
Comment 23 2020-03-18 13:55:40 PDT
Simon Fraser (smfr)
Comment 24 2020-03-18 14:50:57 PDT
Comment on attachment 393900 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=393900&action=review > Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:316 > +void WebPage::platformEditorStateCommon(const Frame& frame, EditorState& result) const This should be getEditorStateCommon or computeEditorStateCommon. > Source/WebKit/WebProcess/WebPage/WebPage.cpp:1067 > + auto& document = *frame->document(); RefPtr<Document>? > Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:237 > +void WebPage::platformEditorState(Frame& frame, EditorState& result) const get/computeEditorState. > Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm:136 > +void WebPage::platformEditorState(Frame& frame, EditorState& result) const get/compute
Daniel Bates
Comment 25 2020-03-24 15:30:23 PDT
Comment on attachment 393900 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=393900&action=review Thanks for the review. >> Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:316 >> +void WebPage::platformEditorStateCommon(const Frame& frame, EditorState& result) const > > This should be getEditorStateCommon or computeEditorStateCommon. Will use get. >> Source/WebKit/WebProcess/WebPage/WebPage.cpp:1067 >> + auto& document = *frame->document(); > > RefPtr<Document>? Will fix. >> Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:237 >> +void WebPage::platformEditorState(Frame& frame, EditorState& result) const > > get/computeEditorState. Will use get. >> Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm:136 >> +void WebPage::platformEditorState(Frame& frame, EditorState& result) const > > get/compute Will use get.
Daniel Bates
Comment 26 2020-03-24 16:04:43 PDT
Daniel Bates
Comment 27 2020-03-24 19:54:06 PDT
Daniel Bates
Comment 28 2020-03-24 23:14:36 PDT
Created attachment 394472 [details] To Land Fix up Playstation code. I still do not know what is the problem with the GTK API tests. Can someone help me?
Daniel Bates
Comment 29 2020-03-24 23:24:34 PDT
GTK API failure is buried in the output: [[ ERROR:../../Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebViewEditor.cpp:341:void testWebViewEditorEditorStateTypingAttributes(EditorTest*, gconstpointer): assertion failed (typingAttributes == WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE): (0 == 2) ]]
Daniel Bates
Comment 30 2020-03-24 23:49:23 PDT
(In reply to Daniel Bates from comment #29) > GTK API failure is buried in the output: > > [[ > ERROR:../../Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebViewEditor.cpp:341: > void testWebViewEditorEditorStateTypingAttributes(EditorTest*, > gconstpointer): assertion failed (typingAttributes == > WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE): (0 == 2) > ]] To fix this I am leaning to patch webkitEditorStateCreate() to initialize editorState->priv->typingAttributes to WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE.
Daniel Bates
Comment 31 2020-03-25 00:21:39 PDT
Created attachment 394474 [details] Attempt to fix GTK I am too tired to think this through right now, just posting a patch based on my previous comment to see what EWS thinks (since it takes some time for EWS to process a patch). Patch may not be correct.
EWS Watchlist
Comment 32 2020-03-25 00:22:20 PDT
Thanks for the patch. If this patch contains new public API please make sure it follows the guidelines for new WebKit2 GTK+ API. See http://trac.webkit.org/wiki/WebKitGTK/AddingNewWebKit2API
Adrian Perez
Comment 33 2020-03-25 02:18:43 PDT
Comment on attachment 394474 [details] Attempt to fix GTK View in context: https://bugs.webkit.org/attachment.cgi?id=394474&action=review I believe that the change to glib/WebKitEditorState.cpp are correct, but would not mind having Carlos García's rubber stamp on that ~_~ > Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:317 > + No need to add this empty line here :)
Carlos Garcia Campos
Comment 34 2020-03-25 02:39:03 PDT
(In reply to Adrian Perez from comment #33) > Comment on attachment 394474 [details] > Attempt to fix GTK > > View in context: > https://bugs.webkit.org/attachment.cgi?id=394474&action=review > > I believe that the change to glib/WebKitEditorState.cpp are correct, > but would not mind having Carlos García's rubber stamp on that ~_~ LGTM > > Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:317 > > + > > No need to add this empty line here :)
Daniel Bates
Comment 35 2020-03-25 09:48:26 PDT
Thanks Adrian and Carlos!
Daniel Bates
Comment 36 2020-03-25 09:50:35 PDT
Daniel Bates
Comment 37 2020-03-25 10:00:48 PDT
(In reply to Adrian Perez from comment #33) > Comment on attachment 394474 [details] > Attempt to fix GTK > > View in context: > https://bugs.webkit.org/attachment.cgi?id=394474&action=review > > I believe that the change to glib/WebKitEditorState.cpp are correct, > but would not mind having Carlos García's rubber stamp on that ~_~ > > > Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:317 > > + > > No need to add this empty line here :) Oops, I forgot to remove it. When I have a moment, I'll look to do so.
Daniel Bates
Comment 38 2020-03-25 10:32:41 PDT
(In reply to Daniel Bates from comment #37) > (In reply to Adrian Perez from comment #33) > > Comment on attachment 394474 [details] > > Attempt to fix GTK > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=394474&action=review > > > > I believe that the change to glib/WebKitEditorState.cpp are correct, > > but would not mind having Carlos García's rubber stamp on that ~_~ > > > > > Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:317 > > > + > > > > No need to add this empty line here :) > > Oops, I forgot to remove it. When I have a moment, I'll look to do so. Removed in <https://trac.webkit.org/changeset/258995>
Darin Adler
Comment 39 2020-03-29 14:07:54 PDT
Comment on attachment 394474 [details] Attempt to fix GTK View in context: https://bugs.webkit.org/attachment.cgi?id=394474&action=review > Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:-261 > - if ((shouldIncludePostLayoutData == IncludePostLayoutDataHint::No || needsLayout) && !requiresPostLayoutData) { > - result.isMissingPostLayoutData = true; > + if (needsLayout || result.isMissingPostLayoutData) > return; > - } This change broke the Mac Catalyst build. After this refactoring, the requiresPostLayoutData boolean local variable above is unused. In the Mac Catalyst configuration the code is simple enough that the compiler emits a warning about the unused boolean; in other configurations it doesn’t warn. I believe the fix is to remove the 4 lines of code above that define and set the value of the local variable.
Daniel Bates
Comment 40 2020-03-29 17:41:23 PDT
Comment on attachment 394474 [details] Attempt to fix GTK View in context: https://bugs.webkit.org/attachment.cgi?id=394474&action=review >> Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:-261 >> - } > > This change broke the Mac Catalyst build. > > After this refactoring, the requiresPostLayoutData boolean local variable above is unused. In the Mac Catalyst configuration the code is simple enough that the compiler emits a warning about the unused boolean; in other configurations it doesn’t warn. I believe the fix is to remove the 4 lines of code above that define and set the value of the local variable. Oops! Bad merge... Here's the fix, I got to run, but I'll try to post later: [[ diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm index 47c620d0478..fe664b6e41b 100644 --- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm +++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm @@ -260,14 +260,8 @@ void WebPage::getPlatformEditorState(Frame& frame, EditorState& result) const } // We only set the remaining EditorState entries if layout is done as a performance optimization - // to avoid the need to force a synchronous layout here to compute these entries. If we - // have a composition or are using a hardware keyboard then we send the full editor state - // immediately so that the UIProcess can update UI, including the position of the caret. + // to avoid the need to force a synchronous layout here to compute these entries. bool needsLayout = view->needsLayout(); - bool requiresPostLayoutData = frame.editor().hasComposition(); -#if !PLATFORM(MACCATALYST) - requiresPostLayoutData |= m_keyboardIsAttached; -#endif if (needsLayout || result.isMissingPostLayoutData) return; ]] Why is this the fix? Because I moved the old logic into WebPage::platformNeedsLayoutForEditorState(), which is called before this function.
Daniel Bates
Comment 41 2020-03-29 17:49:38 PDT
Comment on attachment 394474 [details] Attempt to fix GTK View in context: https://bugs.webkit.org/attachment.cgi?id=394474&action=review >>> Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:-261 >>> - } >> >> This change broke the Mac Catalyst build. >> >> After this refactoring, the requiresPostLayoutData boolean local variable above is unused. In the Mac Catalyst configuration the code is simple enough that the compiler emits a warning about the unused boolean; in other configurations it doesn’t warn. I believe the fix is to remove the 4 lines of code above that define and set the value of the local variable. > > Oops! Bad merge... Here's the fix, I got to run, but I'll try to post later: > > [[ > diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm > index 47c620d0478..fe664b6e41b 100644 > --- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm > +++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm > @@ -260,14 +260,8 @@ void WebPage::getPlatformEditorState(Frame& frame, EditorState& result) const > } > > // We only set the remaining EditorState entries if layout is done as a performance optimization > - // to avoid the need to force a synchronous layout here to compute these entries. If we > - // have a composition or are using a hardware keyboard then we send the full editor state > - // immediately so that the UIProcess can update UI, including the position of the caret. > + // to avoid the need to force a synchronous layout here to compute these entries. > bool needsLayout = view->needsLayout(); > - bool requiresPostLayoutData = frame.editor().hasComposition(); > -#if !PLATFORM(MACCATALYST) > - requiresPostLayoutData |= m_keyboardIsAttached; > -#endif > if (needsLayout || result.isMissingPostLayoutData) > return; > ]] > > Why is this the fix? Because I moved the old logic into WebPage::platformNeedsLayoutForEditorState(), which is called before this function. Got a spare minute and committed the fix in <https://trac.webkit.org/changeset/259183>.
Note You need to log in before you can comment on or make changes to this bug.