[Attachment Support] Don't Blob-convert images and attachments with https:, http...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jan 2018 00:06:41 +0000 (00:06 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jan 2018 00:06:41 +0000 (00:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181143
<rdar://problem/36200381>

Reviewed by Tim Horton.

Source/WebCore:

Clients such as Mail would expect pasting or dropping an image with src="https://..." to result in the source
URL being preserved (i.e. staying as remote images) instead of creating image attachments out of them. This
patch hooks into the shouldConvertToBlob() check added in r226272 so that it applies to attachment element
replacement as well.

Test: WKAttachmentTests.DoNotInsertDataURLImagesAsAttachments

* editing/cocoa/WebContentReaderCocoa.mm:
(WebCore::shouldConvertToBlob):
(WebCore::replaceRichContentWithAttachments):

Tools:

Add a new API test to ensure that a copied image with a data URL does not get pasted as an attachment when
attachment elements are enabled.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
(TestWebKitAPI::TEST):

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

Source/WebCore/ChangeLog
Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-data-url.html [new file with mode: 0644]

index 2a7c481..f87ce83 100644 (file)
@@ -1,3 +1,22 @@
+2018-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Attachment Support] Don't Blob-convert images and attachments with https:, http: or data: urls
+        https://bugs.webkit.org/show_bug.cgi?id=181143
+        <rdar://problem/36200381>
+
+        Reviewed by Tim Horton.
+
+        Clients such as Mail would expect pasting or dropping an image with src="https://..." to result in the source
+        URL being preserved (i.e. staying as remote images) instead of creating image attachments out of them. This
+        patch hooks into the shouldConvertToBlob() check added in r226272 so that it applies to attachment element
+        replacement as well.
+
+        Test: WKAttachmentTests.DoNotInsertDataURLImagesAsAttachments
+
+        * editing/cocoa/WebContentReaderCocoa.mm:
+        (WebCore::shouldConvertToBlob):
+        (WebCore::replaceRichContentWithAttachments):
+
 2018-01-02  Brady Eidson  <beidson@apple.com>
 
         Identify MessagePorts by a globally unique MessagePortIdentifier.
index 10d3021..1e3bbfd 100644 (file)
@@ -175,6 +175,12 @@ private:
     bool m_didDisableImage { false };
 };
 
+
+static bool shouldConvertToBlob(const URL& url)
+{
+    return !(url.protocolIsInHTTPFamily() || url.protocolIsData());
+}
+
 static bool shouldReplaceRichContentWithAttachments()
 {
 #if ENABLE(ATTACHMENT_ELEMENT)
@@ -217,8 +223,11 @@ static void replaceRichContentWithAttachments(DocumentFragment& fragment, const
 
     // FIXME: Handle resources in subframe archives.
     HashMap<AtomicString, Ref<Blob>> urlToBlobMap;
-    for (const Ref<ArchiveResource>& subresource : subresources)
-        urlToBlobMap.set(subresource->url().string(), Blob::create(subresource->data(), subresource->mimeType()));
+    for (const Ref<ArchiveResource>& subresource : subresources) {
+        auto& url = subresource->url();
+        if (shouldConvertToBlob(url))
+            urlToBlobMap.set(url.string(), Blob::create(subresource->data(), subresource->mimeType()));
+    }
 
     Vector<Ref<Element>> elementsToRemove;
     Vector<AttachmentReplacementInfo> attachmentReplacementInfo;
@@ -353,11 +362,6 @@ static String markupForFragmentInDocument(Ref<DocumentFragment>&& fragment, Docu
     return createMarkup(range.get(), nullptr, AnnotateForInterchange, false, ResolveNonLocalURLs);
 }
 
-static bool shouldConvertToBlob(const URL& url)
-{
-    return !(url.protocolIsInHTTPFamily() || url.protocolIsData());
-}
-
 static String sanitizeMarkupWithArchive(Document& destinationDocument, MarkupAndArchive& markupAndArchive, const std::function<bool(const String)>& canShowMIMETypeAsHTML)
 {
     auto page = createPageForSanitizingWebContent();
index f9907a0..b116449 100644 (file)
@@ -1,3 +1,18 @@
+2018-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Attachment Support] Don't Blob-convert images and attachments with https:, http: or data: urls
+        https://bugs.webkit.org/show_bug.cgi?id=181143
+        <rdar://problem/36200381>
+
+        Reviewed by Tim Horton.
+
+        Add a new API test to ensure that a copied image with a data URL does not get pasted as an attachment when
+        attachment elements are enabled.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+        (TestWebKitAPI::TEST):
+
 2018-01-02  Jiewen Tan  <jiewen_tan@apple.com>
 
         Update Credential Management API for WebAuthentication
index bd0c002..7247890 100644 (file)
                F486B1D01F67952300F34BDD /* DataTransfer-setDragImage.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F486B1CF1F6794FF00F34BDD /* DataTransfer-setDragImage.html */; };
                F4A32EC41F05F3850047C544 /* dragstart-change-selection-offscreen.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */; };
                F4A32ECB1F0643370047C544 /* contenteditable-in-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A32ECA1F0642F40047C544 /* contenteditable-in-iframe.html */; };
