RESOLVED FIXED 210004
Nullptr crash in CompositeEditCommand::splitTreeToNode when inserting image in anchor element that has uneditable parent
https://bugs.webkit.org/show_bug.cgi?id=210004
Summary Nullptr crash in CompositeEditCommand::splitTreeToNode when inserting image i...
Jack
Reported 2020-04-04 09:20:48 PDT
Attachments
Patch (6.84 KB, patch)
2020-04-04 10:13 PDT, Jack
no flags
Patch (6.79 KB, patch)
2020-04-04 17:39 PDT, Jack
no flags
Patch (4.38 KB, patch)
2020-04-06 16:33 PDT, Jack
no flags
Jack
Comment 1 2020-04-04 09:21:46 PDT
#0 0x15836d155 in WebCore::CompositeEditCommand::splitTreeToNode(WebCore::Node&, WebCore::Node&, bool) (Safari_ASAN_259384_90de49be478170ac8513448015dcb21abd3583ea.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3512155) #1 0x158439bf5 in WebCore::ReplaceSelectionCommand::doApply() (Safari_ASAN_259384_90de49be478170ac8513448015dcb21abd3583ea.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x35debf5) #2 0x1583451d6 in WebCore::CompositeEditCommand::apply() (Safari_ASAN_259384_90de49be478170ac8513448015dcb21abd3583ea.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x34ea1d6) #3 0x158401dc1 in WebCore::executeInsertFragment(WebCore::Frame&, WTF::Ref<WebCore::DocumentFragment, WTF::DumbPtrTraits<WebCore::DocumentFragment> >&&) (Safari_ASAN_259384_90de49be478170ac8513448015dcb21abd3583ea.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x35a6dc1) #4 0x1584020d2 in WebCore::executeInsertNode(WebCore::Frame&, WTF::Ref<WebCore::Node, WTF::DumbPtrTraits<WebCore::Node> >&&) (Safari_ASAN_259384_90de49be478170ac8513448015dcb21abd3583ea.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x35a70d2) #5 0x1583fba54 in WebCore::executeInsertImage(WebCore::Frame&, WebCore::Event*, WebCore::EditorCommandSource, WTF::String const&) (Safari_ASAN_259384_90de49be478170ac8513448015dcb21abd3583ea.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x35a0a54) #6 0x158074f47 in WebCore::Document::execCommand(WTF::String const&, bool, WTF::String const&) (Safari_ASAN_259384_90de49be478170ac8513448015dcb21abd3583ea.app/Contents/Frameworks/WebCore.framework/Versions/A/WebCore:x86_64+0x3219f47)
Jack
Comment 2 2020-04-04 10:13:22 PDT
Jack
Comment 3 2020-04-04 10:19:45 PDT
(In reply to Jack from comment #2) > Created attachment 395455 [details] > Patch When inserting image in anchor we try to push down the anchor element by first moving anchor's children to its parent. If anchor's parent is uneditable, the move fails and leaves the children dangling and parentless. Later the code crashes when function splitTreeToNode dereferences the parent of the dangling children. RemoveNodePreservingChildren can fail and leave the children dangling if the parent of the node is uneditable. Added editability check for the to-be-removed node. Also pushAnchorElementDown would fail silently and we cannot avoid anchor element in function positionAvoidingSpecialElementBoundary. Added check for same enclosing anchor and return empty Position to the caller. Lastly in ReplaceSelectionCommand, added check for empty Position returned by positionAvoidingSpecialElementBoundary and terminate the command.
Jack
Comment 4 2020-04-04 17:39:57 PDT
Ryosuke Niwa
Comment 5 2020-04-06 12:37:46 PDT
Comment on attachment 395469 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=395469&action=review > Source/WebCore/editing/CompositeEditCommand.cpp:1724 > + Element* newEnclosingAnchor = enclosingAnchorElement(original); > + if (newEnclosingAnchor != enclosingAnchor) > + enclosingAnchor = newEnclosingAnchor; > + else > + return { }; What is this change about? It should be explained in the change log as a per function comment. I don't think this function is ever supposed to return null position like this. See lines below where we set result to original if result is null. r- because of this. > Source/WebCore/editing/RemoveNodePreservingChildrenCommand.cpp:44 > + ContainerNode* parent = m_node->parentNode(); Please use makeRefPtr and auto.
Jack
Comment 6 2020-04-06 13:09:17 PDT
Thanks. I added a comment in the log but not under the function. Do you mean this is where it should go? (WebCore::CompositeEditCommand::positionAvoidingSpecialElementBoundary): Also pushAnchorElementDown would fail silently and we cannot avoid anchor element in function positionAvoidingSpecialElementBoundary. Added check for same enclosing anchor and return empty Position to the caller. (In reply to Ryosuke Niwa from comment #5) > Comment on attachment 395469 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=395469&action=review > > > Source/WebCore/editing/CompositeEditCommand.cpp:1724 > > + Element* newEnclosingAnchor = enclosingAnchorElement(original); > > + if (newEnclosingAnchor != enclosingAnchor) > > + enclosingAnchor = newEnclosingAnchor; > > + else > > + return { }; > > What is this change about? It should be explained in the change log as a per > function comment. > I don't think this function is ever supposed to return null position like > this. > See lines below where we set result to original if result is null. > r- because of this. > > > Source/WebCore/editing/RemoveNodePreservingChildrenCommand.cpp:44 > > + ContainerNode* parent = m_node->parentNode(); > > Please use makeRefPtr and auto.
Ryosuke Niwa
Comment 7 2020-04-06 14:14:44 PDT
(In reply to Jack from comment #6) > Thanks. I added a comment in the log but not under the function. Do you mean > this is where it should go? > > (WebCore::CompositeEditCommand::positionAvoidingSpecialElementBoundary): > Also pushAnchorElementDown would fail silently and we cannot avoid > anchor element in function positionAvoidingSpecialElementBoundary. Added > check for same enclosing anchor and return empty Position to the caller. Yes, although it should start after : in the first line. Regardless, we shouldn't be returning null Position there.
Jack
Comment 8 2020-04-06 14:24:01 PDT
Thanks. Yeah, I thought about that too and experimented with returning original position. The insertion command will continue and insert the image in anchor element without avoiding it. Therefore I thought if we return empty position, the caller can terminate the command earlier. Or is it okay just to let the image be inserted? > (In reply to Ryosuke Niwa from comment #5) > > Comment on attachment 395469 [details] > > Patch > > I don't think this function is ever supposed to return null position like > > this. > > See lines below where we set result to original if result is null. > > r- because of this. > > > > > Source/WebCore/editing/RemoveNodePreservingChildrenCommand.cpp:44 > > > + ContainerNode* parent = m_node->parentNode(); > >
Ryosuke Niwa
Comment 9 2020-04-06 14:31:04 PDT
(In reply to Jack from comment #8) > Thanks. Yeah, I thought about that too and experimented with returning > original position. The insertion command will continue and insert the image > in anchor element without avoiding it. Therefore I thought if we return > empty position, the caller can terminate the command earlier. > > Or is it okay just to let the image be inserted? Yes. That's the exiting fallback path anyway for when the position becomes null.
Ryosuke Niwa
Comment 10 2020-04-06 14:31:28 PDT
There is no security implication here.
Jack
Comment 11 2020-04-06 14:32:45 PDT
I see. Thanks! (In reply to Ryosuke Niwa from comment #9) > (In reply to Jack from comment #8) > > Thanks. Yeah, I thought about that too and experimented with returning > > original position. The insertion command will continue and insert the image > > in anchor element without avoiding it. Therefore I thought if we return > > empty position, the caller can terminate the command earlier. > > > > Or is it okay just to let the image be inserted? > > Yes. That's the exiting fallback path anyway for when the position becomes > null.
Jack
Comment 12 2020-04-06 16:33:15 PDT
EWS
Comment 13 2020-04-06 23:29:30 PDT
Committed r259624: <https://trac.webkit.org/changeset/259624> All reviewed patches have been landed. Closing bug and clearing flags on attachment 395629 [details].
Note You need to log in before you can comment on or make changes to this bug.