Changeset 223340 in webkit
- Timestamp:
- Oct 16, 2017 12:59:39 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 2 deleted
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r223336 r223340 1 2017-10-16 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 On ToT, event.dataTransfer.getData("text/uri-list") returns an empty string when dragging an image 4 https://bugs.webkit.org/show_bug.cgi?id=178301 5 <rdar://problem/34990050> 6 7 Reviewed by Darin Adler. 8 9 Fixes an existing test to account for asynchronous image decoding, and also rebaselines results to expect that 10 only the URL can be read, and not text. 11 12 * TestExpectations: 13 * editing/pasteboard/data-transfer-item-list-add-file-multiple-times-expected.txt: 14 * editing/pasteboard/drag-drop-href-as-text-data-expected.txt: Removed. 15 * editing/pasteboard/drag-drop-href-as-text-data.html: Removed. 16 * editing/pasteboard/drag-drop-href-as-url-expected.txt: Added. 17 * editing/pasteboard/drag-drop-href-as-url.html: Added. 18 19 Tweaks an existing drag and drop test to verify that an URL can be read back when dragging an image, but not 20 when if the URL is a file URL. 21 22 * editing/pasteboard/files-during-page-drags-expected.txt: 23 * editing/pasteboard/files-during-page-drags.html: 24 25 Fixes this test by decoding the dragged image element before starting the drag and drop simulation. 26 27 * platform/mac-wk1/TestExpectations: 28 1 29 2017-10-15 Nikita Vasilyev <nvasilyev@apple.com> 2 30 -
trunk/LayoutTests/TestExpectations
r223327 r223340 72 72 73 73 # Drag and drop via EventSender is only supported on Mac WK1 74 editing/pasteboard/drag-drop-href-as- text-data.html [ Skip ]74 editing/pasteboard/drag-drop-href-as-url.html [ Skip ] 75 75 editing/pasteboard/data-transfer-get-data-on-drop-custom.html [ Skip ] 76 76 editing/pasteboard/data-transfer-get-data-on-drop-plain-text.html [ Skip ] -
trunk/LayoutTests/editing/pasteboard/data-transfer-item-list-add-file-multiple-times-expected.txt
r222885 r223340 10 10 { 11 11 "data": { 12 "Files": "" 12 "Files": "", 13 "text/uri-list": "https://webkit.org" 13 14 }, 14 15 "items": [ … … 87 88 { 88 89 "data": { 89 "Files": "" 90 "Files": "", 91 "text/uri-list": "https://webkit.org" 90 92 }, 91 93 "items": [ … … 151 153 { 152 154 "data": { 153 "Files": "" 155 "Files": "", 156 "text/uri-list": "https://webkit.org" 154 157 }, 155 158 "items": [ … … 201 204 { 202 205 "data": { 203 "Files": "" 206 "Files": "", 207 "text/uri-list": "https://webkit.org" 204 208 }, 205 209 "items": [ -
trunk/LayoutTests/editing/pasteboard/files-during-page-drags-expected.txt
r47829 r223340 5 5 6 6 PASS Drag of A resulted in empty files array. 7 PASS Drag of IMG resulted in empty files array.7 PASS Drag of IMG resulted in files array of size 1 8 8 PASS successfullyParsed is true 9 9 -
trunk/LayoutTests/editing/pasteboard/files-during-page-drags.html
r217390 r223340 4 4 <script src="../../resources/js-test-pre.js"></script> 5 5 </head> 6 <body >6 <body onload=runTest()> 7 7 <p id="description"></p> 8 8 <div id="console"></div> 9 9 <script> 10 10 description("Make sure that .files arrays are always empty for non-file drags."); 11 12 jsTestIsAsync = true; 11 13 12 14 var testContainer = document.createElement('div'); … … 70 72 else if (droppedFiles.length == 0) 71 73 testPassed("Drag of " + source.tagName + " resulted in empty files array."); 74 else if (source == image) 75 testPassed(`Drag of ${source.tagName} resulted in files array of size ${droppedFiles.length}`); 72 76 else 73 77 testFailed("Drag of " + source.tagName + " resulted in non-empty files array! (files: " + droppedFiles.length + ")"); … … 75 79 } 76 80 77 function runTest()81 async function runTest() 78 82 { 83 if (!window.eventSender || !window.testRunner) { 84 testFailed("This test is not interactive, please run using DumpRenderTree"); 85 return; 86 } 87 88 await image.decode(); 79 89 testDrag(link); 80 90 testDrag(image); 81 }82 83 if (window.eventSender) {84 runTest();85 // Clean up after ourselves86 91 document.body.removeChild(testContainer); 87 } else { 88 testFailed("This test is not interactive, please run using DumpRenderTree"); 92 finishJSTest(); 89 93 } 90 94 -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r223324 r223340 7 7 8 8 fast/forms/attributed-strings.html [ Pass ] 9 editing/pasteboard/drag-drop-href-as- text-data.html [ Pass ]9 editing/pasteboard/drag-drop-href-as-url.html [ Pass ] 10 10 editing/pasteboard/data-transfer-get-data-on-drop-custom.html [ Pass ] 11 11 editing/pasteboard/data-transfer-get-data-on-drop-plain-text.html [ Pass ] -
trunk/Source/WebCore/ChangeLog
r223339 r223340 1 2017-10-16 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 On ToT, event.dataTransfer.getData("text/uri-list") returns an empty string when dragging an image 4 https://bugs.webkit.org/show_bug.cgi?id=178301 5 <rdar://problem/34990050> 6 7 Reviewed by Darin Adler. 8 9 After r222656, we consider images on the pasteboard to be files. This causes DataTransfer.getData to return the 10 empty string for all types, which brings back https://bugs.webkit.org/show_bug.cgi?id=170637. To allow pages to 11 access the URL part of a dragged image, we exempt "text/uri-list" from our heurstics to hide pasteboard data 12 which may contain files, and return the URL as long as its protocol is either HTTP or HTTPS. 13 14 Tweaked an existing layout test to cover this scenario, as well as the scenario in which the dragged image links 15 to a file URL (in which case we should avoid exposing the data). 16 17 Test: editing/pasteboard/drag-drop-href-as-url.html 18 DataInteractionTests.DataTransferGetDataWhenDroppingImageWithHTTPURL 19 20 * dom/DataTransfer.cpp: 21 (WebCore::DataTransfer::getDataForItem const): 22 23 When the pasteboard contains files, allow data for "text/uri-list" to be returned, as long as the URL string has 24 a white-listed protocol (currently, this is just http and https). 25 26 (WebCore::DataTransfer::shouldSuppressGetAndSetDataToAvoidExposingFilePaths const): 27 (WebCore::DataTransfer::setData): 28 (WebCore::DataTransfer::types const): 29 30 When the pasteboard contains files, allow "text/uri-list" to be added, alongside the "Files" type, if it would 31 have been exposed in the list of safe DOM types. 32 33 * dom/DataTransfer.h: 34 * platform/Pasteboard.cpp: 35 (WebCore::Pasteboard::canExposeURLToDOMWhenPasteboardContainsFiles): 36 37 Add a new helper method to determine whether it is safe to expose an URL string as "text/uri-list" to bindings, 38 if the pasteboard contains files. While this currently checks whether or not the URL is in the HTTP family, we 39 may want to consider tweaking this to blacklist the "file" protocol instead, and allow all other valid URLs by 40 default. 41 42 * platform/Pasteboard.h: 43 * platform/PlatformPasteboard.h: 44 * platform/ios/PlatformPasteboardIOS.mm: 45 (WebCore::pasteboardMayContainFilePaths): 46 (WebCore::PlatformPasteboard::stringForType const): 47 48 Mark stringForType as const, and also teach stringForType to return the null string for the platform URL type if 49 the pasteboard might contain file paths. 50 51 (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): 52 53 Before coercing a platform type to "text/uri-list" when building the list of DOM-safe types, check that the 54 stringForType is not the empty string, in which case we don't expose the type to the DOM at all. This ensures 55 that in cases where the URL might reveal a file path, we don't advertise "text/uri-list" as a type. We adopt a 56 similar strategy on iOS. 57 58 (WebCore::PlatformPasteboard::stringForType): Deleted. 59 * platform/mac/PlatformPasteboardMac.mm: 60 (WebCore::pasteboardMayContainFilePaths): 61 (WebCore::PlatformPasteboard::stringForType const): 62 (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): 63 (WebCore::PlatformPasteboard::stringForType): Deleted. 64 1 65 2017-10-16 Frederic Wang <fwang@igalia.com> 2 66 -
trunk/Source/WebCore/dom/DataTransfer.cpp
r223334 r223340 150 150 { 151 151 if (!canReadData()) 152 return String();153 154 if ((forFileDrag() || Settings::customPasteboardDataEnabled()) && m_pasteboard->containsFiles())155 152 return { }; 156 153 157 154 auto lowercaseType = stripLeadingAndTrailingHTMLSpaces(type).convertToASCIILowercase(); 155 if (shouldSuppressGetAndSetDataToAvoidExposingFilePaths()) { 156 if (lowercaseType == "text/uri-list") { 157 auto urlString = m_pasteboard->readString(lowercaseType); 158 if (Pasteboard::canExposeURLToDOMWhenPasteboardContainsFiles(urlString)) 159 return urlString; 160 } 161 return { }; 162 } 163 158 164 if (!Settings::customPasteboardDataEnabled()) 159 165 return m_pasteboard->readString(lowercaseType); … … 185 191 } 186 192 193 bool DataTransfer::shouldSuppressGetAndSetDataToAvoidExposingFilePaths() const 194 { 195 if (!forFileDrag() && !Settings::customPasteboardDataEnabled()) 196 return false; 197 return m_pasteboard->containsFiles(); 198 } 199 187 200 void DataTransfer::setData(const String& type, const String& data) 188 201 { … … 190 203 return; 191 204 192 if ( (forFileDrag() || Settings::customPasteboardDataEnabled()) && m_pasteboard->containsFiles())205 if (shouldSuppressGetAndSetDataToAvoidExposingFilePaths()) 193 206 return; 194 207 … … 272 285 } 273 286 274 if (m_itemList && m_itemList->hasItems() && m_itemList->items().findMatching([] (const auto& item) { return item->isFile(); }) != notFound) 275 return addFilesType == AddFilesType::Yes ? Vector<String> { ASCIILiteral("Files") } : Vector<String> { }; 276 277 if (m_pasteboard->containsFiles()) { 278 ASSERT(!m_pasteboard->typesSafeForBindings(m_originIdentifier).contains("Files")); 279 return addFilesType == AddFilesType::Yes ? Vector<String> { ASCIILiteral("Files") } : Vector<String> { }; 280 } 281 282 auto types = m_pasteboard->typesSafeForBindings(m_originIdentifier); 283 ASSERT(!types.contains("Files")); 284 return types; 287 auto safeTypes = m_pasteboard->typesSafeForBindings(m_originIdentifier); 288 bool hasFileBackedItem = m_itemList && m_itemList->hasItems() && notFound != m_itemList->items().findMatching([] (const auto& item) { 289 return item->isFile(); 290 }); 291 292 if (hasFileBackedItem || m_pasteboard->containsFiles()) { 293 Vector<String> types; 294 if (addFilesType == AddFilesType::Yes) 295 types.append(ASCIILiteral("Files")); 296 if (safeTypes.contains("text/uri-list")) 297 types.append(ASCIILiteral("text/uri-list")); 298 return types; 299 } 300 301 ASSERT(!safeTypes.contains("Files")); 302 return safeTypes; 285 303 } 286 304 -
trunk/Source/WebCore/dom/DataTransfer.h
r223195 r223340 122 122 #endif 123 123 124 bool shouldSuppressGetAndSetDataToAvoidExposingFilePaths() const; 125 124 126 enum class AddFilesType { No, Yes }; 125 127 Vector<String> types(AddFilesType) const; -
trunk/Source/WebCore/platform/Pasteboard.cpp
r222761 r223340 31 31 #include "Settings.h" 32 32 #include "SharedBuffer.h" 33 #include "URLParser.h" 33 34 #include <wtf/persistence/PersistentCoders.h> 34 35 #include <wtf/text/StringHash.h> … … 43 44 { 44 45 return type == "text/plain" || type == "text/html" || type == "text/uri-list"; 46 } 47 48 bool Pasteboard::canExposeURLToDOMWhenPasteboardContainsFiles(const String& urlString) 49 { 50 return URLParser { urlString }.result().protocolIsInHTTPFamily(); 45 51 } 46 52 -
trunk/Source/WebCore/platform/Pasteboard.h
r223195 r223340 190 190 191 191 static bool isSafeTypeForDOMToReadAndWrite(const String&); 192 static bool canExposeURLToDOMWhenPasteboardContainsFiles(const String&); 192 193 193 194 virtual bool isStatic() const { return false; } -
trunk/Source/WebCore/platform/PlatformPasteboard.h
r223195 r223340 71 71 WEBCORE_EXPORT RefPtr<SharedBuffer> bufferForType(const String& pasteboardType); 72 72 WEBCORE_EXPORT void getPathnamesForType(Vector<String>& pathnames, const String& pasteboardType) const; 73 WEBCORE_EXPORT String stringForType(const String& pasteboardType) ;73 WEBCORE_EXPORT String stringForType(const String& pasteboardType) const; 74 74 WEBCORE_EXPORT long changeCount() const; 75 75 WEBCORE_EXPORT Color color(); -
trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm
r223238 r223340 112 112 } 113 113 114 String PlatformPasteboard::stringForType(const String& type) 115 { 116 NSArray *values = [m_pasteboard valuesForPasteboardType:type inItemSet:[NSIndexSet indexSetWithIndex:0]]; 117 for (id value in values) { 118 if ([value isKindOfClass:[NSURL class]]) 119 return [(NSURL *)value absoluteString]; 120 121 if ([value isKindOfClass:[NSAttributedString class]]) 122 return [(NSAttributedString *)value string]; 123 124 if ([value isKindOfClass:[NSString class]]) 125 return (NSString *)value; 126 } 127 return String(); 114 static bool pasteboardMayContainFilePaths(id<AbstractPasteboard> pasteboard) 115 { 116 if ([pasteboard isKindOfClass:[WebItemProviderPasteboard class]]) 117 return false; 118 119 for (NSString *type in pasteboard.pasteboardTypes) { 120 if (Pasteboard::shouldTreatCocoaTypeAsFile(type)) 121 return true; 122 } 123 return false; 124 } 125 126 String PlatformPasteboard::stringForType(const String& type) const 127 { 128 auto value = retainPtr([m_pasteboard valuesForPasteboardType:type inItemSet:[NSIndexSet indexSetWithIndex:0]].firstObject); 129 String result; 130 if ([value isKindOfClass:[NSURL class]]) 131 result = [(NSURL *)value absoluteString]; 132 133 else if ([value isKindOfClass:[NSAttributedString class]]) 134 result = [(NSAttributedString *)value string]; 135 136 else if ([value isKindOfClass:[NSString class]]) 137 result = (NSString *)value; 138 139 if (pasteboardMayContainFilePaths(m_pasteboard.get()) && type == String { kUTTypeURL }) { 140 if (!Pasteboard::canExposeURLToDOMWhenPasteboardContainsFiles(result)) 141 result = { }; 142 } 143 144 return result; 128 145 } 129 146 … … 389 406 } 390 407 391 if (auto* coercedType = safeTypeForDOMToReadAndWriteForPlatformType(type)) 392 domPasteboardTypes.add(String::fromUTF8(coercedType)); 408 if (auto* coercedType = safeTypeForDOMToReadAndWriteForPlatformType(type)) { 409 auto domTypeAsString = String::fromUTF8(coercedType); 410 if (domTypeAsString == "text/uri-list") { 411 BOOL ableToDetermineProtocolOfPasteboardURL = ![m_pasteboard isKindOfClass:[WebItemProviderPasteboard class]]; 412 if (ableToDetermineProtocolOfPasteboardURL && stringForType(kUTTypeURL).isEmpty()) 413 continue; 414 } 415 domPasteboardTypes.add(WTFMove(domTypeAsString)); 416 } 393 417 } 394 418 -
trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm
r223238 r223340 79 79 } 80 80 81 String PlatformPasteboard::stringForType(const String& pasteboardType) 82 { 83 if (pasteboardType == String(NSURLPboardType)) { 84 if (NSURL *urlFromPasteboard = [NSURL URLFromPasteboard:m_pasteboard.get()]) 85 return urlFromPasteboard.absoluteString; 86 87 URL url([NSURL URLWithString:[m_pasteboard stringForType:NSURLPboardType]]); 88 if (!url.isValid()) 81 static bool pasteboardMayContainFilePaths(NSPasteboard *pasteboard) 82 { 83 for (NSString *type in pasteboard.types) { 84 if ([type isEqualToString:(NSString *)NSFilenamesPboardType] || [type isEqualToString:(NSString *)NSFilesPromisePboardType] || Pasteboard::shouldTreatCocoaTypeAsFile(type)) 85 return true; 86 } 87 return false; 88 } 89 90 String PlatformPasteboard::stringForType(const String& pasteboardType) const 91 { 92 if (pasteboardType == String { NSURLPboardType }) { 93 String urlString = ([NSURL URLFromPasteboard:m_pasteboard.get()] ?: [NSURL URLWithString:[m_pasteboard stringForType:NSURLPboardType]]).absoluteString; 94 if (pasteboardMayContainFilePaths(m_pasteboard.get()) && !Pasteboard::canExposeURLToDOMWhenPasteboardContainsFiles(urlString)) 89 95 return { }; 90 return url .string();96 return urlString; 91 97 } 92 98 … … 126 132 if (Pasteboard::isSafeTypeForDOMToReadAndWrite(type)) 127 133 domPasteboardTypes.add(type); 128 else if (auto* domType = safeTypeForDOMToReadAndWriteForPlatformType(type)) 129 domPasteboardTypes.add(String::fromUTF8(domType)); 134 else if (auto* domType = safeTypeForDOMToReadAndWriteForPlatformType(type)) { 135 auto domTypeAsString = String::fromUTF8(domType); 136 if (domTypeAsString == "text/uri-list" && stringForType(NSURLPboardType).isEmpty()) 137 continue; 138 domPasteboardTypes.add(WTFMove(domTypeAsString)); 139 } 130 140 } 131 141 -
trunk/Tools/ChangeLog
r223329 r223340 1 2017-10-16 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 On ToT, event.dataTransfer.getData("text/uri-list") returns an empty string when dragging an image 4 https://bugs.webkit.org/show_bug.cgi?id=178301 5 <rdar://problem/34990050> 6 7 Reviewed by Darin Adler. 8 9 Fixes issues in DumpRenderTree's LocalPasteboard to ensure that drag-drop-href-as-url.html exposes files, and 10 also adds a new iOS drag and drop API test. 11 12 * DumpRenderTree/mac/DumpRenderTreePasteboard.mm: 13 (-[LocalPasteboard addTypes:owner:]): 14 (-[LocalPasteboard setData:forType:]): 15 16 Fixes LocalPasteboard's implementation of changeCount to incremement when the pasteboard owner changes, rather 17 than every time data is changed. This is consistent with NSPasteboard behavior. 18 19 * TestWebKitAPI/Tests/ios/DataInteractionTests.mm: 20 (TestWebKitAPI::TEST): 21 22 Adds a new API test to verify that an image and HTTP URL written by the platform is correctly web exposed. 23 1 24 2017-10-15 Darin Adler <darin@apple.com> 2 25 -
trunk/Tools/DumpRenderTree/mac/DumpRenderTreePasteboard.mm
r223167 r223340 142 142 - (NSInteger)addTypes:(NSArray *)newTypes owner:(id)newOwner 143 143 { 144 _owner = newOwner; 144 if (_owner != newOwner) { 145 _owner = newOwner; 146 ++_changeCount; 147 } 148 145 149 for (NSString *type in newTypes) 146 150 _types.add(toUTI(type)); 147 151 148 return ++_changeCount;152 return _changeCount; 149 153 } 150 154 … … 187 191 188 192 _data.set(WTFMove(uti), data ? data : [NSData data]); 189 ++_changeCount;190 193 return YES; 191 194 } -
trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm
r223195 r223340 1561 1561 // File URLs should never be exposed directly to web content, so DataTransfer.getData should return an empty string here. 1562 1562 checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ 1563 @"dragover": @{ @"Files": @"" }, 1564 @"drop": @{ @"Files": @"" } 1563 @"dragover": @{ @"Files": @"", @"text/uri-list": @"" }, 1564 @"drop": @{ @"Files": @"", @"text/uri-list": @"" } 1565 }); 1566 } 1567 1568 TEST(DataInteractionTests, DataTransferGetDataWhenDroppingImageWithHTTPURL) 1569 { 1570 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); 1571 [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; 1572 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); 1573 1574 auto itemProvider = adoptNS([[UIItemProvider alloc] init]); 1575 [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(DataLoadCompletionBlock completionHandler) 1576 { 1577 completionHandler(UIImageJPEGRepresentation(testIconImage(), 0.5), nil); 1578 return nil; 1579 }]; 1580 [itemProvider registerObject:[NSURL URLWithString:@"http://webkit.org"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; 1581 [simulator setExternalItemProviders:@[ itemProvider.get() ]]; 1582 1583 [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; 1584 checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ 1585 @"dragover": @{ @"Files": @"", @"text/uri-list": @"" }, 1586 @"drop": @{ @"Files": @"", @"text/uri-list": @"http://webkit.org/" } 1565 1587 }); 1566 1588 }
Note: See TracChangeset
for help on using the changeset viewer.