+               F4A9202F1FEE34E900F59590 /* apple-data-url.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A9202E1FEE34C800F59590 /* apple-data-url.html */; };
                F4AB578A1F65165400DB0DA1 /* custom-draggable-div.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */; };
                F4B825D81EF4DBFB006E417F /* compressed-files.zip in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4B825D61EF4DBD4006E417F /* compressed-files.zip */; };
                F4BFA68E1E4AD08000154298 /* DragAndDropPasteboardTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4BFA68C1E4AD08000154298 /* DragAndDropPasteboardTests.mm */; };
                                1C2B81871C8925A000A5529F /* Ahem.ttf in Copy Resources */,
                                1A63479F183D72A4005B1707 /* all-content-in-one-iframe.html in Copy Resources */,
                                C25CCA0D1E5141840026CB8A /* AllAhem.svg in Copy Resources */,
+                               F4A9202F1FEE34E900F59590 /* apple-data-url.html in Copy Resources */,
                                F46A095A1ED8A6E600D4AA55 /* apple.gif in Copy Resources */,
                                5C9E59411D3EB5AC00E3C62E /* ApplicationCache.db in Copy Resources */,
                                5C9E59421D3EB5AC00E3C62E /* ApplicationCache.db-shm in Copy Resources */,
                F493247C1F44DF8D006F4336 /* UIKitSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIKitSPI.h; sourceTree = "<group>"; };
                F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "dragstart-change-selection-offscreen.html"; sourceTree = "<group>"; };
                F4A32ECA1F0642F40047C544 /* contenteditable-in-iframe.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "contenteditable-in-iframe.html"; sourceTree = "<group>"; };
+               F4A9202E1FEE34C800F59590 /* apple-data-url.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "apple-data-url.html"; sourceTree = "<group>"; };
                F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "custom-draggable-div.html"; sourceTree = "<group>"; };
                F4B825D61EF4DBD4006E417F /* compressed-files.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = "compressed-files.zip"; sourceTree = "<group>"; };
                F4BFA68C1E4AD08000154298 /* DragAndDropPasteboardTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropPasteboardTests.mm; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                C25CCA0C1E5140E50026CB8A /* AllAhem.svg */,
+                               F4A9202E1FEE34C800F59590 /* apple-data-url.html */,
                                F47D30EB1ED28619000482E1 /* apple.gif */,
                                5C9E593E1D3EB1DE00E3C62E /* ApplicationCache.db */,
                                5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */,
                                7C83DED41D0A590C00FEBCF3 /* HashSet.cpp in Sources */,
                                7C83DEE01D0A590C00FEBCF3 /* IntegerToStringConversion.cpp in Sources */,
                                7A0509411FB9F06400B33FB8 /* JSONValue.cpp in Sources */,
-                               FE05FB061FE84FB700093230 /* PoisonedUniquePtr.cpp in Sources */,
                                531C1D8E1DF8EF72006E979F /* LEBDecoder.cpp in Sources */,
                                A57D54F91F3397B400A97AA7 /* LifecycleLogger.cpp in Sources */,
                                93E2C5551FD3204100E1DF6A /* LineEnding.cpp in Sources */,
                                FE05FAEF1FE0645B00093230 /* Poisoned.cpp in Sources */,
                                FE05FAEC1FDB510A00093230 /* PoisonedRef.cpp in Sources */,
                                FE05FAED1FDB510E00093230 /* PoisonedRefPtr.cpp in Sources */,
