Pasting from Excel no longer provides text/html data
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Feb 2018 23:41:34 +0000 (23:41 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Feb 2018 23:41:34 +0000 (23:41 +0000)
commitb41ff009c4aefe6fc2834937c1b9d3e1a6875de5
treea2f1433c631070901a608aa68b54fe8c1a187e85
parent5d24025546da96c7de2e1c80cae818a138a38e54
Pasting from Excel no longer provides text/html data
https://bugs.webkit.org/show_bug.cgi?id=182636
<rdar://problem/37087060>

Reviewed by Ryosuke Niwa.

Source/WebCore:

After r222656, we treat images on the pasteboard as files. However, we also have an existing policy which hides
text data ("text/uri-list", "text/html", "text/plain") from the page when files are present on the pasteboard.
When copying a table, Microsoft Excel writes a rendering of the table to the pasteboard as an image. This means
that we'll hide other data types (importantly, 'text/html') upon pasting, even though important clients (such as
Google Docs and Confluence) depend on the 'text/html' data in order to correctly handle the paste (rather than
paste as an image of a table).

To fix this, we add an exception to the DataTransfer.getData codepath when the pasteboard contains files.
Instead of always returning the empty string for text/html, we still allow pasteboard access, but only read
from a limited set of rich text types, i.e. web archive, RTF(D), and HTML markup. Importantly, this prevents
us from exposing any file paths that appear as plain text or URLs on the pasteboard. Just as in the regular
codepath for getData(), if the pasteboard data comes from the same origin, we allow unsanitized access;
otherwise, we use WebContentMarkupReader to extract markup from the pasteboard.

Tests:  PasteMixedContent.ImageFileAndPlainText
        PasteMixedContent.ImageFileAndWebArchive
        PasteMixedContent.ImageFileAndHTML
        PasteMixedContent.ImageFileAndRTF
        PasteMixedContent.ImageFileAndURL
        PasteMixedContent.ImageFileWithHTMLAndURL
        DataInteractionTests.DataTransferGetDataWhenDroppingImageAndMarkup

Also rebaselined some layout tests, which cover changes in behavior when dropping on macOS and pasting on iOS.

* dom/DataTransfer.cpp:
(WebCore::DataTransfer::getDataForItem const):

Augment the codepath handling the case where the pasteboard contains files, such that we allow reading
"text/html", but only from rich text types.

(WebCore::DataTransfer::readStringFromPasteboard const):

Factor out logic for reading from the pasteboard into a private helper. This is called in two places from
getDataForItem: in the normal (existing) path, and in the case where we allow 'text/html' to be read despite
files appearing in the pasteboard.

One important difference here is that this helper now takes a WebContentReadingPolicy, whose purpose is to
prevent reading from non-rich-text types when files appear in the pasteboard.

Another tweak here is that we now use `lowercaseType` instead of the original (unadjusted) `type` when reading
from the pasteboard. This doesn't seem to be intended in the first place.

(WebCore::DataTransfer::types const):

Tweak the implementation of DataTransfer.types() in the case where files exist on the pasteboard, such that we
also add "text/html" if it is present in the list of DOM-safe types.

* dom/DataTransfer.h:
* platform/Pasteboard.h:

Introduce WebContentReadingPolicy, which indicates whether or not we should limit web content reading from the
pasteboard to only rich text types upon paste or drop. Normally, we allow all types to be read as web content
(::AnyType), but when files appear on the pasteboard, we force OnlyRichTextTypes to ensure that no other types
can unintentionally be read back as web content.

* platform/StaticPasteboard.h:
* platform/gtk/PasteboardGtk.cpp:
(WebCore::Pasteboard::read):
* platform/ios/PasteboardIOS.mm:

Teach Pasteboard (on iOS) to respect WebContentReadingPolicy.

(WebCore::isTypeAllowedByReadingPolicy):
(WebCore::Pasteboard::read):
(WebCore::Pasteboard::readRespectingUTIFidelities):
* platform/mac/PasteboardMac.mm:

