Title: [282260] trunk
Revision
282260
Author
[email protected]
Date
2021-09-09 23:41:27 -0700 (Thu, 09 Sep 2021)

Log Message

Nullptr crash in CompositeEditCommand::splitTreeToNode via InsertParagraphSeparatorCommand::doApply
https://bugs.webkit.org/show_bug.cgi?id=229276

Patch by Frédéric Wang <[email protected]> on 2021-09-09
Reviewed by Ryosuke Niwa.

Source/WebCore:

The loop in CompositeEditCommand::splitTreeToNode calls splitElement with the parent node as an
argument. This patch fixes a nullptr crash by following the rule of [1]: store the parent node as
a local smart pointer. Additionally, it ensures that editingIgnoresContent() returns false on the
parent so that the corresponding ASSERT in Position's constructor does not fail when
firstPositionInNode is called.

[1] https://lists.webkit.org/pipermail/webkit-dev/2020-September/031386.html

Tests: editing/execCommand/indent-input-in-image-crash.html
       editing/execCommand/indent-input-in-image-editing-ignores-content-assert.html

* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::moveParagraphs): Store parent node in a smart pointer and exit loop
if it returns true for editingIgnoresContent.

LayoutTests:

Add regression tests for a crash and an assert in CompositeEditCommand::splitTreeToNode.

* editing/execCommand/indent-input-in-image-crash-expected.txt: Added.
* editing/execCommand/indent-input-in-image-crash.html: Added.
* editing/execCommand/indent-input-in-image-editing-ignores-content-assert-expected.txt: Added.
* editing/execCommand/indent-input-in-image-editing-ignores-content-assert.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (282259 => 282260)


--- trunk/LayoutTests/ChangeLog	2021-09-10 05:38:39 UTC (rev 282259)
+++ trunk/LayoutTests/ChangeLog	2021-09-10 06:41:27 UTC (rev 282260)
@@ -1,3 +1,17 @@
+2021-09-09  Frédéric Wang  <[email protected]>
+
+        Nullptr crash in CompositeEditCommand::splitTreeToNode via InsertParagraphSeparatorCommand::doApply
+        https://bugs.webkit.org/show_bug.cgi?id=229276
+
+        Reviewed by Ryosuke Niwa.
+
+        Add regression tests for a crash and an assert in CompositeEditCommand::splitTreeToNode.
+
+        * editing/execCommand/indent-input-in-image-crash-expected.txt: Added.
+        * editing/execCommand/indent-input-in-image-crash.html: Added.
+        * editing/execCommand/indent-input-in-image-editing-ignores-content-assert-expected.txt: Added.
+        * editing/execCommand/indent-input-in-image-editing-ignores-content-assert.html: Added.
+
 2021-09-09  Alan Bujtas  <[email protected]>
 
         [Table layout] Incorrect vertical position when the inline level box has 0px used height.

Added: trunk/LayoutTests/editing/execCommand/indent-input-in-image-crash-expected.txt (0 => 282260)


--- trunk/LayoutTests/editing/execCommand/indent-input-in-image-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/indent-input-in-image-crash-expected.txt	2021-09-10 06:41:27 UTC (rev 282260)
@@ -0,0 +1 @@
+This test passes if it does not crash.

Added: trunk/LayoutTests/editing/execCommand/indent-input-in-image-crash.html (0 => 282260)


--- trunk/LayoutTests/editing/execCommand/indent-input-in-image-crash.html	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/indent-input-in-image-crash.html	2021-09-10 06:41:27 UTC (rev 282260)
@@ -0,0 +1,39 @@
+<style>
+  head {
+    display: block;
+  }
+  img {
+    content: counter(section, lower-roman);
+  }
+</style>
+<script>
+  _onload_ = async () => {
+    if (window.testRunner) {
+      testRunner.dumpAsText();
+      testRunner.waitUntilDone();
+    }
+    document.designMode = 'on';
+    let img0 = document.createElement('img');
+    document.head.appendChild(img0);
+    let embed0 = document.createElement('embed');
+    embed0.src = '';
+    img0.appendChild(embed0);
+    let div0 = document.createElement('div');
+    img0.appendChild(div0);
+    let input = document.createElement('input');
+    div0.appendChild(input);
+    getSelection().setBaseAndExtent(input, 0, input, 0);
+    let promise = new Promise(function(resolve) {
+      new EventSource('#')._onerror_ = () => {
+        document.execCommand('Indent');
+        resolve();
+      };
+    });
+    await new File([], '').text();
+    document.execCommand('SelectAll');
+    document.execCommand('Indent');
+    await promise;
+    document.body.innerHTML = "This test passes if it does not crash.";
+    testRunner.notifyDone();
+  };
+</script>

