Diff
Modified: branches/safari-605-branch/Source/WebCore/ChangeLog (227403 => 227404)
--- branches/safari-605-branch/Source/WebCore/ChangeLog 2018-01-23 06:42:50 UTC (rev 227403)
+++ branches/safari-605-branch/Source/WebCore/ChangeLog 2018-01-23 06:42:54 UTC (rev 227404)
@@ -1,5 +1,43 @@
2018-01-22 Jason Marcell <jmarc...@apple.com>
+ Cherry-pick r227351. rdar://problem/36746029
+
+ 2018-01-22 Ryosuke Niwa <rn...@webkit.org>
+
+ Blob conversion and sanitization doesn't work with Microsoft Word for Mac 2011
+ https://bugs.webkit.org/show_bug.cgi?id=181616
+ <rdar://problem/36484908>
+
+ Reviewed by Wenson Hsieh.
+
+ The bug was caused by WebContentReader::readHTML and WebContentMarkupReader::readHTML not sanitizing plain HTML string
+ as done for web archives even when custom pasteboard data is enabled. Fixed the bug by doing the sanitization.
+
+ Unfortunately, we can't make file URLs available in this case because WebContent process doesn't have sandbox extensions
+ to access local files referenced by the HTML source in the clipboard, and we can't make WebContent process request for
+ a sandbox extension¸on an arbitrary local file, as it would defeat the whole point of sandboxing.
+
+ Instead, we strip away all HTML attributes referencing a URL whose scheme is not HTTP, HTTPS, or data when sanitizing
+ text/html from the clipboard to avoid exposing local file paths, which can reveal privacy & security sensitive data
+ such as the user's full name, and the location of private containers of other applications in the system.
+
+ Tests: PasteHTML.DoesNotSanitizeHTMLWhenCustomPasteboardDataIsDisabled
+ PasteHTML.DoesNotStripFileURLsWhenCustomPasteboardDataIsDisabled
+ PasteHTML.ExposesHTMLTypeInDataTransfer
+ PasteHTML.KeepsHTTPURLs
+ PasteHTML.SanitizesHTML
+ PasteHTML.StripsFileURLs
+
+ * editing/cocoa/WebContentReaderCocoa.mm:
+ (WebCore::WebContentReader::readHTML): Fixed the bug by sanitizing the markup, and stripping away file URLs.
+ (WebCore::WebContentMarkupReader::readHTML): Ditto.
+ * editing/markup.cpp:
+ (WebCore::removeSubresourceURLAttributes): Added.
+ (WebCore::sanitizeMarkup): Added.
+ * editing/markup.h:
+
+2018-01-22 Jason Marcell <jmarc...@apple.com>
+
Cherry-pick r227357. rdar://problem/36763204
2018-01-22 Per Arne Vollan <pvol...@apple.com>
Modified: branches/safari-605-branch/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm (227403 => 227404)
--- branches/safari-605-branch/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-01-23 06:42:50 UTC (rev 227403)
+++ branches/safari-605-branch/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2018-01-23 06:42:54 UTC (rev 227404)
@@ -175,7 +175,7 @@
};
-static bool shouldConvertToBlob(const URL& url)
+static bool shouldReplaceSubresourceURL(const URL& url)
{
return !(url.protocolIsInHTTPFamily() || url.protocolIsData());
}
@@ -224,7 +224,7 @@
HashMap<AtomicString, Ref<Blob>> urlToBlobMap;
for (const Ref<ArchiveResource>& subresource : subresources) {
auto& url = ""
- if (shouldConvertToBlob(url))
+ if (shouldReplaceSubresourceURL(url))
urlToBlobMap.set(url.string(), Blob::create(subresource->data(), subresource->mimeType()));
}
@@ -376,7 +376,7 @@
HashMap<AtomicString, AtomicString> blobURLMap;
for (const Ref<ArchiveResource>& subresource : markupAndArchive.archive->subresources()) {
auto& subresourceURL = subresource->url();
- if (!shouldConvertToBlob(subresourceURL))
+ if (!shouldReplaceSubresourceURL(subresourceURL))
continue;
auto blob = Blob::create(subresource->data(), subresource->mimeType());
String blobURL = DOMURL::createObjectURL(destinationDocument, blob);
@@ -394,7 +394,7 @@
continue;
auto subframeURL = subframeMainResource->url();
- if (!shouldConvertToBlob(subframeURL))
+ if (!shouldReplaceSubresourceURL(subframeURL))
continue;
MarkupAndArchive subframeContent = { String::fromUTF8(subframeMainResource->data().data(), subframeMainResource->data().size()),
@@ -499,7 +499,17 @@
if (stringOmittingMicrosoftPrefix.isEmpty())
return false;
- addFragment(createFragmentFromMarkup(document, stringOmittingMicrosoftPrefix, emptyString(), DisallowScriptingAndPluginContent));
+ String markup;
+ if (RuntimeEnabledFeatures::sharedFeatures().customPasteboardDataEnabled() && shouldSanitize()) {
+ markup = sanitizeMarkup(stringOmittingMicrosoftPrefix, WTF::Function<void (DocumentFragment&)> { [] (DocumentFragment& fragment) {
+ removeSubresourceURLAttributes(fragment, [] (const URL& url) {
+ return shouldReplaceSubresourceURL(url);
+ });
+ } });
+ } else
+ markup = stringOmittingMicrosoftPrefix;
+
+ addFragment(createFragmentFromMarkup(document, markup, emptyString(), DisallowScriptingAndPluginContent));
return true;
}
@@ -509,9 +519,13 @@
return false;
String rawHTML = stripMicrosoftPrefix(string);
- if (shouldSanitize())
- markup = sanitizeMarkup(rawHTML);
- else
+ if (shouldSanitize()) {
+ markup = sanitizeMarkup(rawHTML, WTF::Function<void (DocumentFragment&)> { [] (DocumentFragment& fragment) {
+ removeSubresourceURLAttributes(fragment, [] (const URL& url) {
+ return shouldReplaceSubresourceURL(url);
+ });
+ } });
+ } else
markup = rawHTML;
return !markup.isEmpty();
Modified: branches/safari-605-branch/Source/WebCore/editing/markup.cpp (227403 => 227404)
--- branches/safari-605-branch/Source/WebCore/editing/markup.cpp 2018-01-23 06:42:50 UTC (rev 227403)
+++ branches/safari-605-branch/Source/WebCore/editing/markup.cpp 2018-01-23 06:42:54 UTC (rev 227404)
@@ -72,6 +72,7 @@
#include "TextIterator.h"
#include "TypedElementDescendantIterator.h"
#include "URL.h"
+#include "URLParser.h"
#include "VisibleSelection.h"
#include "VisibleUnits.h"
#include <wtf/StdLibExtras.h>
@@ -144,6 +145,30 @@
change.apply();
}
+struct ElementAttribute {
+ Ref<Element> element;
+ QualifiedName attributeName;
+};
+
+void removeSubresourceURLAttributes(Ref<DocumentFragment>&& fragment, WTF::Function<bool(const URL&)> shouldRemoveURL)
+{
+ Vector<ElementAttribute> attributesToRemove;
+ for (auto& element : descendantsOfType<Element>(fragment)) {
+ if (!element.hasAttributes())
+ continue;
+ for (const Attribute& attribute : element.attributesIterator()) {
+ // FIXME: This won't work for srcset.
+ if (element.attributeContainsURL(attribute) && !attribute.value().isEmpty()) {
+ URL url = "" { attribute.value() }.result();
+ if (shouldRemoveURL(url))
+ attributesToRemove.append({ element, attribute.name() });
+ }
+ }
+ }
+ for (auto& item : attributesToRemove)
+ item.element->removeAttribute(item.attributeName);
+}
+
std::unique_ptr<Page> createPageForSanitizingWebContent()
{
PageConfiguration pageConfiguration(createEmptyEditorClient(), SocketProvider::create(), LibWebRTCProvider::create(), CacheStorageProvider::create());
@@ -172,7 +197,7 @@
}
-String sanitizeMarkup(const String& rawHTML)
+String sanitizeMarkup(const String& rawHTML, std::optional<WTF::Function<void(DocumentFragment&)>> fragmentSanitizer)
{
auto page = createPageForSanitizingWebContent();
Document* stagingDocument = page->mainFrame().document();
@@ -181,6 +206,10 @@
ASSERT(bodyElement);
auto fragment = createFragmentFromMarkup(*stagingDocument, rawHTML, emptyString(), DisallowScriptingAndPluginContent);
+
+ if (fragmentSanitizer)
+ (*fragmentSanitizer)(fragment);
+
bodyElement->appendChild(fragment.get());
auto range = Range::create(*stagingDocument);
Modified: branches/safari-605-branch/Source/WebCore/editing/markup.h (227403 => 227404)
--- branches/safari-605-branch/Source/WebCore/editing/markup.h 2018-01-23 06:42:50 UTC (rev 227403)
+++ branches/safari-605-branch/Source/WebCore/editing/markup.h 2018-01-23 06:42:54 UTC (rev 227404)
@@ -29,6 +29,7 @@
#include "FragmentScriptingPermission.h"
#include "HTMLInterchange.h"
#include <wtf/Forward.h>
+#include <wtf/Function.h>
#include <wtf/HashMap.h>
namespace WebCore {
@@ -47,8 +48,10 @@
class Range;
void replaceSubresourceURLs(Ref<DocumentFragment>&&, HashMap<AtomicString, AtomicString>&&);
+void removeSubresourceURLAttributes(Ref<DocumentFragment>&&, WTF::Function<bool(const URL&)> shouldRemoveURL);
+
std::unique_ptr<Page> createPageForSanitizingWebContent();
-String sanitizeMarkup(const String&);
+String sanitizeMarkup(const String&, std::optional<WTF::Function<void(DocumentFragment&)>> fragmentSanitizer = std::nullopt);
enum EChildrenOnly { IncludeNode, ChildrenOnly };
enum EAbsoluteURLs { DoNotResolveURLs, ResolveAllURLs, ResolveNonLocalURLs };
Modified: branches/safari-605-branch/Tools/ChangeLog (227403 => 227404)
--- branches/safari-605-branch/Tools/ChangeLog 2018-01-23 06:42:50 UTC (rev 227403)
+++ branches/safari-605-branch/Tools/ChangeLog 2018-01-23 06:42:54 UTC (rev 227404)
@@ -1,5 +1,25 @@
2018-01-22 Jason Marcell <jmarc...@apple.com>
+ Cherry-pick r227351. rdar://problem/36746029
+
+ 2018-01-22 Ryosuke Niwa <rn...@webkit.org>
+
+ Blob conversion and sanitization doesn't work with Microsoft Word for Mac 2011
+ https://bugs.webkit.org/show_bug.cgi?id=181616
+ <rdar://problem/36484908>
+
+ Reviewed by Wenson Hsieh.
+
+ Added tests to make sure we sanitize plain HTML, not just web archives,
+ when and only when custom pasteboard data is enabled.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/PasteHTML.mm: Added.
+ (writeHTMLToPasteboard): Added.
+ (createWebViewWithCustomPasteboardDataSetting): Added.
+
+2018-01-22 Jason Marcell <jmarc...@apple.com>
+
Cherry-pick r227273. rdar://problem/36722654
2018-01-20 Chris Dumez <cdu...@apple.com>
Modified: branches/safari-605-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (227403 => 227404)
--- branches/safari-605-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-01-23 06:42:50 UTC (rev 227403)
+++ branches/safari-605-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-01-23 06:42:54 UTC (rev 227404)
@@ -573,6 +573,7 @@
9B62630C1F8C25C8007EE29B /* copy-url.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B62630B1F8C2510007EE29B /* copy-url.html */; };
9B7A37C41F8AEBA5004AA228 /* CopyURL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */; };
9B7D740F1F8378770006C432 /* paste-rtfd.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B7D740E1F8377E60006C432 /* paste-rtfd.html */; };
+ 9BCB7C2820130600003E7C0C /* PasteHTML.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BCB7C2620130600003E7C0C /* PasteHTML.mm */; };
9BD4239A1E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */; };
9BD4239C1E04C01C00200395 /* chinese-character-with-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD4239B1E04BFD000200395 /* chinese-character-with-image.html */; };
9BD5111C1FE8E11600D2B630 /* AccessingPastedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BD5111B1FE8E11600D2B630 /* AccessingPastedImage.mm */; };
@@ -1581,6 +1582,7 @@
9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstResponderScrollingPosition.mm; sourceTree = "<group>"; };
9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CopyURL.mm; sourceTree = "<group>"; };
9B7D740E1F8377E60006C432 /* paste-rtfd.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "paste-rtfd.html"; sourceTree = "<group>"; };
+ 9BCB7C2620130600003E7C0C /* PasteHTML.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteHTML.mm; sourceTree = "<group>"; };
9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AttributedSubstringForProposedRangeWithImage.mm; sourceTree = "<group>"; };
9BD4239B1E04BFD000200395 /* chinese-character-with-image.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "chinese-character-with-image.html"; sourceTree = "<group>"; };
9BD5111B1FE8E11600D2B630 /* AccessingPastedImage.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AccessingPastedImage.mm; sourceTree = "<group>"; };
@@ -2107,6 +2109,7 @@
CEBCA12E1E3A660100C73293 /* OverrideContentSecurityPolicy.mm */,
9BDCCD851F7D0B0700009A18 /* PasteImage.mm */,
9BDD95561F83683600D20C60 /* PasteRTFD.mm */,
+ 9BCB7C2620130600003E7C0C /* PasteHTML.mm */,
9B2346411F943A2400DB1D23 /* PasteWebArchive.mm */,
3FCC4FE41EC4E8520076E37C /* PictureInPictureDelegate.mm */,
83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */,
@@ -3381,6 +3384,7 @@
7CCE7EBB1A411A7E00447C4C /* DOMHTMLTableCellCellAbove.mm in Sources */,
2D51A0C71C8BF00C00765C45 /* DOMHTMLVideoElementWrapper.mm in Sources */,
46397B951DC2C850009A78AE /* DOMNode.mm in Sources */,
+ 9BCB7C2820130600003E7C0C /* PasteHTML.mm in Sources */,
7CCE7EBC1A411A7E00447C4C /* DOMNodeFromJSObject.mm in Sources */,
7CCE7EBD1A411A7E00447C4C /* DOMRangeOfString.mm in Sources */,
7CCE7EEC1A411AE600447C4C /* DOMWindowExtensionBasic.cpp in Sources */,
Added: branches/safari-605-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteHTML.mm (0 => 227404)
--- branches/safari-605-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteHTML.mm (rev 0)
+++ branches/safari-605-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteHTML.mm 2018-01-23 06:42:54 UTC (rev 227404)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if WK_API_ENABLED && PLATFORM(COCOA)
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import <WebCore/LegacyNSPasteboardTypes.h>
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKPreferencesRefPrivate.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/text/WTFString.h>
+
+#if PLATFORM(IOS)
+#include <MobileCoreServices/MobileCoreServices.h>
+#endif
+
+@interface WKWebView ()
+- (void)paste:(id)sender;
+@end
+
+#if PLATFORM(MAC)
+void writeHTMLToPasteboard(NSString *html)
+{
+ [[NSPasteboard generalPasteboard] declareTypes:@[WebCore::legacyHTMLPasteboardType()] owner:nil];
+ [[NSPasteboard generalPasteboard] setString:html forType:WebCore::legacyHTMLPasteboardType()];
+}
+#else
+void writeHTMLToPasteboard(NSString *html)
+{
+ [[UIPasteboard generalPasteboard] setItems:@[@{ (NSString *)kUTTypeHTML : html}]];
+}
+#endif
+
+static RetainPtr<TestWKWebView> createWebViewWithCustomPasteboardDataSetting(bool enabled)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ auto preferences = (WKPreferencesRef)[[webView configuration] preferences];
+ WKPreferencesSetDataTransferItemsEnabled(preferences, true);
+ WKPreferencesSetCustomPasteboardDataEnabled(preferences, enabled);
+ return webView;
+}
+
+TEST(PasteHTML, ExposesHTMLTypeInDataTransfer)
+{
+ auto webView = createWebViewWithCustomPasteboardDataSetting(true);
+ [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+
+ writeHTMLToPasteboard(@"<!DOCTYPE html><html><body><p><u>hello</u>, world</p></body></html>");
+ [webView paste:nil];
+
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.types.includes('text/html')"]);
+ [webView stringByEvaluatingJavaScript:@"editor.innerHTML = clipboardData.values[0]; editor.focus()"];
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"document.queryCommandState('underline')"].boolValue);
+ [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary')"];
+ EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"document.queryCommandState('underline')"].boolValue);
+ EXPECT_WK_STREQ("hello, world", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
+}
+
+TEST(PasteHTML, SanitizesHTML)
+{
+ auto webView = createWebViewWithCustomPasteboardDataSetting(true);
+ [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+
+ writeHTMLToPasteboard(@"<!DOCTYPE html><meta content=\"secret\"><b _onmouseover_=\"dangerousCode()\">hello</b>"
+ "<!-- secret-->, world<script>dangerousCode()</script>';");
+ [webView paste:nil];
+
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.types.includes('text/html')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('hello')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('world')"].boolValue);
+ EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('secret')"].boolValue);
+ EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('dangerousCode')"].boolValue);
+}
+
+TEST(PasteHTML, DoesNotSanitizeHTMLWhenCustomPasteboardDataIsDisabled)
+{
+ auto webView = createWebViewWithCustomPasteboardDataSetting(false);
+ [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+
+ writeHTMLToPasteboard(@"<!DOCTYPE html><meta content=\"secret\"><b _onmouseover_=\"dangerousCode()\">hello</b>"
+ "<!-- secret-->, world<script>dangerousCode()</script>';");
+ [webView paste:nil];
+
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.types.includes('text/html')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('hello')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('world')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('secret')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('dangerousCode')"].boolValue);
+}
+
+TEST(PasteHTML, StripsFileURLs)
+{
+ auto webView = createWebViewWithCustomPasteboardDataSetting(true);
+ [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+
+ writeHTMLToPasteboard(@"<!DOCTYPE html><html><body><a alt='hello' href=''>world</a>");
+ [webView paste:nil];
+
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.types.includes('text/html')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('hello')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('world')"].boolValue);
+ EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('secret')"].boolValue);
+}
+
+TEST(PasteHTML, DoesNotStripFileURLsWhenCustomPasteboardDataIsDisabled)
+{
+ auto webView = createWebViewWithCustomPasteboardDataSetting(false);
+ [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+
+ writeHTMLToPasteboard(@"<!DOCTYPE html><html><body><a alt='hello' href=''>world</a>");
+ [webView paste:nil];
+
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.types.includes('text/html')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('hello')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('world')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('secret')"].boolValue);
+}
+
+TEST(PasteHTML, KeepsHTTPURLs)
+{
+ auto webView = createWebViewWithCustomPasteboardDataSetting(true);
+ [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+
+ writeHTMLToPasteboard(@"<!DOCTYPE html><html><body><a title='hello' href=''>world</a>");
+ [webView paste:nil];
+
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.types.includes('text/html')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('hello')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('world')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"clipboardData.values[0].includes('abe.png')"].boolValue);
+}
+
+#endif // WK_API_ENABLED && PLATFORM(COCOA)