Teach Pasteboard (on macOS) to respect WebContentReadingPolicy.

(WebCore::Pasteboard::read):
* platform/win/PasteboardWin.cpp:
(WebCore::Pasteboard::read):
* platform/wpe/PasteboardWPE.cpp:
(WebCore::Pasteboard::read):

Adjust non-Cocoa Pasteboard implementations for an interface change.

Tools:

Add new API tests to exercise pasting images with various other content types on macOS, and when dropping images
and HTML markup on iOS. See the WebCore ChangeLog for more detail.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/DataTransfer.html: Added.

Add a new API test harness that dumps various bits of information about a DataTransfer upon paste and drop.
While somewhat similar to some existing harnesses, this makes a distinction between the raw HTML data on the
pasteboard and the actual result of inserting said HTML into the DOM. This allows us to check that the HTML has
been sanitized, while making checks for the actual content of the HTML robust against inline style changes.

* TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm:
* TestWebKitAPI/Tests/WebKitCocoa/PasteMixedContent.mm: Added.

Add a new test suite to exercise pasting mixed content types. In these test cases, the pasteboard contains a
file, with some combination of plain text, rich text, and URLs.

(imagePath):
(writeTypesAndDataToPasteboard):

Add a helper to write a var-arg list of content types and data to the general NSPasteboard.

(setUpWebView):
(markupString):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
(TestWebKitAPI::testIconImageData):
(TestWebKitAPI::TEST):
* TestWebKitAPI/cocoa/TestWKWebView.h:

Move a private declaration of -[WKWebView paste:] out to TestWKWebView.h, so that it can be shared across
multiple tests. Currently, it only resides in PasteImage.mm, but I need it in PasteMixedContent.mm as well.

LayoutTests:

Rebaseline some existing layout tests. We now expose "text/html" alongside "Files" on DataTransfer.types() in
some circumstances. This also provides some test coverage for ensuring that the paste codepath iOS allows the
page to request HTML, even if there are files on the pasteboard. See the WebCore ChangeLog for more detail.

* editing/pasteboard/data-transfer-item-list-add-file-multiple-times-expected.txt:
* editing/pasteboard/data-transfer-item-list-add-file-on-copy-expected.txt:
* editing/pasteboard/data-transfer-item-list-add-file-on-drag-expected.txt:

Adjust test expectations for the additional "text/html" type.

* editing/pasteboard/paste-image-does-not-reveal-file-url-expected.txt:
* editing/pasteboard/paste-image-does-not-reveal-file-url.html:

Instead of checking that types is [ "Files" ], just check that types contains "Files". On iOS, copying a
selected image does not also copy HTML, but on macOS it does; this covers both cases.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228340 268f45cc-cd09-0410-ab3c-d52691b4dbfc
23 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/data-transfer-item-list-add-file-multiple-times-expected.txt
LayoutTests/editing/pasteboard/data-transfer-item-list-add-file-on-copy-expected.txt
LayoutTests/editing/pasteboard/data-transfer-item-list-add-file-on-drag-expected.txt
LayoutTests/editing/pasteboard/paste-image-does-not-reveal-file-url-expected.txt
LayoutTests/editing/pasteboard/paste-image-does-not-reveal-file-url.html
Source/WebCore/ChangeLog
Source/WebCore/dom/DataTransfer.cpp
Source/WebCore/dom/DataTransfer.h
Source/WebCore/platform/Pasteboard.h
Source/WebCore/platform/StaticPasteboard.h
Source/WebCore/platform/gtk/PasteboardGtk.cpp
Source/WebCore/platform/ios/PasteboardIOS.mm
Source/WebCore/platform/mac/PasteboardMac.mm
Source/WebCore/platform/win/PasteboardWin.cpp
Source/WebCore/platform/wpe/PasteboardWPE.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/DataTransfer.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteMixedContent.mm [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm
Tools/TestWebKitAPI/cocoa/TestWKWebView.h