Added: trunk/LayoutTests/editing/execCommand/indent-input-in-image-editing-ignores-content-assert-expected.txt (0 => 282260)


--- trunk/LayoutTests/editing/execCommand/indent-input-in-image-editing-ignores-content-assert-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/indent-input-in-image-editing-ignores-content-assert-expected.txt	2021-09-10 06:41:27 UTC (rev 282260)
@@ -0,0 +1 @@
+This test passes if it does not assert.

Added: trunk/LayoutTests/editing/execCommand/indent-input-in-image-editing-ignores-content-assert.html (0 => 282260)


--- trunk/LayoutTests/editing/execCommand/indent-input-in-image-editing-ignores-content-assert.html	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/indent-input-in-image-editing-ignores-content-assert.html	2021-09-10 06:41:27 UTC (rev 282260)
@@ -0,0 +1,24 @@
+<style>
+  head {
+    display: block;
+  }
+  img {
+    content: counter(section, lower-roman);
+  }
+</style>
+<script>
+  _onload_ = () => {
+    if (window.testRunner)
+      testRunner.dumpAsText();
+    document.designMode = 'on';
+    let img0 = document.createElement('img');
+    document.head.appendChild(img0);
+    let div0 = document.createElement('div');
+    img0.appendChild(div0);
+    let input = document.createElement('input');
+    div0.appendChild(input);
+    getSelection().setBaseAndExtent(input, 0, input, 0);
+    document.execCommand('Indent');
+    document.body.innerHTML = "This test passes if it does not assert.";
+  };
+</script>

Modified: trunk/Source/WebCore/ChangeLog (282259 => 282260)


--- trunk/Source/WebCore/ChangeLog	2021-09-10 05:38:39 UTC (rev 282259)
+++ trunk/Source/WebCore/ChangeLog	2021-09-10 06:41:27 UTC (rev 282260)
@@ -1,3 +1,25 @@
+2021-09-09  Frédéric Wang  <[email protected]>
+
+        Nullptr crash in CompositeEditCommand::splitTreeToNode via InsertParagraphSeparatorCommand::doApply
+        https://bugs.webkit.org/show_bug.cgi?id=229276
+
+        Reviewed by Ryosuke Niwa.
+
+        The loop in CompositeEditCommand::splitTreeToNode calls splitElement with the parent node as an
+        argument. This patch fixes a nullptr crash by following the rule of [1]: store the parent node as
+        a local smart pointer. Additionally, it ensures that editingIgnoresContent() returns false on the
+        parent so that the corresponding ASSERT in Position's constructor does not fail when
+        firstPositionInNode is called.
+
+        [1] https://lists.webkit.org/pipermail/webkit-dev/2020-September/031386.html
+
+        Tests: editing/execCommand/indent-input-in-image-crash.html
+               editing/execCommand/indent-input-in-image-editing-ignores-content-assert.html
+
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::moveParagraphs): Store parent node in a smart pointer and exit loop
+        if it returns true for editingIgnoresContent.
+
 2021-09-09  Alan Bujtas  <[email protected]>
 
         [Table layout] Incorrect vertical position when the inline level box has 0px used height.

Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (282259 => 282260)


--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2021-09-10 05:38:39 UTC (rev 282259)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2021-09-10 06:41:27 UTC (rev 282260)
@@ -1749,13 +1749,14 @@
     ASSERT(adjustedEnd);
     RefPtr<Node> node;
     for (node = &start; node && node->parentNode() != adjustedEnd; node = node->parentNode()) {
-        if (!node->parentNode() || !is<Element>(*node->parentNode()))
+        RefPtr parentNode = node->parentNode();
+        if (!parentNode || !is<Element>(*parentNode) || editingIgnoresContent(*parentNode))
             break;
         // Do not split a node when doing so introduces an empty node.
-        VisiblePosition positionInParent = firstPositionInNode(node->parentNode());
+        VisiblePosition positionInParent = firstPositionInNode(parentNode.get());
         VisiblePosition positionInNode = firstPositionInOrBeforeNode(node.get());
         if (positionInParent != positionInNode)
-            splitElement(downcast<Element>(*node->parentNode()), *node);
+            splitElement(downcast<Element>(*parentNode), *node);
     }
 
     return node;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to