Modified: trunk/Source/WebCore/ChangeLog (238660 => 238661)
--- trunk/Source/WebCore/ChangeLog 2018-11-29 04:39:45 UTC (rev 238660)
+++ trunk/Source/WebCore/ChangeLog 2018-11-29 05:25:07 UTC (rev 238661)
@@ -1,3 +1,39 @@
+2018-11-28 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [iOSMac] Dropping text selections from web content into editable elements crashes the web process
+ https://bugs.webkit.org/show_bug.cgi?id=192113
+ <rdar://problem/46323701>
+
+ Reviewed by Ryosuke Niwa.
+
+ In iOSMac, registering invalid UTIs on NSItemProvider when starting a drag or handling a drop does not work.
+ Since iOS writes and reads only "Apple Web Archive pasteboard type" (a.k.a. `WebArchivePboardType`) during drag
+ and drop as well as copy and paste, we fail to read or write any web archive data, and subsequently fall back to
+ reading RTF or flat RTFD, both of which are not supported in iOSMac, since UIFoundation links against the
+ system's macOS WebKit stack.
+
+ To fix this, we add support for reading and writing com.apple.webarchive (`kUTTypeWebArchive`) on iOS, so that
+ WebKit-based iOSMac applications can understand web archive data from the host running macOS, and the host can
+ also understand web archive data written by the iOSMac app. Additionally, don't allow reading RTF and flat RTFD
+ as web content in iOSMac. (Note that writing RTF and flat RTFD is still safe, since it does not depend on
+ UIFoundation.framework but rather `WebCore::HTMLConverter`).
+
+ Test: DragAndDropTests.ModernWebArchiveType
+
+ * editing/cocoa/WebContentReaderCocoa.mm:
+ (WebCore::createFragment):
+
+ Additionally make sure that we never call into UIFoundation's NSAttributedString to markup conversion codepath
+ by making `createFragment` an empty stub on iOSMac.
+
+ * platform/ios/PasteboardIOS.mm:
+ (WebCore::supportedImageTypes):
+ (WebCore::isTypeAllowedByReadingPolicy):
+ (WebCore::Pasteboard::readPasteboardWebContentDataForType):
+ (WebCore::Pasteboard::supportedWebContentPasteboardTypes):
+ * platform/ios/PlatformPasteboardIOS.mm:
+ (WebCore::PlatformPasteboard::write):
+
2018-11-28 Commit Queue <commit-qu...@webkit.org>
Unreviewed, rolling out r238653 and r238656.
Modified: trunk/Source/WebCore/platform/ios/PasteboardIOS.mm (238660 => 238661)
--- trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2018-11-29 04:39:45 UTC (rev 238660)
+++ trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2018-11-29 05:25:07 UTC (rev 238661)
@@ -168,7 +168,7 @@
static NSArray* supportedImageTypes()
{
- return @[(id)kUTTypePNG, (id)kUTTypeTIFF, (id)kUTTypeJPEG, (id)kUTTypeGIF];
+ return @[(__bridge NSString *)kUTTypePNG, (__bridge NSString *)kUTTypeTIFF, (__bridge NSString *)kUTTypeJPEG, (__bridge NSString *)kUTTypeGIF];
}
static bool isTypeAllowedByReadingPolicy(NSString *type, WebContentReadingPolicy policy)
@@ -175,21 +175,22 @@
{
return policy == WebContentReadingPolicy::AnyType
|| [type isEqualToString:WebArchivePboardType]
- || [type isEqualToString:(NSString *)kUTTypeHTML]
- || [type isEqualToString:(NSString *)kUTTypeRTF]
- || [type isEqualToString:(NSString *)kUTTypeFlatRTFD];
+ || [type isEqualToString:(__bridge NSString *)kUTTypeWebArchive]
+ || [type isEqualToString:(__bridge NSString *)kUTTypeHTML]
+ || [type isEqualToString:(__bridge NSString *)kUTTypeRTF]
+ || [type isEqualToString:(__bridge NSString *)kUTTypeFlatRTFD];
}
Pasteboard::ReaderResult Pasteboard::readPasteboardWebContentDataForType(PasteboardWebContentReader& reader, PasteboardStrategy& strategy, NSString *type, int itemIndex)
{
- if ([type isEqualToString:WebArchivePboardType]) {
- auto buffer = strategy.readBufferFromPasteboard(itemIndex, WebArchivePboardType, m_pasteboardName);
+ if ([type isEqualToString:WebArchivePboardType] || [type isEqualToString:(__bridge NSString *)kUTTypeWebArchive]) {
+ auto buffer = strategy.readBufferFromPasteboard(itemIndex, type, m_pasteboardName);
if (m_changeCount != changeCount())
return ReaderResult::PasteboardWasChangedExternally;
return buffer && reader.readWebArchive(*buffer) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
}
- if ([type isEqualToString:(NSString *)kUTTypeHTML]) {
+ if ([type isEqualToString:(__bridge NSString *)kUTTypeHTML]) {
String htmlString = strategy.readStringFromPasteboard(itemIndex, kUTTypeHTML, m_pasteboardName);
if (m_changeCount != changeCount())
return ReaderResult::PasteboardWasChangedExternally;
@@ -196,7 +197,8 @@
return !htmlString.isNull() && reader.readHTML(htmlString) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
}
- if ([type isEqualToString:(NSString *)kUTTypeFlatRTFD]) {
+#if !PLATFORM(IOSMAC)
+ if ([type isEqualToString:(__bridge NSString *)kUTTypeFlatRTFD]) {
RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, kUTTypeFlatRTFD, m_pasteboardName);
if (m_changeCount != changeCount())
return ReaderResult::PasteboardWasChangedExternally;
@@ -203,12 +205,13 @@
return buffer && reader.readRTFD(*buffer) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
}
- if ([type isEqualToString:(NSString *)kUTTypeRTF]) {
+ if ([type isEqualToString:(__bridge NSString *)kUTTypeRTF]) {
RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, kUTTypeRTF, m_pasteboardName);
if (m_changeCount != changeCount())
return ReaderResult::PasteboardWasChangedExternally;
return buffer && reader.readRTF(*buffer) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
}
+#endif // !PLATFORM(IOSMAC)
if ([supportedImageTypes() containsObject:type]) {
RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, type, m_pasteboardName);
@@ -217,7 +220,7 @@
return buffer && reader.readImage(buffer.releaseNonNull(), type) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
}
- if ([type isEqualToString:(NSString *)kUTTypeURL]) {
+ if ([type isEqualToString:(__bridge NSString *)kUTTypeURL]) {
String title;
URL url = "" m_pasteboardName, title);
if (m_changeCount != changeCount())
@@ -225,7 +228,7 @@
return !url.isNull() && reader.readURL(url, title) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
}
- if (UTTypeConformsTo((CFStringRef)type, kUTTypePlainText)) {
+ if (UTTypeConformsTo((__bridge CFStringRef)type, kUTTypePlainText)) {
String string = strategy.readStringFromPasteboard(itemIndex, kUTTypePlainText, m_pasteboardName);
if (m_changeCount != changeCount())
return ReaderResult::PasteboardWasChangedExternally;
@@ -232,7 +235,7 @@
return !string.isNull() && reader.readPlainText(string) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
}
- if (UTTypeConformsTo((CFStringRef)type, kUTTypeText)) {
+ if (UTTypeConformsTo((__bridge CFStringRef)type, kUTTypeText)) {
String string = strategy.readStringFromPasteboard(itemIndex, kUTTypeText, m_pasteboardName);
if (m_changeCount != changeCount())
return ReaderResult::PasteboardWasChangedExternally;
@@ -321,7 +324,23 @@
NSArray *Pasteboard::supportedWebContentPasteboardTypes()
{
- return @[(id)WebArchivePboardType, (id)kUTTypeFlatRTFD, (id)kUTTypeRTF, (id)kUTTypeHTML, (id)kUTTypePNG, (id)kUTTypeTIFF, (id)kUTTypeJPEG, (id)kUTTypeGIF, (id)kUTTypeURL, (id)kUTTypeText];
+ return @[
+#if !PLATFORM(IOSMAC)
+ WebArchivePboardType,
+#endif
+ (__bridge NSString *)kUTTypeWebArchive,
+#if !PLATFORM(IOSMAC)
+ (__bridge NSString *)kUTTypeFlatRTFD,
+ (__bridge NSString *)kUTTypeRTF,
+#endif
+ (__bridge NSString *)kUTTypeHTML,
+ (__bridge NSString *)kUTTypePNG,
+ (__bridge NSString *)kUTTypeTIFF,
+ (__bridge NSString *)kUTTypeJPEG,
+ (__bridge NSString *)kUTTypeGIF,
+ (__bridge NSString *)kUTTypeURL,
+ (__bridge NSString *)kUTTypeText
+ ];
}
NSArray *Pasteboard::supportedFileUploadPasteboardTypes()
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm (238660 => 238661)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm 2018-11-29 04:39:45 UTC (rev 238660)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm 2018-11-29 05:25:07 UTC (rev 238661)
@@ -25,12 +25,52 @@
#import "config.h"
+#if WK_API_ENABLED && ENABLE(DRAG_SUPPORT)
+
#import "DragAndDropSimulator.h"
#import "PlatformUtilities.h"
#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WebArchive.h>
-#if WK_API_ENABLED && ENABLE(DRAG_SUPPORT)
+#if PLATFORM(IOS_FAMILY)
+#import <MobileCoreServices/MobileCoreServices.h>
+#endif
+TEST(DragAndDropTests, ModernWebArchiveType)
+{
+ NSData *markupData = [@"<strong><i>Hello world</i></strong>" dataUsingEncoding:NSUTF8StringEncoding];
+ auto mainResource = adoptNS([[WebResource alloc] initWithData:markupData URL:[NSURL URLWithString:@"foo.html"] MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]);
+ auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:@[ ] subframeArchives:@[ ]]);
+ NSString *webArchiveType = (__bridge NSString *)kUTTypeWebArchive;
+
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 320, 500)]);
+ auto webView = [simulator webView];
+ [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width'><body style='width: 100%; height: 100%;' contenteditable>"];
+#if PLATFORM(MAC)
+ NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
+ [pasteboard declareTypes:@[webArchiveType, (__bridge NSString *)kUTTypeUTF8PlainText] owner:nil];
+ [pasteboard setData:[archive data] forType:webArchiveType];
+ [pasteboard setData:[@"Hello world" dataUsingEncoding:NSUTF8StringEncoding] forType:(__bridge NSString *)kUTTypeUTF8PlainText];
+ [simulator setExternalDragPasteboard:pasteboard];
+#else
+ auto item = adoptNS([[NSItemProvider alloc] init]);
+ [item registerDataRepresentationForTypeIdentifier:webArchiveType visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[&] (void (^completionHandler)(NSData *, NSError *)) -> NSProgress * {
+ completionHandler([archive data], nil);
+ return nil;
+ }];
+ [item registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeUTF8PlainText visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[&] (void (^completionHandler)(NSData *, NSError *)) -> NSProgress * {
+ completionHandler([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
+ return nil;
+ }];
+ [simulator setExternalItemProviders:@[ item.get() ]];
+#endif
+ [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)];
+ [webView stringByEvaluatingJavaScript:@"document.body.focus(); getSelection().setBaseAndExtent(document.body, 0, document.body, 1)"];
+ EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"document.queryCommandState('bold')"].boolValue);
+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"document.queryCommandState('italic')"].boolValue);
+}
+
TEST(DragAndDropTests, DragImageLocationForLinkInSubframe)
{
auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 400, 400)]);