+                               FE05FB061FE84FB700093230 /* PoisonedUniquePtr.cpp in Sources */,
+                               FEC8F4EB1FE9F5AF0056FD8A /* PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp in Sources */,
+                               FEC8F4E71FE9C9050056FD8A /* PoisonedUniquePtrForTriviallyDestructibleArrays.cpp in Sources */,
                                53EC25411E96FD87000831B9 /* PriorityQueue.cpp in Sources */,
                                7C83DF131D0A590C00FEBCF3 /* RedBlackTree.cpp in Sources */,
                                7C83DF141D0A590C00FEBCF3 /* Ref.cpp in Sources */,
                                7C83DF321D0A590C00FEBCF3 /* StringBuilder.cpp in Sources */,
                                7CD4C26E1E2C0E6E00929470 /* StringConcatenate.cpp in Sources */,
                                7C83DF361D0A590C00FEBCF3 /* StringHasher.cpp in Sources */,
-                               FEC8F4E71FE9C9050056FD8A /* PoisonedUniquePtrForTriviallyDestructibleArrays.cpp in Sources */,
                                7C83DF371D0A590C00FEBCF3 /* StringImpl.cpp in Sources */,
                                7C83DF381D0A590C00FEBCF3 /* StringOperators.cpp in Sources */,
                                7C83DF3A1D0A590C00FEBCF3 /* StringView.cpp in Sources */,
                                9329AA291DE3F81E003ABD07 /* TextBreakIterator.cpp in Sources */,
                                E3DEA8111F0A589000CBC2E8 /* ThreadGroup.cpp in Sources */,
                                E38A0D351FD50CC300E98C8B /* Threading.cpp in Sources */,
-                               FEC8F4EB1FE9F5AF0056FD8A /* PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp in Sources */,
                                5311BD5E1EA9490E00525281 /* ThreadMessages.cpp in Sources */,
                                0F2C20B81DCD545000542D9E /* Time.cpp in Sources */,
                                7C83E03B1D0A602700FEBCF3 /* UtilitiesCocoa.mm in Sources */,
index 08bdb14..f93fa6b 100644 (file)
@@ -893,6 +893,25 @@ TEST(WKAttachmentTests, InsertPastedAttributedStringContainingMultipleAttachment
     }
 }
 
+TEST(WKAttachmentTests, DoNotInsertDataURLImagesAsAttachments)
+{
+    auto webContentSourceView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]);
+    [webContentSourceView synchronouslyLoadTestPageNamed:@"apple-data-url"];
+    [webContentSourceView selectAll:nil];
+    [webContentSourceView _synchronouslyExecuteEditCommand:@"Copy" argument:nil];
+
+    auto webView = webViewForTestingAttachments();
+    {
+        ObserveAttachmentUpdatesForScope observer(webView.get());
+        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
+        EXPECT_EQ(0U, observer.observer().inserted.count);
+    }
+
+    EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"Boolean(document.querySelector('attachment'))"].boolValue);
+    EXPECT_EQ(1990, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').src.length"].integerValue);
+    EXPECT_WK_STREQ("This is an apple", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]);
+}
+
 #pragma mark - Platform-specific tests
 
 #if PLATFORM(MAC)
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-data-url.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-data-url.html
new file mode 100644 (file)
index 0000000..63435fe
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+This is an apple<img src="data:image/gif;base64,R0lGODlhNABAAMQfAGJiYvLz9ImKitvb2/39/cnJyaSkpOPj49TU1MHBwbW1terq7Lu7u/X19uXm5+3u7+fo6eDg4e/w8t7e3/n5+RcXF87Oz/f398fHx9fX16+vr9HR0fDw8Pj4+MzMzAAAACH5BAEAAB8ALAAAAAA0AEAAQAX/4CeOZGme5iFUlYC+cCwKD7FAxxElAiTDnATAcCEYj8aABiBIDCIbjQCgqBEojUCjQSEEpoXTAUCQLB4PiZoTaG/fjcuFgj1kBrnIZDLoDzIIgRsTAgYmBk8TEQ4OEGdpbBQLDAUQEA55e32AGxsWHh4FBRgJCQgFAhQoCwIDlgsSFxyFOnt8foAInp+jpQkMwArCGsQaCg0KBgEoDwAAHoHRgroW1aEYpL7A28LDxcUGGgalhi8IAAgYoOvrn5/soL2lwcThEBQAAz/7JxYAXVcCPNjggp/BEwIYOHNmwMHBErMSEMgCR47FC3EwwnlzocOFBxMy3NHkp88EBwU///gjcKCRo0cPOEhwM6fDgUGWMuHKtQvUBgBhThhQ4CBCSwhoJDToQKxljlq4BPHCNo+bggXEXnwZMNMAupJ/ckm9RvUXg27dvqllkEFADxMQAKirZs3Du1CiRpX1ZfasN3EGAlsYIIADv3MCDnBowKEAQwSGSRzAMEVABIwTmCB4yHkEQQMACQDY0LmzgAlXZF0ac6D0QwUJOAxAkMArgAyuT3gQ5zYwBh8jBmhgoG9EBgYG3BbSQHpfBAEKjHSYTt3jxQ4BH3DB2EaLnAYLIgC6EyGuBhMDyDSI2X3jlu8Vay7480TPrU250p8n0SrASzQxsTGTFu9hF4B45WESgf8e+EWzy0/NlTBOeDk0AtNMcVAQQCcH5LTgLSJJ9c4ooQiwjFAI7GGUhWkE0AFWv+GQB4N/6OJJPNnMY0EAACyAgmMSLIKUBBxQgEoGRX0IIk8j5hiMNwxQkBAKDAhgxgMdeCBXBGCJFGInvMhj1V/fJMCjmSVEAEBcAFiQS4jS9HSNNk+mpZZaBmAwWgmZUeNJJ4DWJUqOdI6JZ2DjEHKiCRwEBg88BbCTl15O+lUPoo3u94MCAERAijrx+NQHBuIo4EGNgBRQigcRdAFAArl9EAAbBnWgRaylObCEiQQIECGu+2i5gBEaxgUcsDJk1sAVtp4xJbIy6JkdJhBAB63/DCstoOAGXhV3LQxeubWQZd/+kBBDuF17AKcAaDDAAuEp1G4GDZiAgBRMYODAAgdYYBsD+zjgFUAUVGedERf8NO49AQ2YkX85ZNDuCyoUcEVGBlunEUVbuBHHdBwcMNtIfkwQFwYlUMDDRA5v9B18FRUMHn22gBUWIZp+QEGeBKShRnceu5cRHbLdodNO0aSngAlV2vCIBD4PSOB7c0hidCb31TgNDyfEdcElLz3Cwdgt07HAHY0crbWN7iiQUgluN7DiK2eQ3cYcFwywQYcy0ggnmLx48FNrQllQ1FGvxIQhBQ+o0wgmUIU1Fl7YbEBZByggskeFjiQVAAUQKFDJ/2p5REUNjlSx1dYFmWOgh5BiazhcTlhvMpZedMIm2q8kuE1h5zNRkMxJM97HJI65D7NBBz2ekNkDLZ0hQQeEJZAkjbafPmdVdhKDQAMAEC5hAg8g9XlyeNRs+o1kVeWXAncywDwD9ZKQmSMBLDAEl13ydCPu3CPTnRKgPwP4aARVuoBjEBGW8fivSdkYE/zudCcPCMADvUOXNOIEJtQVCi0CxFN6HlCCKgFqA4II1F0A6L46kQlRgRkDBk0ghV3Q5YYQxAahtvGkb8DQgM94gWPuAoq6xCMvGKDUDl8YmOigIwYyjNSjpriOQUXQUpfilwAc8gMhZCABc8HhNSJlgTkOgoIUZykG+UQTFIMohBEIKGN9BmCbQgRmCq+awAIwgh0bvMo1C6hNZfJ0wBdMwG29KQAJy/WtEAAAO1BvbG9udXMK"></img>
+</body>
\ No newline at end of file