Title: [275652] trunk
Revision
275652
Author
[email protected]
Date
2021-04-07 22:21:10 -0700 (Wed, 07 Apr 2021)

Log Message

Nullptr dereference in ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline
https://bugs.webkit.org/show_bug.cgi?id=224259

Patch by Julian Gonzalez <[email protected]> on 2021-04-07
Reviewed by Ryosuke Niwa.

Source/WebCore:

When pruning after removing the end <br> in ReplaceSelectionCommand::doApply(), make sure
that insertedNodes is updated properly (given that we may be removing an ancestor
of the start or end of insertedNodes).

Test: editing/inserting/insert-display-contents-crash.html

* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::InsertedNodes::willRemovePossibleAncestorNode):
(WebCore::ReplaceSelectionCommand::InsertedNodes::willRemoveNode):
(WebCore::ReplaceSelectionCommand::doApply):
* editing/ReplaceSelectionCommand.h:

LayoutTests:

Add a test to catch the editing crash fixed here; thanks to Tuomas Karkkainen
for its basic structure.

* editing/inserting/insert-display-contents-crash-expected.txt: Added.
* editing/inserting/insert-display-contents-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (275651 => 275652)


--- trunk/LayoutTests/ChangeLog	2021-04-08 04:21:19 UTC (rev 275651)
+++ trunk/LayoutTests/ChangeLog	2021-04-08 05:21:10 UTC (rev 275652)
@@ -1,3 +1,16 @@
+2021-04-07  Julian Gonzalez  <[email protected]>
+
+        Nullptr dereference in ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline
+        https://bugs.webkit.org/show_bug.cgi?id=224259
+
+        Reviewed by Ryosuke Niwa.
+
+        Add a test to catch the editing crash fixed here; thanks to Tuomas Karkkainen
+        for its basic structure.
+
+        * editing/inserting/insert-display-contents-crash-expected.txt: Added.
+        * editing/inserting/insert-display-contents-crash.html: Added.
+
 2021-04-07  Robert Jenner  <[email protected]>
 
         [ macOS ] media/modern-media-controls/seek-forward-support/seek-forward-support.html is a flakey timeout

Added: trunk/LayoutTests/editing/inserting/insert-display-contents-crash-expected.txt (0 => 275652)


--- trunk/LayoutTests/editing/inserting/insert-display-contents-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/inserting/insert-display-contents-crash-expected.txt	2021-04-08 05:21:10 UTC (rev 275652)
@@ -0,0 +1 @@
+This test passes if WebKit does not crash. PASS

Added: trunk/LayoutTests/editing/inserting/insert-display-contents-crash.html (0 => 275652)


--- trunk/LayoutTests/editing/inserting/insert-display-contents-crash.html	                        (rev 0)
+++ trunk/LayoutTests/editing/inserting/insert-display-contents-crash.html	2021-04-08 05:21:10 UTC (rev 275652)
@@ -0,0 +1,27 @@
+<html>
+<head>
+<style>
+h6 {
+    padding-block-end: 1px;
+}
+li {
+    display: contents;
+}
+</style>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+_onload_ = () => {
+    document.body.appendChild(document.createElement('h6'));
+    document.execCommand('SelectAll');
+    document.designMode = 'on';
+    document.execCommand('InsertOrderedList');
+    document.body.offsetTop;
+    document.styleSheets[0].insertRule(`br { display: contents; }`);
+    document.execCommand('InsertHTML', false, 'a<h1>');
+    document.execCommand('InsertHTML', false, '<h1>This test passes if WebKit does not crash. PASS');
+};
+</script>
+</head>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (275651 => 275652)


