WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
208115
Nullptr crash in WebCore::canHaveChildrenForEditing via CompositeEditCommand::insertNode
https://bugs.webkit.org/show_bug.cgi?id=208115
Summary
Nullptr crash in WebCore::canHaveChildrenForEditing via CompositeEditCommand:...
Jack
Reported
2020-02-23 15:02:10 PST
<
rdar://56685655
> #0 0x6c019d821 in WebCore::Node::getFlag(WebCore::Node::NodeFlags) const (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x19b821) #1 0x6c33db02d in WebCore::canHaveChildrenForEditing(WebCore::Node const&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x33d902d) #2 0x6c339c496 in WebCore::CompositeEditCommand::insertNodeAt(WTF::Ref<WebCore::Node, WTF::DumbPtrTraits<WebCore::Node> >&&, WebCore::Position const&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x339a496) #3 0x6c3466d28 in WebCore::InsertListCommand::listifyParagraph(WebCore::VisiblePosition const&, WebCore::QualifiedName const&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3464d28) #4 0x6c34654ff in WebCore::InsertListCommand::doApplyForSingleParagraph(bool, WebCore::HTMLQualifiedName const&, WebCore::Range*) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x34634ff) #5 0x6c34647af in WebCore::InsertListCommand::doApply() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x34627af) #6 0x6c3396376 in WebCore::CompositeEditCommand::apply() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3394376) #7 0x6c344d78b in WebCore::executeInsertUnorderedList(WebCore::Frame&, WebCore::Event*, WebCore::EditorCommandSource, WTF::String const&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x344b78b) #8 0x6c30be1c7 in WebCore::Document::execCommand(WTF::String const&, bool, WTF::String const&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x30bc1c7) #9 0x6c0a33c9a in WebCore::jsDocumentPrototypeFunctionExecCommandBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSDocument*, JSC::ThrowScope&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0xa31c9a) #10 0x6c08ec150 in long long WebCore::IDLOperation<WebCore::JSDocument>::call<&(WebCore::jsDocumentPrototypeFunctionExecCommandBody(JSC::JSGlobalObject*, JSC::CallFrame*, WebCore::JSDocument*, JSC::ThrowScope&)), (WebCore::CastedThisErrorBehavior)0>(JSC::JSGlobalObject&, JSC::CallFrame&, char const*) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x8ea150) #11 0x3d778e40116a (<unknown module>) #12 0x6d9a7640c in llint_entry (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0xa3d40c) #13 0x6d9a76298 in llint_entry (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0xa3d298) #14 0x6d9a5f878 in vmEntryToJavaScript (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0xa26878) #15 0x6db0140db in JSC::Interpreter::executeCall(JSC::JSGlobalObject*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1fdb0db) #16 0x6db5d6fc0 in JSC::call(JSC::JSGlobalObject*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x259dfc0) #17 0x6db5d70c1 in JSC::call(JSC::JSGlobalObject*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x259e0c1) #18 0x6db5d749f in JSC::profiledCall(JSC::JSGlobalObject*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x259e49f) #19 0x6c29c7174 in WebCore::JSExecState::profiledCall(JSC::JSGlobalObject*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x29c5174) #20 0x6c29ef55c in WebCore::JSEventListener::handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event&) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x29ed55c) #21 0x6c31cf524 in WebCore::EventTarget::innerInvokeEventListeners(WebCore::Event&, WTF::Vector<WTF::RefPtr<WebCore::RegisteredEventListener, WTF::DumbPtrTraits<WebCore::RegisteredEventListener> >, 1ul, WTF::CrashOnOverflow, 16ul>, WebCore::EventTarget::EventInvokePhase) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x31cd524) #22 0x6c31ca7f7 in WebCore::EventTarget::fireEventListeners(WebCore::Event&, WebCore::EventTarget::EventInvokePhase) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x31c87f7) #23 0x6c3f59e37 in WebCore::DOMWindow::dispatchEvent(WebCore::Event&, WebCore::EventTarget*) (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3f57e37) #24 0x6c3f6c5cf in WebCore::DOMWindow::dispatchLoadEvent() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3f6a5cf) #25 0x6c30a603f in WebCore::Document::dispatchWindowLoadEvent() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x30a403f) #26 0x6c30a59f0 in WebCore::Document::implicitClose() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x30a39f0) #27 0x6c3d944fb in WebCore::FrameLoader::checkCompleted() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3d924fb) #28 0x6c308b978 in WebCore::Document::loadEventDelayTimerFired() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3089978) #29 0x6c3110d53 in std::__1::__bind_return<void (WebCore::Document::*)(), std::__1::tuple<WebCore::Document*>, std::__1::tuple<>, __is_valid_bind_return<void (WebCore::Document::*)(), std::__1::tuple<WebCore::Document*>, std::__1::tuple<> >::value>::type std::__1::__bind<void (WebCore::Document::*&)(), WebCore::Document*>::operator()<>() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x310ed53) #30 0x6c42a0ff5 in WebCore::ThreadTimers::sharedTimerFiredInternal() (Safari_ASAN_251639_8651f88be7c86f1fa8b4fafe3bc6b2caded79eda.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x429eff5)
Attachments
Patch
(4.10 KB, patch)
2020-02-24 16:02 PST
,
Jack
no flags
Details
Formatted Diff
Diff
Patch
(4.10 KB, patch)
2020-02-25 09:06 PST
,
Jack
no flags
Details
Formatted Diff
Diff
Patch
(4.16 KB, patch)
2020-02-25 23:32 PST
,
Jack
no flags
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Jack
Comment 1
2020-02-24 14:59:34 PST
Root cause: In this case, hr is uneditable, and the script tries to insert an ol after hr, so the code is creating a BR element and inserting it after HR. However, since hr is uneditable, the insertion fails, making the BR element parentless. and that results in an null insertionPos, and it is later referenced in canHaveChildrenForEditing. <style> body { -webkit-user-modify: read-write; background-image: url(); } </style> <script> onload = function fun() { document.getSelection().setPosition(HR); HR.appendChild(document.createElement("option")); document.execCommand("insertOrderedList", false); } </script> <body><hr id=HR contenteditable="false"></hr>
Jack
Comment 2
2020-02-24 15:21:42 PST
In debug build, it would trigger two assertions: 1. CompositeEditCommand::insertNodeAt ASSERT(isEditablePosition(editingPosition)); 2. InsertNodeBeforeCommand::InsertNodeBeforeCommand ASSERT(m_refChild->parentNode()->hasEditableStyle() || !m_refChild->parentNode()->renderer());
Jack
Comment 3
2020-02-24 16:02:46 PST
Created
attachment 391591
[details]
Patch
Ryosuke Niwa
Comment 4
2020-02-24 19:02:05 PST
Comment on
attachment 391591
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=391591&action=review
> Source/WebCore/editing/InsertListCommand.cpp:341 > - if (start.isNull() || end.isNull()) > + if (start.isNull() || end.isNull() || !start.deepEquivalent().deprecatedNode()->hasEditableStyle())
Please check the eatability of start.deepEquivalent().containerNode() instead.
Ryosuke Niwa
Comment 5
2020-02-24 19:02:20 PST
This is not a security bug.
Jack
Comment 6
2020-02-25 09:04:41 PST
Thanks! Yes, in this case the anchorType is PositionIsOffsetInAnchor, so container node is also m_anchorNode. (lldb) p anchorType() (WebCore::Position::AnchorType) $3 = PositionIsOffsetInAnchor (In reply to Ryosuke Niwa from
comment #4
)
> Comment on
attachment 391591
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=391591&action=review
> > > Source/WebCore/editing/InsertListCommand.cpp:341 > > - if (start.isNull() || end.isNull()) > > + if (start.isNull() || end.isNull() || !start.deepEquivalent().deprecatedNode()->hasEditableStyle()) > > Please check the eatability of start.deepEquivalent().containerNode() > instead.
Jack
Comment 7
2020-02-25 09:06:09 PST
Created
attachment 391660
[details]
Patch
Doug Kelly
Comment 8
2020-02-25 17:04:52 PST
Hey Jack, I just happened to notice unlistify can crash in much the same way -- does it make sense to apply the check at the level of doApply() instead? doApply() already has an early-abort for if content is not editable: if (endingSelection().isNoneOrOrphaned() || !endingSelection().isContentRichlyEditable()) return;
Ryosuke Niwa
Comment 9
2020-02-25 18:02:49 PST
Comment on
attachment 391660
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=391660&action=review
> Source/WebCore/editing/InsertListCommand.cpp:341 > - if (start.isNull() || end.isNull()) > + if (start.isNull() || end.isNull() || !start.deepEquivalent().containerNode()->hasEditableStyle())
Sorry, I forgot to point out earlier but we should probably check that the end is also editable.
Jack
Comment 10
2020-02-25 23:06:30 PST
Thanks, Doug. It is possible. However, the actual inserting position is determined later in the call stack (depending on the tag and its children and some other properties) and can change in other cases, so it can be false positives if the code returns too early. In this test case, at doApply() the endingSelection has anchor type = PositionIsBeforeAnchor, so the editability is checked on the parent of anchor node, which is <body> hence it does not return here. When it enters listifyParagraph and after startOfParagraph is called, the anchor type becomes PositionIsOffsetInAnchor so the editability is checked on the anchor node, <hr>, which is uneditable. One experiment I did was removing the child (option) of the uneditable element (hr). Even though the anchor node is the uneditable element, the code does continue and inserts ol in front of hr. It sort of makes sense since if there is nothing to be "listified" inside <hr>, it is not considered "editing" <hr>? (In reply to Doug Kelly from
comment #8
)
> Hey Jack, > > I just happened to notice unlistify can crash in much the same way -- does > it make sense to apply the check at the level of doApply() instead? > > doApply() already has an early-abort for if content is not editable: > > if (endingSelection().isNoneOrOrphaned() || > !endingSelection().isContentRichlyEditable()) > return;
Jack
Comment 11
2020-02-25 23:29:07 PST
Thanks! I thought about it but wondered if it is okay to listify contents if only the end is uneditable. Definitely it is more important to prevent crash! (In reply to Ryosuke Niwa from
comment #9
)
> Comment on
attachment 391660
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=391660&action=review
> > > Source/WebCore/editing/InsertListCommand.cpp:341 > > - if (start.isNull() || end.isNull()) > > + if (start.isNull() || end.isNull() || !start.deepEquivalent().containerNode()->hasEditableStyle()) > > Sorry, I forgot to point out earlier but we should probably check that the > end is also editable.
Jack
Comment 12
2020-02-25 23:32:11 PST
Created
attachment 391723
[details]
Patch
WebKit Commit Bot
Comment 13
2020-02-26 17:01:42 PST
Comment on
attachment 391723
[details]
Patch Clearing flags on attachment: 391723 Committed
r257536
: <
https://trac.webkit.org/changeset/257536
>
WebKit Commit Bot
Comment 14
2020-02-26 17:01:44 PST
All reviewed patches have been landed. Closing bug.
Ryosuke Niwa
Comment 15
2020-03-07 19:59:40 PST
***
Bug 208515
has been marked as a duplicate of this bug. ***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug