Changeset 238661 in webkit


Ignore:
Timestamp:
Nov 28, 2018 9:25:07 PM (5 years ago)
Author:
Wenson Hsieh
Message:

[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.

Source/WebCore:

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):

Tools:

Add a test to verify that, when dropping an item with both "com.apple.webarchive" and "public.utf8-plain-text"
representations, the higher fidelity web archive data is used when handling the drop.

  • TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm:
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r238657 r238661  
     12018-11-28  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOSMac] Dropping text selections from web content into editable elements crashes the web process
     4        https://bugs.webkit.org/show_bug.cgi?id=192113
     5        <rdar://problem/46323701>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        In iOSMac, registering invalid UTIs on NSItemProvider when starting a drag or handling a drop does not work.
     10        Since iOS writes and reads only "Apple Web Archive pasteboard type" (a.k.a. `WebArchivePboardType`) during drag
     11        and drop as well as copy and paste, we fail to read or write any web archive data, and subsequently fall back to
     12        reading RTF or flat RTFD, both of which are not supported in iOSMac, since UIFoundation links against the
     13        system's macOS WebKit stack.
     14
     15        To fix this, we add support for reading and writing com.apple.webarchive (`kUTTypeWebArchive`) on iOS, so that
     16        WebKit-based iOSMac applications can understand web archive data from the host running macOS, and the host can
     17        also understand web archive data written by the iOSMac app. Additionally, don't allow reading RTF and flat RTFD
     18        as web content in iOSMac. (Note that writing RTF and flat RTFD is still safe, since it does not depend on
     19        UIFoundation.framework but rather `WebCore::HTMLConverter`).
     20
     21        Test: DragAndDropTests.ModernWebArchiveType
     22
     23        * editing/cocoa/WebContentReaderCocoa.mm:
     24        (WebCore::createFragment):
     25
     26        Additionally make sure that we never call into UIFoundation's NSAttributedString to markup conversion codepath
     27        by making `createFragment` an empty stub on iOSMac.
     28
     29        * platform/ios/PasteboardIOS.mm:
     30        (WebCore::supportedImageTypes):
     31        (WebCore::isTypeAllowedByReadingPolicy):
     32        (WebCore::Pasteboard::readPasteboardWebContentDataForType):
     33        (WebCore::Pasteboard::supportedWebContentPasteboardTypes):
     34        * platform/ios/PlatformPasteboardIOS.mm:
     35        (WebCore::PlatformPasteboard::write):
     36
    1372018-11-28  Commit Queue  <commit-queue@webkit.org>
    238
  • trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm

    r238657 r238661  
    8686namespace WebCore {
    8787
    88 #if (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300)
     88#if PLATFORM(IOSMAC)
     89
     90static FragmentAndResources createFragment(Frame&, NSAttributedString *)
     91{
     92    return { };
     93}
     94
     95#elif (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300)
    8996
    9097static NSDictionary *attributesForAttributedStringConversion()
  • trunk/Source/WebCore/platform/ios/PasteboardIOS.mm

    r237266 r238661  
    169169static NSArray* supportedImageTypes()
    170170{
    171     return @[(id)kUTTypePNG, (id)kUTTypeTIFF, (id)kUTTypeJPEG, (id)kUTTypeGIF];
     171    return @[(__bridge NSString *)kUTTypePNG, (__bridge NSString *)kUTTypeTIFF, (__bridge NSString *)kUTTypeJPEG, (__bridge NSString *)kUTTypeGIF];
    172172}
    173173
     
    176176    return policy == WebContentReadingPolicy::AnyType
    177177        || [type isEqualToString:WebArchivePboardType]
    178         || [type isEqualToString:(NSString *)kUTTypeHTML]
    179         || [type isEqualToString:(NSString *)kUTTypeRTF]
    180         || [type isEqualToString:(NSString *)kUTTypeFlatRTFD];
     178        || [type isEqualToString:(__bridge NSString *)kUTTypeWebArchive]
     179        || [type isEqualToString:(__bridge NSString *)kUTTypeHTML]
     180        || [type isEqualToString:(__bridge NSString *)kUTTypeRTF]
     181        || [type isEqualToString:(__bridge NSString *)kUTTypeFlatRTFD];
    181182}
    182183
    183184Pasteboard::ReaderResult Pasteboard::readPasteboardWebContentDataForType(PasteboardWebContentReader& reader, PasteboardStrategy& strategy, NSString *type, int itemIndex)
    184185{
    185     if ([type isEqualToString:WebArchivePboardType]) {
    186         auto buffer = strategy.readBufferFromPasteboard(itemIndex, WebArchivePboardType, m_pasteboardName);
     186    if ([type isEqualToString:WebArchivePboardType] || [type isEqualToString:(__bridge NSString *)kUTTypeWebArchive]) {
     187        auto buffer = strategy.readBufferFromPasteboard(itemIndex, type, m_pasteboardName);
    187188        if (m_changeCount != changeCount())
    188189            return ReaderResult::PasteboardWasChangedExternally;
     
    190191    }
    191192
    192     if ([type isEqualToString:(NSString *)kUTTypeHTML]) {
     193    if ([type isEqualToString:(__bridge NSString *)kUTTypeHTML]) {
    193194        String htmlString = strategy.readStringFromPasteboard(itemIndex, kUTTypeHTML, m_pasteboardName);
    194195        if (m_changeCount != changeCount())
     
    197198    }
    198199
    199     if ([type isEqualToString:(NSString *)kUTTypeFlatRTFD]) {
     200#if !PLATFORM(IOSMAC)
     201    if ([type isEqualToString:(__bridge NSString *)kUTTypeFlatRTFD]) {
    200202        RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, kUTTypeFlatRTFD, m_pasteboardName);
    201203        if (m_changeCount != changeCount())
     
    204206    }
    205207
    206     if ([type isEqualToString:(NSString *)kUTTypeRTF]) {
     208    if ([type isEqualToString:(__bridge NSString *)kUTTypeRTF]) {
    207209        RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, kUTTypeRTF, m_pasteboardName);
    208210        if (m_changeCount != changeCount())
     
    210212        return buffer && reader.readRTF(*buffer) ? ReaderResult::ReadType : ReaderResult::DidNotReadType;
    211213    }
     214#endif // !PLATFORM(IOSMAC)
    212215
    213216    if ([supportedImageTypes() containsObject:type]) {
     
    218221    }
    219222
    220     if ([type isEqualToString:(NSString *)kUTTypeURL]) {
     223    if ([type isEqualToString:(__bridge NSString *)kUTTypeURL]) {
    221224        String title;
    222225        URL url = strategy.readURLFromPasteboard(itemIndex, m_pasteboardName, title);
     
    226229    }
    227230
    228     if (UTTypeConformsTo((CFStringRef)type, kUTTypePlainText)) {
     231    if (UTTypeConformsTo((__bridge CFStringRef)type, kUTTypePlainText)) {
    229232        String string = strategy.readStringFromPasteboard(itemIndex, kUTTypePlainText, m_pasteboardName);
    230233        if (m_changeCount != changeCount())
     
    233236    }
    234237
    235     if (UTTypeConformsTo((CFStringRef)type, kUTTypeText)) {
     238    if (UTTypeConformsTo((__bridge CFStringRef)type, kUTTypeText)) {
    236239        String string = strategy.readStringFromPasteboard(itemIndex, kUTTypeText, m_pasteboardName);
    237240        if (m_changeCount != changeCount())
     
    322325NSArray *Pasteboard::supportedWebContentPasteboardTypes()
    323326{
    324     return @[(id)WebArchivePboardType, (id)kUTTypeFlatRTFD, (id)kUTTypeRTF, (id)kUTTypeHTML, (id)kUTTypePNG, (id)kUTTypeTIFF, (id)kUTTypeJPEG, (id)kUTTypeGIF, (id)kUTTypeURL, (id)kUTTypeText];
     327    return @[
     328#if !PLATFORM(IOSMAC)
     329        WebArchivePboardType,
     330#endif
     331        (__bridge NSString *)kUTTypeWebArchive,
     332#if !PLATFORM(IOSMAC)
     333        (__bridge NSString *)kUTTypeFlatRTFD,
     334        (__bridge NSString *)kUTTypeRTF,
     335#endif
     336        (__bridge NSString *)kUTTypeHTML,
     337        (__bridge NSString *)kUTTypePNG,
     338        (__bridge NSString *)kUTTypeTIFF,
     339        (__bridge NSString *)kUTTypeJPEG,
     340        (__bridge NSString *)kUTTypeGIF,
     341        (__bridge NSString *)kUTTypeURL,
     342        (__bridge NSString *)kUTTypeText
     343    ];
    325344}
    326345
  • trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm

    r238461 r238661  
    351351    auto representationsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
    352352
     353#if !PLATFORM(IOSMAC)
    353354    [representationsToRegister addData:[webIOSPastePboardType dataUsingEncoding:NSUTF8StringEncoding] forType:webIOSPastePboardType];
     355#endif
    354356
    355357    ASSERT(content.clientTypes.size() == content.clientData.size());
     
    357359        [representationsToRegister addData:content.clientData[i]->createNSData().get() forType:content.clientTypes[i]];
    358360
    359     if (content.dataInWebArchiveFormat)
    360         [representationsToRegister addData:content.dataInWebArchiveFormat->createNSData().get() forType:WebArchivePboardType];
     361    if (content.dataInWebArchiveFormat) {
     362        auto webArchiveData = content.dataInWebArchiveFormat->createNSData();
     363#if !PLATFORM(IOSMAC)
     364        [representationsToRegister addData:webArchiveData.get() forType:WebArchivePboardType];
     365#endif
     366        [representationsToRegister addData:webArchiveData.get() forType:(__bridge NSString *)kUTTypeWebArchive];
     367    }
    361368
    362369    if (content.dataInAttributedStringFormat) {
  • trunk/Tools/ChangeLog

    r238644 r238661  
     12018-11-28  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOSMac] Dropping text selections from web content into editable elements crashes the web process
     4        https://bugs.webkit.org/show_bug.cgi?id=192113
     5        <rdar://problem/46323701>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        Add a test to verify that, when dropping an item with both "com.apple.webarchive" and "public.utf8-plain-text"
     10        representations, the higher fidelity web archive data is used when handling the drop.
     11
     12        * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm:
     13
    1142018-11-28  Aakash Jain  <aakash_jain@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm

    r235835 r238661  
    2626#import "config.h"
    2727
     28#if WK_API_ENABLED && ENABLE(DRAG_SUPPORT)
     29
    2830#import "DragAndDropSimulator.h"
    2931#import "PlatformUtilities.h"
    3032#import <WebKit/WKPreferencesPrivate.h>
     33#import <WebKit/WebArchive.h>
    3134
    32 #if WK_API_ENABLED && ENABLE(DRAG_SUPPORT)
     35#if PLATFORM(IOS_FAMILY)
     36#import <MobileCoreServices/MobileCoreServices.h>
     37#endif
     38
     39TEST(DragAndDropTests, ModernWebArchiveType)
     40{
     41    NSData *markupData = [@"<strong><i>Hello world</i></strong>" dataUsingEncoding:NSUTF8StringEncoding];
     42    auto mainResource = adoptNS([[WebResource alloc] initWithData:markupData URL:[NSURL URLWithString:@"foo.html"] MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]);
     43    auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:@[ ] subframeArchives:@[ ]]);
     44    NSString *webArchiveType = (__bridge NSString *)kUTTypeWebArchive;
     45
     46    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 320, 500)]);
     47    auto webView = [simulator webView];
     48    [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width'><body style='width: 100%; height: 100%;' contenteditable>"];
     49#if PLATFORM(MAC)
     50    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
     51    [pasteboard declareTypes:@[webArchiveType, (__bridge NSString *)kUTTypeUTF8PlainText] owner:nil];
     52    [pasteboard setData:[archive data] forType:webArchiveType];
     53    [pasteboard setData:[@"Hello world" dataUsingEncoding:NSUTF8StringEncoding] forType:(__bridge NSString *)kUTTypeUTF8PlainText];
     54    [simulator setExternalDragPasteboard:pasteboard];
     55#else
     56    auto item = adoptNS([[NSItemProvider alloc] init]);
     57    [item registerDataRepresentationForTypeIdentifier:webArchiveType visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[&] (void (^completionHandler)(NSData *, NSError *)) -> NSProgress * {
     58        completionHandler([archive data], nil);
     59        return nil;
     60    }];
     61    [item registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeUTF8PlainText visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[&] (void (^completionHandler)(NSData *, NSError *)) -> NSProgress * {
     62        completionHandler([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
     63        return nil;
     64    }];
     65    [simulator setExternalItemProviders:@[ item.get() ]];
     66#endif
     67    [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)];
     68    [webView stringByEvaluatingJavaScript:@"document.body.focus(); getSelection().setBaseAndExtent(document.body, 0, document.body, 1)"];
     69    EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]);
     70    EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"document.queryCommandState('bold')"].boolValue);
     71    EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"document.queryCommandState('italic')"].boolValue);
     72}
    3373
    3474TEST(DragAndDropTests, DragImageLocationForLinkInSubframe)
Note: See TracChangeset for help on using the changeset viewer.