--- trunk/Source/WebCore/ChangeLog	2021-04-08 04:21:19 UTC (rev 275651)
+++ trunk/Source/WebCore/ChangeLog	2021-04-08 05:21:10 UTC (rev 275652)
@@ -1,3 +1,22 @@
+2021-04-07  Julian Gonzalez  <[email protected]>
+
+        Nullptr dereference in ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline
+        https://bugs.webkit.org/show_bug.cgi?id=224259
+
+        Reviewed by Ryosuke Niwa.
+
+        When pruning after removing the end <br> in ReplaceSelectionCommand::doApply(), make sure
+        that insertedNodes is updated properly (given that we may be removing an ancestor
+        of the start or end of insertedNodes).
+
+        Test: editing/inserting/insert-display-contents-crash.html
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::InsertedNodes::willRemovePossibleAncestorNode):
+        (WebCore::ReplaceSelectionCommand::InsertedNodes::willRemoveNode):
+        (WebCore::ReplaceSelectionCommand::doApply):
+        * editing/ReplaceSelectionCommand.h:
+
 2021-04-07  Jean-Yves Avenard  <[email protected]>
 
         Site could crash if MediaRemote framework isn't available.

Modified: trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp (275651 => 275652)


--- trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp	2021-04-08 04:21:19 UTC (rev 275651)
+++ trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp	2021-04-08 05:21:10 UTC (rev 275652)
@@ -400,8 +400,34 @@
     }
 }
 
+inline void ReplaceSelectionCommand::InsertedNodes::willRemovePossibleAncestorNode(Node* node)
+{
+    bool containsFirstNode = node->contains(m_firstNodeInserted.get());
+    bool containsLastNode = node->contains(m_lastNodeInserted.get());
+    if (containsFirstNode && containsLastNode) {
+        m_firstNodeInserted = nullptr;
+        m_lastNodeInserted = nullptr;
+        return;
+    }
+
+    if (containsLastNode)
+        m_lastNodeInserted = NodeTraversal::previousSkippingChildren(*node);
+    else if (containsFirstNode)
+        m_firstNodeInserted = NodeTraversal::nextSkippingChildren(*node);
+
+    if (!m_lastNodeInserted)
+        m_lastNodeInserted = m_firstNodeInserted;
+    else if (!m_firstNodeInserted)
+        m_firstNodeInserted = m_lastNodeInserted;
+    else if (m_firstNodeInserted->isDescendantOf(m_lastNodeInserted.get()))
+        std::swap(m_firstNodeInserted, m_lastNodeInserted);
+}
+
 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node* node)
 {
+    ASSERT(!m_firstNodeInserted || !m_firstNodeInserted->isDescendantOf(node));
+    ASSERT(!m_lastNodeInserted || !m_lastNodeInserted->isDescendantOf(node));
+
     if (m_firstNodeInserted == node && m_lastNodeInserted == node) {
         m_firstNodeInserted = nullptr;
         m_lastNodeInserted = nullptr;
@@ -1303,11 +1329,14 @@
         removeNode(*endBR);
         document().updateLayoutIgnorePendingStylesheets();
         if (auto nodeToRemove = makeRefPtr(highestNodeToRemoveInPruning(parent.get()))) {
-            insertedNodes.willRemoveNode(nodeToRemove.get());
+            insertedNodes.willRemovePossibleAncestorNode(nodeToRemove.get());
             removeNode(*nodeToRemove);
         }
     }
 
+    if (insertedNodes.isEmpty())
+        return;
+
     makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes);
     if (insertedNodes.isEmpty())
         return;

Modified: trunk/Source/WebCore/editing/ReplaceSelectionCommand.h (275651 => 275652)


--- trunk/Source/WebCore/editing/ReplaceSelectionCommand.h	2021-04-08 04:21:19 UTC (rev 275651)
+++ trunk/Source/WebCore/editing/ReplaceSelectionCommand.h	2021-04-08 05:21:10 UTC (rev 275652)
@@ -68,6 +68,7 @@
     public:
         void respondToNodeInsertion(Node*);
         void willRemoveNodePreservingChildren(Node*);
+        void willRemovePossibleAncestorNode(Node*);
         void willRemoveNode(Node*);
         void didReplaceNode(Node*, Node* newNode);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to