Pasting a table from Confluence strip of table cell content
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Mar 2019 18:39:51 +0000 (18:39 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Mar 2019 18:39:51 +0000 (18:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196390

Reviewed by Antti Koivisto.

Source/WebCore:

The bug was ultimately caused by FrameView of the document we use to sanitize the pasteboard content
having 0px by 0px dimension. This caused div with `overflow-x: auto` surrounding a table to have
the height of 0px. Because StyledMarkupAccumulator::renderedTextRespectingRange uses TextIterator
to serialize a text node and this div was an ancestor of the text node, TextIterator::handleTextNode
ended up exiting early.

Fixed the bug by giving FrameView, which is used to sanitize the content, a dimension of 800px by 600px.

Using TextIteratorIgnoresStyleVisibility is not a great alternative since removing invisible content
during paste is an important privacy feature.

Test: editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html

* editing/markup.cpp:
(WebCore::createPageForSanitizingWebContent):

LayoutTests:

Added a regression test.

* editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin-expected.txt: Added.
* editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243653 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/editing/markup.cpp

index 7f27553..908ba38 100644 (file)
@@ -1,3 +1,15 @@
+2019-03-29  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Pasting a table from Confluence strip of table cell content
+        https://bugs.webkit.org/show_bug.cgi?id=196390
+
+        Reviewed by Antti Koivisto.
+
+        Added a regression test.
+
+        * editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin-expected.txt: Added.
+        * editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html: Added.
+
 2019-03-29  Shawn Roberts  <sroberts@apple.com>
 
         fast/mediastream/MediaStreamTrack-getSettings.html is a flaky failure
diff --git a/LayoutTests/editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin-expected.txt b/LayoutTests/editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin-expected.txt
new file mode 100644 (file)
index 0000000..f6b16b1
--- /dev/null
@@ -0,0 +1,16 @@
+This tests copying and pasting content with "overflow: auto" would not strip its content.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS markup.includes("secret") is false
+PASS markup.includes("Start</div>") is true
+PASS markup.includes("Content</p>") is true
+PASS markup.includes("End</span>") is true
+PASS editor.querySelector("div").textContent is "Start"
+PASS editor.querySelector("p").textContent is "Content"
+PASS editor.querySelector("span").textContent is "End"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html b/LayoutTests/editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html
new file mode 100644 (file)
index 0000000..dc5e182
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test.js"></script>
+<script>
+
+description('This tests copying and pasting content with "overflow: auto" would not strip its content.');
+
+function startTest() {
+    const iframe = document.createElement('iframe');
+    document.body.appendChild(iframe);
+    iframe.src = `data:text/html;charset=utf-8,<!DOCTYPE html>
+    <body><button onclick="document.execCommand('selectAll'); document.execCommand('copy'); getSelection().removeAllRanges();">Start</button>
+    <script>
+    document.addEventListener('copy', () => {
+        event.preventDefault();
+        event.clipboardData.setData('text/html', '<div>Start</div><div style="height: 1000px;"></div><!-- secret -->'
+            + '<div style="visibility: hidden;">secret</div><p style="overflow: auto;">Content</p><div style="height: 1000px;"></div><span id="end">End</span>');
+        window.parent.postMessage({}, '*');
+    });
+    window.onload = () => {
+        document.execCommand('selectAll');
+        document.execCommand('copy');
+    }
+    </sc` + `ript>
+    </body>`;
+}
+
+
+function continueTest() {
+    editor.focus();
+    document.execCommand('selectAll');
+    if (window.testRunner)
+        testRunner.execCommand('paste');
+}
+
+function didPaste(event) {
+    window.markup = event.clipboardData.getData('text/html');
+    shouldBeFalse('markup.includes("secret")');
+    shouldBeTrue('markup.includes("Start</div>")');
+    shouldBeTrue('markup.includes("Content</p>")');
+    shouldBeTrue('markup.includes("End</span>")');
+
+    setTimeout(() => {
+        shouldBeEqualToString('editor.querySelector("div").textContent', 'Start');
+        shouldBeEqualToString('editor.querySelector("p").textContent', 'Content');
+        shouldBeEqualToString('editor.querySelector("span").textContent', 'End');
+        editor.textContent = editor.innerHTML;
+        editor.contentEditable = false;
+        if (window.testRunner)
+            editor.style.display = 'none';
+        finishJSTest();
+    }, 0);
+}
+
+onload = startTest;
+onmessage = continueTest;
+jsTestIsAsync = true;
+
+</script>
+<div id="editor" onpaste="didPaste(event)" contenteditable>Paste now</div>
+</body>
+</html>
\ No newline at end of file
index aecdae9..86f4ac8 100644 (file)
@@ -1,3 +1,26 @@
+2019-03-29  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Pasting a table from Confluence strip of table cell content
+        https://bugs.webkit.org/show_bug.cgi?id=196390
+
+        Reviewed by Antti Koivisto.
+
+        The bug was ultimately caused by FrameView of the document we use to sanitize the pasteboard content
+        having 0px by 0px dimension. This caused div with `overflow-x: auto` surrounding a table to have
+        the height of 0px. Because StyledMarkupAccumulator::renderedTextRespectingRange uses TextIterator
+        to serialize a text node and this div was an ancestor of the text node, TextIterator::handleTextNode
+        ended up exiting early.
+
+        Fixed the bug by giving FrameView, which is used to sanitize the content, a dimension of 800px by 600px.
+
+        Using TextIteratorIgnoresStyleVisibility is not a great alternative since removing invisible content
+        during paste is an important privacy feature.
+
+        Test: editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html
+
+        * editing/markup.cpp:
+        (WebCore::createPageForSanitizingWebContent):
+
 2019-03-29  Antoine Quint  <graouts@apple.com>
 
         WebKitTestRunner crashes when running pointerevents/ios/touch-action-none-in-overflow-scrolling-touch.html
index 311074d..00cb4e9 100644 (file)
@@ -183,7 +183,7 @@ std::unique_ptr<Page> createPageForSanitizingWebContent()
     page->settings().setAcceleratedCompositingEnabled(false);
 
     Frame& frame = page->mainFrame();
-    frame.setView(FrameView::create(frame));
+    frame.setView(FrameView::create(frame, IntSize { 800, 600 }));
     frame.init();
 
     FrameLoader& loader = frame.loader();