Changeset 223195 in webkit


Ignore:
Timestamp:
Oct 11, 2017, 12:01:10 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

Sanitize URL in pasteboard for other applications and cross origin content
https://bugs.webkit.org/show_bug.cgi?id=178060
<rdar://problem/34874518>

Reviewed by Wenson Hsieh.

Source/WebCore:

This patch introduces the sanitization of URL when written from a web content to prevent web content from
exploiting the URL parser of other applications in the system particularly of those that actively monitor
system pasteboard (a.k.a. clipboard on non-Cocoa platforms) and decode or otherwise process URLs.

Because the Web compatibility requires that DataTransfer exposes the original URL to any document in the
same origin as the one which wrote the URL into the pasteboard, we store a string which uniquely identifies
the origin of an originating document into our custom pasteboard data. Note that we expose any URL which
didn't come from WebKit since we don't expect URLs to reveal privacy sensitive information. We use UUID for
the origin identifier of a null origin document.

An alternative approach is to store the pasteboard data from the same origin into the document and invalidate
it when the system pasteboard changes. However, Pasteboard object cannot know about Document (as Pasteboard
is a platform object and Document is a WebCore object), this turns out be quite tricky as there are multiple
places where we create Pasteboard objects, and they all need to be aware of this special same origin
Pasteboard object that hangs off of Document. Also, this approach would result in the same origin code paths
to diverge between null origin and non-null origin documents.

Tests: editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document.html

editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin.html
editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin.html
editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html
http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url.html
CopyURL.ValidURL
CopyURL.UnescapedURL
CopyURL.MalformedURL
DataInteractionTests.DataTransferSetDataValidURL
DataInteractionTests.DataTransferSetDataUnescapedURL
DataInteractionTests.DataTransferSetDataInvalidURL

  • dom/DataTransfer.cpp:

(WebCore::originForDocument): Extracted from createForCopyAndPaste.
(WebCore::DataTransfer::createForCopyAndPaste):
(WebCore::DataTransfer::getDataForItem const): Read the URL from the custom data when the originating content
is of the same origin. When the originating content is cross origin, or there is no custom data (e.g. written
by another native application; or sanitization didn't result in any difference), then callback to native value.
(WebCore::DataTransfer::setDataFromItemList): Sanitize the URL before writing it to the native pasteboard.
Store the original value if the sanitization resulted in any difference.
(WebCore::DataTransfer::types const):
(WebCore::DataTransfer::commitToPasteboard): Moved the code to write custom data to Pasteboard since we need
to write the origin string with it.
(WebCore::DataTransfer::createForDragStartEvent): Added Document as an argument to compute the origin string.
(WebCore::DataTransfer::createForDrop): Ditto.
(WebCore::DataTransfer::createForUpdatingDropTarget):
(WebCore::DataTransfer::moveDragState):

  • dom/DataTransfer.h:
  • dom/Document.cpp:

(WebCore::Document::uniqueIdentifier): Added. See above.

  • dom/Document.h:
  • editing/Editor.cpp:

(WebCore::createDataTransferForClipboardEvent):
(WebCore::dispatchClipboardEvent):

  • page/DragController.cpp:

(WebCore::DragController::dispatchTextInputEventFor):

  • page/EventHandler.cpp:

(WebCore::EventHandler::performDragAndDrop):
(WebCore::EventHandler::handleDrag):

  • platform/Pasteboard.h:
  • platform/PasteboardStrategy.h:
  • platform/PlatformPasteboard.h:
  • platform/StaticPasteboard.cpp:

(WebCore::StaticPasteboard::takeCustomData): Moved the logic to write to native pasteboard to DataTransfer.

  • platform/StaticPasteboard.h:
  • platform/cocoa/PasteboardCocoa.mm:

(WebCore::Pasteboard::typesSafeForBindings):
(WebCore::Pasteboard::readStringInCustomData): Rewritten using readCustomData. See below.
(WebCore::Pasteboard::readOrigin): Added.
(WebCore::Pasteboard::readCustomData): Added. Populates the cache. Because a single Pasteboard object is never
allowed to read values once its content is updated by other applications, we can permanently cache the result.

  • platform/gtk/PasteboardGtk.cpp:

(WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string.
(WebCore::Pasteboard::readOrigin): Added.

  • platform/gtk/PlatformPasteboardGtk.cpp:

(WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Now takes the unused origin string.

  • platform/ios/PlatformPasteboardIOS.mm:

(WebCore::originKeyKeyForTeamData): Added.
(WebCore::customTypesKeyForTeamData): Added. Replaces the use of PasteboardCustomData::cocoaType() in the team
data for clarity since the team data key isn't same as the pasteboard type. We don't have to worry about the
backwards compatibility since drag & drop session doesn't persist across iOS upgrades, and there is no publicly
released iOS with this team data support.
(WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Read the origin string and the custom data
off the team data. Don't expose custom types that are written by cross origin documents.
(WebCore::PlatformPasteboard::write): Add the orign string with custom pasteboard types in the team data.
(WebCore::PlatformPasteboard::readURL): Fixed a bug that this function was not reading NSURL when UIPasteboard
serializes NSURL as a plist. This code is exercised by CopyURL.ValidURL.

  • platform/mac/PlatformPasteboardMac.mm:

(WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Don't add custom pasteboard types that are
added by cross origin documents.

  • platform/win/PasteboardWin.cpp:

(WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string.
(WebCore::Pasteboard::readOrigin): Added.

  • platform/wpe/PasteboardWPE.cpp:

(WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string.
(WebCore::Pasteboard::readOrigin): Added.

  • platform/wpe/PlatformPasteboardWPE.cpp:

(WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Now takes the unused origin string.

Source/WebKit:

Plubmed the origin identifier through IPC from Pasteboard in WebContent process to PlatformPasteboard in UIProcess.

  • UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:

(WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite):

  • UIProcess/WebPasteboardProxy.cpp:

(WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite):

  • UIProcess/WebPasteboardProxy.h:
  • UIProcess/WebPasteboardProxy.messages.in:
  • WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:

(WebKit::WebPlatformStrategies::typesSafeForDOMToReadAndWrite):

  • WebProcess/WebCoreSupport/WebPlatformStrategies.h:

Source/WebKitLegacy/mac:

  • WebCoreSupport/WebPlatformStrategies.h:
  • WebCoreSupport/WebPlatformStrategies.mm:

(WebPlatformStrategies::typesSafeForDOMToReadAndWrite):

Tools:

Added API tests for sanitizing URLs copied from web content, and that the original URL is exposed to the web content.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/CopyURL.mm: Added.

(readURLFromPasteboard): A helper function.

  • TestWebKitAPI/Tests/WebKitCocoa/copy-url.html: Added.
  • TestWebKitAPI/Tests/ios/DataInteractionTests.mm:

(DataInteractionTests.DataTransferGetDataWhenDroppingCustomData): Rebaselined. https://www.apple.com is no longer
normalized to https://www.apple.com/ by NSURL / UIPasteboard as expected.
(DataInteractionTests.DataTransferSetDataValidURL): Added.
(DataInteractionTests.DataTransferSetDataUnescapedURL): Added.
(DataInteractionTests.qDataTransferSetDataInvalidURL): Added.

LayoutTests:

Added tests for copying & pasting URLs. URLs should be %-escaped and any invalid URL should be stripped away and
invisible to a cross-origin content or a null origin document but the same origin content should have access to
its original form.

  • TestExpectations:
  • editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document-expected.txt: Added.
  • editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document.html: Added.
  • editing/pasteboard/data-transfer-get-data-on-drop-custom-expected.txt: Rebaselined. We no longer normalize

"https://www.apple.com" into "https://www.apple.com/" by NSURL / UIPasteboard within the same origin content.

  • editing/pasteboard/data-transfer-get-data-on-paste-custom-expected.txt: Ditto.
  • editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-expected.txt: Added.
  • editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin-expected.txt: Added.
  • editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin.html: Added.
  • editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin-expected.txt: Added.
  • editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin.html: Added.
  • editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin-expected.txt: Added.
  • editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html: Added.
  • editing/pasteboard/dataTransfer-setData-getData-expected.txt: Rebaselined. More test cases are passing.
  • editing/pasteboard/dataTransfer-setData-getData.html: Updated expectations as the original URL is now preserved.
  • http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url-expected.txt: Added.
  • http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url.html: Added.
  • http/tests/security/clipboard/resources/copy.html: Added.
  • platform/mac-wk1/TestExpectations:
Location:
trunk
Files:
14 added
42 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r223193 r223195  
     12017-10-11  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Sanitize URL in pasteboard for other applications and cross origin content
     4        https://bugs.webkit.org/show_bug.cgi?id=178060
     5        <rdar://problem/34874518>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Added tests for copying & pasting URLs. URLs should be %-escaped and any invalid URL should be stripped away and
     10        invisible to a cross-origin content or a null origin document but the same origin content should have access to
     11        its original form.
     12
     13        * TestExpectations:
     14        * editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document-expected.txt: Added.
     15        * editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document.html: Added.
     16        * editing/pasteboard/data-transfer-get-data-on-drop-custom-expected.txt: Rebaselined. We no longer normalize
     17        "https://www.apple.com" into "https://www.apple.com/" by NSURL / UIPasteboard within the same origin content.
     18        * editing/pasteboard/data-transfer-get-data-on-paste-custom-expected.txt: Ditto.
     19        * editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-expected.txt: Added.
     20        * editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin-expected.txt: Added.
     21        * editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin.html: Added.
     22        * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin-expected.txt: Added.
     23        * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin.html: Added.
     24        * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin-expected.txt: Added.
     25        * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html: Added.
     26        * editing/pasteboard/dataTransfer-setData-getData-expected.txt: Rebaselined. More test cases are passing.
     27        * editing/pasteboard/dataTransfer-setData-getData.html: Updated expectations as the original URL is now preserved.
     28        * http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url-expected.txt: Added.
     29        * http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url.html: Added.
     30        * http/tests/security/clipboard/resources/copy.html: Added.
     31        * platform/mac-wk1/TestExpectations:
     32
    1332017-10-11  Andy Estes  <aestes@apple.com>
    234
  • trunk/LayoutTests/TestExpectations

    r223076 r223195  
    7575editing/pasteboard/data-transfer-get-data-on-drop-url.html [ Skip ]
    7676editing/pasteboard/data-transfer-is-unique-for-dragenter-and-dragleave.html [ Skip ]
     77editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html [ Skip ]
    7778editing/pasteboard/drag-end-crash-accessing-item-list.html [ Skip ]
    7879editing/pasteboard/data-transfer-item-list-add-file-on-drag.html [ Skip ]
  • trunk/LayoutTests/editing/pasteboard/data-transfer-get-data-on-drop-custom-expected.txt

    r222595 r223195  
    1515        "text/html": "<b>年年年</b>",
    1616        "bar/מקור השם עברית": "<i>מקור השם עברית</i>",
    17         "text/uri-list": "https://www.apple.com/",
     17        "text/uri-list": "https://www.apple.com",
    1818        "baz/年年年": "https://www.webkit.org",
    1919        "text/rtf": "AAAAAAAAAAA"
  • trunk/LayoutTests/editing/pasteboard/data-transfer-get-data-on-paste-custom-expected.txt

    r222595 r223195  
    66        "text/html": "<b>年年年</b>",
    77        "bar/מקור השם עברית": "<i>מקור השם עברית</i>",
    8         "text/uri-list": "https://www.apple.com/",
     8        "text/uri-list": "https://www.apple.com",
    99        "baz/年年年": "https://www.webkit.org",
    1010        "text/rtf": "AAAAAAAAAAA"
  • trunk/LayoutTests/editing/pasteboard/dataTransfer-setData-getData-expected.txt

    r223167 r223195  
    66--- Test set/get 'URL':
    77PASS getDataResultType is "string"
    8 PASS getDataResult is "http://test.com/"
     8PASS getDataResult is "http://test.com"
    99--- Test set/get 'URL' with multiple URLs:
    1010PASS getDataResultType is "string"
    11 FAIL getDataResult should be http://test.com/. Was .
     11FAIL getDataResult should be http://test.com. Was http://test.com
     12http://check.com.
    1213--- Test set/get 'text/uri-list':
    1314PASS getDataResultType is "string"
    14 FAIL getDataResult should be http://test.com
    15 http://check.com. Was .
     15PASS getDataResult is "http://test.com\r\nhttp://check.com"
    1616--- Test set/get 'text/uri-list' using '\n':
    1717PASS getDataResultType is "string"
    18 FAIL getDataResult should be http://test.com
    19 http://check.com. Was .
     18PASS getDataResult is "http://test.com\nhttp://check.com"
    2019--- Test set 'text/uri-list', get 'URL':
    2120PASS getDataResultType is "string"
    22 FAIL getDataResult should be http://test.com/. Was .
     21FAIL getDataResult should be http://test.com. Was http://test.com
     22http://check.com.
    2323--- Test set 'URL', get 'text/uri-list':
    2424PASS getDataResultType is "string"
    25 FAIL getDataResult should be http://test.com
    26 http://check.com. Was .
     25PASS getDataResult is "http://test.com\r\nhttp://check.com"
    2726--- Test set 'text/uri-list', get 'URL', using only '\n':
    2827PASS getDataResultType is "string"
    29 FAIL getDataResult should be http://test.com/. Was .
     28FAIL getDataResult should be http://test.com. Was http://test.com
     29http://check.com.
    3030--- Test set/get 'text/uri-list' with comments:
    3131PASS getDataResultType is "string"
    32 FAIL getDataResult should be # comment
    33 http://test.com
    34 http://check.com. Was .
     32PASS getDataResult is "# comment\r\nhttp://test.com\r\nhttp://check.com"
    3533--- Test set 'text/uri-list', get 'URL' with comments:
    3634PASS getDataResultType is "string"
    37 FAIL getDataResult should be http://test.com/. Was .
     35FAIL getDataResult should be http://test.com. Was # comment
     36http://test.com
     37http://check.com.
    3838--- Test set 'text/uri-list', get 'URL' with only comments:
    3939PASS getDataResultType is "string"
    40 PASS getDataResult is ""
     40FAIL getDataResult should be . Was # comment
     41# comment 2
     42# comment 3.
    4143--- Test set/get 'text/plain':
    4244PASS getDataResultType is "string"
  • trunk/LayoutTests/editing/pasteboard/dataTransfer-setData-getData.html

    r217390 r223195  
    8686    debug("--- Test set/get 'URL':");
    8787    test("URL", "http://test.com",
    88          "URL", "http://test.com/");
     88         "URL", "http://test.com");
    8989
    9090    debug("--- Test set/get 'URL' with multiple URLs:");
    9191    test("URL", "http://test.com\r\nhttp://check.com",
    92          "URL", "http://test.com/");
     92         "URL", "http://test.com");
    9393
    9494    debug("--- Test set/get 'text/uri-list':");
     
    102102    debug("--- Test set 'text/uri-list', get 'URL':");
    103103    test("text/uri-list", "http://test.com\r\nhttp://check.com",
    104          "URL", "http://test.com/");
     104         "URL", "http://test.com");
    105105
    106106    debug("--- Test set 'URL', get 'text/uri-list':");
     
    110110    debug("--- Test set 'text/uri-list', get 'URL', using only '\\n':");
    111111    test("text/uri-list", "http://test.com\nhttp://check.com",
    112          "URL", "http://test.com/");
     112         "URL", "http://test.com");
    113113
    114114    debug("--- Test set/get 'text/uri-list' with comments:");
     
    118118    debug("--- Test set 'text/uri-list', get 'URL' with comments:");
    119119    test("text/uri-list", "# comment\r\nhttp://test.com\r\nhttp://check.com",
    120          "URL", "http://test.com/");
     120         "URL", "http://test.com");
    121121
    122122    debug("--- Test set 'text/uri-list', get 'URL' with only comments:");
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r223189 r223195  
    1313editing/pasteboard/data-transfer-get-data-on-drop-url.html [ Pass ]
    1414editing/pasteboard/data-transfer-is-unique-for-dragenter-and-dragleave.html [ Pass ]
     15editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html [ Pass ]
    1516editing/pasteboard/drag-end-crash-accessing-item-list.html [ Pass ]
    1617editing/pasteboard/data-transfer-item-list-add-file-on-drag.html [ Pass ]
  • trunk/LayoutTests/platform/win/TestExpectations

    r223189 r223195  
    11331133[ Debug ] editing/selection/4983858.html [ Skip ] # Debug Assertion
    11341134[ Debug ] editing/selection/4975120.html [ Skip ] # Debug Assertion
     1135
     1136# Custom pasteboard data is not supported on Windows.
     1137http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url.html
    11351138
    11361139webkit.org/b/140783 [ Release ] editing/pasteboard/copy-standalone-image.html [ Failure ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r223194 r223195  
     12017-10-11  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Sanitize URL in pasteboard for other applications and cross origin content
     4        https://bugs.webkit.org/show_bug.cgi?id=178060
     5        <rdar://problem/34874518>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        This patch introduces the sanitization of URL when written from a web content to prevent web content from
     10        exploiting the URL parser of other applications in the system particularly of those that actively monitor
     11        system pasteboard (a.k.a. clipboard on non-Cocoa platforms) and decode or otherwise process URLs.
     12
     13        Because the Web compatibility requires that DataTransfer exposes the original URL to any document in the
     14        same origin as the one which wrote the URL into the pasteboard, we store a string which uniquely identifies
     15        the origin of an originating document into our custom pasteboard data. Note that we expose any URL which
     16        didn't come from WebKit since we don't expect URLs to reveal privacy sensitive information. We use UUID for
     17        the origin identifier of a null origin document.
     18
     19        An alternative approach is to store the pasteboard data from the same origin into the document and invalidate
     20        it when the system pasteboard changes. However, Pasteboard object cannot know about Document (as Pasteboard
     21        is a platform object and Document is a WebCore object), this turns out be quite tricky as there are multiple
     22        places where we create Pasteboard objects, and they all need to be aware of this special same origin
     23        Pasteboard object that hangs off of Document. Also, this approach would result in the same origin code paths
     24        to diverge between null origin and non-null origin documents.
     25
     26        Tests: editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document.html
     27               editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin.html
     28               editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin.html
     29               editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html
     30               http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url.html
     31               CopyURL.ValidURL
     32               CopyURL.UnescapedURL
     33               CopyURL.MalformedURL
     34               DataInteractionTests.DataTransferSetDataValidURL
     35               DataInteractionTests.DataTransferSetDataUnescapedURL
     36               DataInteractionTests.DataTransferSetDataInvalidURL
     37
     38        * dom/DataTransfer.cpp:
     39        (WebCore::originForDocument): Extracted from createForCopyAndPaste.
     40        (WebCore::DataTransfer::createForCopyAndPaste):
     41        (WebCore::DataTransfer::getDataForItem const): Read the URL from the custom data when the originating content
     42        is of the same origin. When the originating content is cross origin, or there is no custom data (e.g. written
     43        by another native application; or sanitization didn't result in any difference), then callback to native value.
     44        (WebCore::DataTransfer::setDataFromItemList): Sanitize the URL before writing it to the native pasteboard.
     45        Store the original value if the sanitization resulted in any difference.
     46        (WebCore::DataTransfer::types const):
     47        (WebCore::DataTransfer::commitToPasteboard): Moved the code to write custom data to Pasteboard since we need
     48        to write the origin string with it.
     49        (WebCore::DataTransfer::createForDragStartEvent): Added Document as an argument to compute the origin string.
     50        (WebCore::DataTransfer::createForDrop): Ditto.
     51        (WebCore::DataTransfer::createForUpdatingDropTarget):
     52        (WebCore::DataTransfer::moveDragState):
     53        * dom/DataTransfer.h:
     54        * dom/Document.cpp:
     55        (WebCore::Document::uniqueIdentifier): Added. See above.
     56        * dom/Document.h:
     57        * editing/Editor.cpp:
     58        (WebCore::createDataTransferForClipboardEvent):
     59        (WebCore::dispatchClipboardEvent):
     60        * page/DragController.cpp:
     61        (WebCore::DragController::dispatchTextInputEventFor):
     62        * page/EventHandler.cpp:
     63        (WebCore::EventHandler::performDragAndDrop):
     64        (WebCore::EventHandler::handleDrag):
     65        * platform/Pasteboard.h:
     66        * platform/PasteboardStrategy.h:
     67        * platform/PlatformPasteboard.h:
     68        * platform/StaticPasteboard.cpp:
     69        (WebCore::StaticPasteboard::takeCustomData): Moved the logic to write to native pasteboard to DataTransfer.
     70        * platform/StaticPasteboard.h:
     71        * platform/cocoa/PasteboardCocoa.mm:
     72        (WebCore::Pasteboard::typesSafeForBindings):
     73        (WebCore::Pasteboard::readStringInCustomData): Rewritten using readCustomData. See below.
     74        (WebCore::Pasteboard::readOrigin): Added.
     75        (WebCore::Pasteboard::readCustomData): Added. Populates the cache. Because a single Pasteboard object is never
     76        allowed to read values once its content is updated by other applications, we can permanently cache the result.
     77        * platform/gtk/PasteboardGtk.cpp:
     78        (WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string.
     79        (WebCore::Pasteboard::readOrigin): Added.
     80        * platform/gtk/PlatformPasteboardGtk.cpp:
     81        (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Now takes the unused origin string.
     82        * platform/ios/PlatformPasteboardIOS.mm:
     83        (WebCore::originKeyKeyForTeamData): Added.
     84        (WebCore::customTypesKeyForTeamData): Added. Replaces the use of PasteboardCustomData::cocoaType() in the team
     85        data for clarity since the team data key isn't same as the pasteboard type. We don't have to worry about the
     86        backwards compatibility since drag & drop session doesn't persist across iOS upgrades, and there is no publicly
     87        released iOS with this team data support.
     88        (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Read the origin string and the custom data
     89        off the team data. Don't expose custom types that are written by cross origin documents.
     90        (WebCore::PlatformPasteboard::write): Add the orign string with custom pasteboard types in the team data.
     91        (WebCore::PlatformPasteboard::readURL): Fixed a bug that this function was not reading NSURL when UIPasteboard
     92        serializes NSURL as a plist. This code is exercised by CopyURL.ValidURL.
     93        * platform/mac/PlatformPasteboardMac.mm:
     94        (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Don't add custom pasteboard types that are
     95        added by cross origin documents.
     96        * platform/win/PasteboardWin.cpp:
     97        (WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string.
     98        (WebCore::Pasteboard::readOrigin): Added.
     99        * platform/wpe/PasteboardWPE.cpp:
     100        (WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string.
     101        (WebCore::Pasteboard::readOrigin): Added.
     102        * platform/wpe/PlatformPasteboardWPE.cpp:
     103        (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Now takes the unused origin string.
     104
    11052017-10-11  Antti Koivisto  <antti@apple.com>
    2106
  • trunk/Source/WebCore/dom/DataTransfer.cpp

    r223034 r223195  
    4242#include "Settings.h"
    4343#include "StaticPasteboard.h"
     44#include "URLParser.h"
    4445#include "WebCorePasteboardFileReader.h"
    4546
     
    7879}
    7980
    80 Ref<DataTransfer> DataTransfer::createForCopyAndPaste(StoreMode storeMode, std::unique_ptr<Pasteboard>&& pasteboard)
    81 {
    82     return adoptRef(*new DataTransfer(storeMode, WTFMove(pasteboard)));
     81static String originIdentifierForDocument(Document& document)
     82{
     83    auto origin = document.securityOrigin().toString();
     84    if (origin == "null")
     85        return document.uniqueIdentifier();
     86    return origin;
     87}
     88
     89Ref<DataTransfer> DataTransfer::createForCopyAndPaste(Document& document, StoreMode storeMode, std::unique_ptr<Pasteboard>&& pasteboard)
     90{
     91    auto dataTransfer = adoptRef(*new DataTransfer(storeMode, WTFMove(pasteboard)));
     92    dataTransfer->m_originIdentifier = originIdentifierForDocument(document);
     93    return dataTransfer;
    8394}
    8495
     
    122133}
    123134
    124 static bool shouldReadOrWriteTypeAsCustomData(const String& type)
    125 {
    126     return Settings::customPasteboardDataEnabled() && !Pasteboard::isSafeTypeForDOMToReadAndWrite(type);
    127 }
    128 
    129135void DataTransfer::clearData(const String& type)
    130136{
     
    150156
    151157    auto lowercaseType = stripLeadingAndTrailingHTMLSpaces(type).convertToASCIILowercase();
    152     if (shouldReadOrWriteTypeAsCustomData(lowercaseType))
    153         return m_pasteboard->readStringInCustomData(lowercaseType);
    154     return m_pasteboard->readString(lowercaseType);
     158    if (!Settings::customPasteboardDataEnabled())
     159        return m_pasteboard->readString(lowercaseType);
     160
     161    bool isSameOrigin = false;
     162    if (is<StaticPasteboard>(*m_pasteboard)) {
     163        // StaticPasteboard is only used to stage data written by websites before being committed to the system pasteboard.
     164        isSameOrigin = true;
     165    } else if (!m_originIdentifier.isNull()) {
     166        String originOfPasteboard = m_pasteboard->readOrigin();
     167        isSameOrigin = m_originIdentifier == originOfPasteboard;
     168    }
     169
     170    if (!isSameOrigin) {
     171        if (!Pasteboard::isSafeTypeForDOMToReadAndWrite(lowercaseType))
     172            return { };
     173        return m_pasteboard->readString(lowercaseType);
     174    }
     175
     176    String value = m_pasteboard->readStringInCustomData(lowercaseType);
     177    if (value.isNull() && Pasteboard::isSafeTypeForDOMToReadAndWrite(lowercaseType))
     178        value = m_pasteboard->readString(lowercaseType);
     179    return value;
    155180}
    156181
     
    179204    RELEASE_ASSERT(is<StaticPasteboard>(*m_pasteboard));
    180205
    181     if (shouldReadOrWriteTypeAsCustomData(type))
     206    if (!Settings::customPasteboardDataEnabled()) {
     207        m_pasteboard->writeString(type, data);
     208        return;
     209    }
     210
     211    String sanitizedData;
     212    if (type == "text/uri-list") {
     213        auto url = URLParser(data).result();
     214        if (url.isValid())
     215            sanitizedData = url.string();
     216    } else if (type == "text/plain")
     217        sanitizedData = data; // Nothing to sanitize.
     218
     219    if (sanitizedData != data)
    182220        downcast<StaticPasteboard>(*m_pasteboard).writeStringInCustomData(type, data);
    183     else
    184         m_pasteboard->writeString(type, data);
     221
     222    if (Pasteboard::isSafeTypeForDOMToReadAndWrite(type) && !sanitizedData.isNull())
     223        m_pasteboard->writeString(type, sanitizedData);
    185224}
    186225
     
    237276
    238277    if (m_pasteboard->containsFiles()) {
    239         ASSERT(!m_pasteboard->typesSafeForBindings().contains("Files"));
     278        ASSERT(!m_pasteboard->typesSafeForBindings(m_originIdentifier).contains("Files"));
    240279        return addFilesType == AddFilesType::Yes ? Vector<String> { ASCIILiteral("Files") } : Vector<String> { };
    241280    }
    242281
    243     auto types = m_pasteboard->typesSafeForBindings();
     282    auto types = m_pasteboard->typesSafeForBindings(m_originIdentifier);
    244283    ASSERT(!types.contains("Files"));
    245284    return types;
     
    323362}
    324363
     364void DataTransfer::commitToPasteboard(Pasteboard& nativePasteboard)
     365{
     366    ASSERT(is<StaticPasteboard>(*m_pasteboard) && !is<StaticPasteboard>(nativePasteboard));
     367    PasteboardCustomData customData = downcast<StaticPasteboard>(*m_pasteboard).takeCustomData();
     368    if (Settings::customPasteboardDataEnabled()) {
     369        customData.origin = m_originIdentifier;
     370        nativePasteboard.writeCustomData(customData);
     371        return;
     372    }
     373
     374    for (auto& entry : customData.platformData)
     375        nativePasteboard.writeString(entry.key, entry.value);
     376    for (auto& entry : customData.sameOriginCustomData)
     377        nativePasteboard.writeString(entry.key, entry.value);
     378}
     379
    325380#if !ENABLE(DRAG_SUPPORT)
    326381
     
    354409}
    355410
    356 Ref<DataTransfer> DataTransfer::createForDragStartEvent()
    357 {
    358     return adoptRef(*new DataTransfer(StoreMode::ReadWrite, std::make_unique<StaticPasteboard>(), Type::DragAndDropData));
    359 }
    360 
    361 Ref<DataTransfer> DataTransfer::createForDrop(std::unique_ptr<Pasteboard>&& pasteboard, DragOperation sourceOperation, bool draggingFiles)
     411Ref<DataTransfer> DataTransfer::createForDragStartEvent(Document& document)
     412{
     413    auto dataTransfer = adoptRef(*new DataTransfer(StoreMode::ReadWrite, std::make_unique<StaticPasteboard>(), Type::DragAndDropData));
     414    dataTransfer->m_originIdentifier = originIdentifierForDocument(document);
     415    return dataTransfer;
     416}
     417
     418Ref<DataTransfer> DataTransfer::createForDrop(Document& document, std::unique_ptr<Pasteboard>&& pasteboard, DragOperation sourceOperation, bool draggingFiles)
    362419{
    363420    auto dataTransfer = adoptRef(*new DataTransfer(DataTransfer::StoreMode::Readonly, WTFMove(pasteboard), draggingFiles ? Type::DragAndDropFiles : Type::DragAndDropData));
    364421    dataTransfer->setSourceOperation(sourceOperation);
     422    dataTransfer->m_originIdentifier = originIdentifierForDocument(document);
    365423    return dataTransfer;
    366424}
     
    377435    auto dataTransfer = adoptRef(*new DataTransfer(mode, WTFMove(pasteboard), draggingFiles ? Type::DragAndDropFiles : Type::DragAndDropData));
    378436    dataTransfer->setSourceOperation(sourceOperation);
     437    dataTransfer->m_originIdentifier = originIdentifierForDocument(document);
    379438    return dataTransfer;
    380439}
     
    590649    // contain data that was in the static pasteboard.
    591650    m_pasteboard->clear();
    592     downcast<StaticPasteboard>(other->pasteboard()).commitToPasteboard(*m_pasteboard);
     651    other->commitToPasteboard(*m_pasteboard);
    593652
    594653    m_dropEffect = other->m_dropEffect;
  • trunk/Source/WebCore/dom/DataTransfer.h

    r223034 r223195  
    4646    enum class StoreMode { Invalid, ReadWrite, Readonly, Protected };
    4747
    48     static Ref<DataTransfer> createForCopyAndPaste(StoreMode, std::unique_ptr<Pasteboard>&&);
     48    static Ref<DataTransfer> createForCopyAndPaste(Document&, StoreMode, std::unique_ptr<Pasteboard>&&);
    4949    static Ref<DataTransfer> createForInputEvent(const String& plainText, const String& htmlText);
    5050
     
    8383
    8484    Pasteboard& pasteboard() { return *m_pasteboard; }
     85    void commitToPasteboard(Pasteboard&);
    8586
    8687#if ENABLE(DRAG_SUPPORT)
    8788    static Ref<DataTransfer> createForDrag();
    88     static Ref<DataTransfer> createForDragStartEvent();
    89     static Ref<DataTransfer> createForDrop(std::unique_ptr<Pasteboard>&&, DragOperation, bool draggingFiles);
     89    static Ref<DataTransfer> createForDragStartEvent(Document&);
     90    static Ref<DataTransfer> createForDrop(Document&, std::unique_ptr<Pasteboard>&&, DragOperation, bool draggingFiles);
    9091    static Ref<DataTransfer> createForUpdatingDropTarget(Document&, std::unique_ptr<Pasteboard>&&, DragOperation, bool draggingFiles);
    9192
     
    125126    Vector<Ref<File>> filesFromPasteboardAndItemList() const;
    126127
     128    String m_originIdentifier;
    127129    StoreMode m_storeMode;
    128130    std::unique_ptr<Pasteboard> m_pasteboard;
  • trunk/Source/WebCore/dom/Document.cpp

    r223149 r223195  
    214214#include <wtf/SetForScope.h>
    215215#include <wtf/SystemTracing.h>
     216#include <wtf/UUID.h>
    216217#include <wtf/text/StringBuffer.h>
    217218#include <yarr/RegularExpression.h>
     
    53045305#endif
    53055306
     5307String Document::uniqueIdentifier()
     5308{
     5309    if (!m_uniqueIdentifier)
     5310        m_uniqueIdentifier = "null:" + createCanonicalUUIDString();
     5311    return m_uniqueIdentifier;
     5312}
     5313
    53065314ExceptionOr<Ref<XPathExpression>> Document::createExpression(const String& expression, RefPtr<XPathNSResolver>&& resolver)
    53075315{
  • trunk/Source/WebCore/dom/Document.h

    r223049 r223195  
    958958    uint64_t domTreeVersion() const { return m_domTreeVersion; }
    959959
     960    String uniqueIdentifier();
     961
    960962    // XPathEvaluator methods
    961963    WEBCORE_EXPORT ExceptionOr<Ref<XPathExpression>> createExpression(const String& expression, RefPtr<XPathNSResolver>&&);
     
    15181520    uint64_t m_domTreeVersion;
    15191521    static uint64_t s_globalTreeVersion;
    1520    
     1522
     1523    String m_uniqueIdentifier;
     1524
    15211525    HashSet<NodeIterator*> m_nodeIterators;
    15221526    HashSet<Range*> m_ranges;
  • trunk/Source/WebCore/editing/Editor.cpp

    r222956 r223195  
    346346}
    347347
    348 static Ref<DataTransfer> createDataTransferForClipboardEvent(ClipboardEventKind kind)
     348static Ref<DataTransfer> createDataTransferForClipboardEvent(Document& document, ClipboardEventKind kind)
    349349{
    350350    switch (kind) {
    351351    case ClipboardEventKind::Copy:
    352352    case ClipboardEventKind::Cut:
    353         return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::ReadWrite, std::make_unique<StaticPasteboard>());
     353        return DataTransfer::createForCopyAndPaste(document, DataTransfer::StoreMode::ReadWrite, std::make_unique<StaticPasteboard>());
    354354    case ClipboardEventKind::PasteAsPlainText:
    355355        if (Settings::customPasteboardDataEnabled()) {
     
    358358            auto pasteboard = std::make_unique<StaticPasteboard>();
    359359            pasteboard->writeString(plainTextType, plainText);
    360             return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Readonly, WTFMove(pasteboard));
     360            return DataTransfer::createForCopyAndPaste(document, DataTransfer::StoreMode::Readonly, WTFMove(pasteboard));
    361361        }
    362362        FALLTHROUGH;
    363363    case ClipboardEventKind::Paste:
    364         return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Readonly, Pasteboard::createForCopyAndPaste());
     364        return DataTransfer::createForCopyAndPaste(document, DataTransfer::StoreMode::Readonly, Pasteboard::createForCopyAndPaste());
    365365    case ClipboardEventKind::BeforeCopy:
    366366    case ClipboardEventKind::BeforeCut:
    367367    case ClipboardEventKind::BeforePaste:
    368         return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Invalid, std::make_unique<StaticPasteboard>());
     368        return DataTransfer::createForCopyAndPaste(document, DataTransfer::StoreMode::Invalid, std::make_unique<StaticPasteboard>());
    369369    }
    370370    ASSERT_NOT_REACHED();
    371     return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Invalid, std::make_unique<StaticPasteboard>());
     371    return DataTransfer::createForCopyAndPaste(document, DataTransfer::StoreMode::Invalid, std::make_unique<StaticPasteboard>());
    372372}
    373373
     
    381381        return true;
    382382
    383     auto dataTransfer = createDataTransferForClipboardEvent(kind);
     383    auto dataTransfer = createDataTransferForClipboardEvent(target->document(), kind);
    384384
    385385    ClipboardEvent::Init init;
     
    394394        auto pasteboard = Pasteboard::createForCopyAndPaste();
    395395        pasteboard->clear();
    396         downcast<StaticPasteboard>(dataTransfer->pasteboard()).commitToPasteboard(*pasteboard);
     396        dataTransfer->commitToPasteboard(*pasteboard);
    397397    }
    398398
  • trunk/Source/WebCore/page/DragController.cpp

    r223031 r223195  
    507507    String text = m_page.dragCaretController().isContentRichlyEditable() ? emptyString() : dragData.asPlainText();
    508508    Element* target = innerFrame->editor().findEventTargetFrom(m_page.dragCaretController().caretPosition());
     509    // FIXME: What guarantees target is not null?
    509510    return target->dispatchEvent(TextEvent::createForDrop(innerFrame->document()->domWindow(), text));
    510511}
  • trunk/Source/WebCore/page/EventHandler.cpp

    r223031 r223195  
    23902390            preventedDefault = targetFrame->eventHandler().performDragAndDrop(event, WTFMove(pasteboard), sourceOperation, draggingFiles);
    23912391    } else if (m_dragTarget) {
    2392         auto dataTransfer = DataTransfer::createForDrop(WTFMove(pasteboard), sourceOperation, draggingFiles);
     2392        auto dataTransfer = DataTransfer::createForDrop(m_dragTarget->document(), WTFMove(pasteboard), sourceOperation, draggingFiles);
    23932393        preventedDefault = dispatchDragEvent(eventNames().dropEvent, *m_dragTarget, event, dataTransfer);
    23942394        dataTransfer->makeInvalidForSecurity();
     
    36413641    if (!m_mouseDownMayStartDrag)
    36423642        return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
    3643    
     3643    ASSERT(dragState().source);
     3644
    36443645    if (!ExactlyOneBitSet(dragState().type)) {
    36453646        ASSERT((dragState().type & DragSourceActionSelection));
     
    36783679   
    36793680    if (dragState().shouldDispatchEvents) {
    3680         auto dragStartDataTransfer = DataTransfer::createForDragStartEvent();
     3681        ASSERT(dragState().source);
     3682        auto dragStartDataTransfer = DataTransfer::createForDragStartEvent(dragState().source->document());
    36813683        m_mouseDownMayStartDrag = dispatchDragStartEventOnSourceElement(dragStartDataTransfer);
    36823684        hasNonDefaultPasteboardData = dragStartDataTransfer->pasteboard().hasData() ? HasNonDefaultPasteboardData::Yes : HasNonDefaultPasteboardData::No;
  • trunk/Source/WebCore/platform/Pasteboard.h

    r223140 r223195  
    194194
    195195    virtual bool hasData();
    196     virtual Vector<String> typesSafeForBindings();
     196    virtual Vector<String> typesSafeForBindings(const String& origin);
    197197    virtual Vector<String> typesForLegacyUnsafeBindings();
     198    virtual String readOrigin();
    198199    virtual String readString(const String& type);
    199200    virtual String readStringInCustomData(const String& type);
     
    212213    virtual void write(const PasteboardWebContent&);
    213214
     215    virtual void writeCustomData(const PasteboardCustomData&);
     216
    214217    virtual bool containsFiles();
    215218    virtual bool canSmartReplace();
     
    251254    const String& name() const { return m_pasteboardName; }
    252255    long changeCount() const;
     256    const PasteboardCustomData& readCustomData();
    253257#endif
    254258
     
    262266#endif
    263267
    264     void writeCustomData(const PasteboardCustomData&);
    265 
    266268private:
    267269#if PLATFORM(IOS)
     
    296298    String m_pasteboardName;
    297299    long m_changeCount;
     300    std::optional<PasteboardCustomData> m_customDataCache;
    298301#endif
    299302
  • trunk/Source/WebCore/platform/PasteboardStrategy.h

    r222595 r223195  
    7373#endif
    7474
    75     virtual Vector<String> typesSafeForDOMToReadAndWrite(const String& pasteboardName) = 0;
     75    virtual Vector<String> typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin) = 0;
    7676    virtual long writeCustomData(const PasteboardCustomData&, const String& pasteboardName) = 0;
    7777
  • trunk/Source/WebCore/platform/PlatformPasteboard.h

    r222595 r223195  
    9696
    9797    WEBCORE_EXPORT long write(const PasteboardCustomData&);
    98     WEBCORE_EXPORT Vector<String> typesSafeForDOMToReadAndWrite() const;
     98    WEBCORE_EXPORT Vector<String> typesSafeForDOMToReadAndWrite(const String& origin) const;
    9999
    100100#if PLATFORM(GTK)
  • trunk/Source/WebCore/platform/StaticPasteboard.cpp

    r222964 r223195  
    2626#include "config.h"
    2727#include "StaticPasteboard.h"
    28 
    29 #include "Settings.h"
    30 #include "SharedBuffer.h"
    3128
    3229namespace WebCore {
     
    8683}
    8784
    88 void StaticPasteboard::commitToPasteboard(Pasteboard& pasteboard)
     85PasteboardCustomData StaticPasteboard::takeCustomData()
    8986{
    90     if (m_platformData.isEmpty() && m_customData.isEmpty())
    91         return;
    92 
    93     if (Settings::customPasteboardDataEnabled()) {
    94         pasteboard.writeCustomData({ { }, WTFMove(m_types), WTFMove(m_platformData), WTFMove(m_customData) });
    95         return;
    96     }
    97 
    98     for (auto& entry : m_platformData)
    99         pasteboard.writeString(entry.key, entry.value);
    100     for (auto& entry : m_customData)
    101         pasteboard.writeString(entry.key, entry.value);
     87    return { { }, WTFMove(m_types), WTFMove(m_platformData), WTFMove(m_customData) };
    10288}
    10389
  • trunk/Source/WebCore/platform/StaticPasteboard.h

    r222964 r223195  
    3737    StaticPasteboard();
    3838
    39     void commitToPasteboard(Pasteboard&);
     39    PasteboardCustomData takeCustomData();
    4040
    4141    bool isStatic() const final { return true; }
    4242
    4343    bool hasData() final;
    44     Vector<String> typesSafeForBindings() final { return m_types; }
     44    Vector<String> typesSafeForBindings(const String&) final { return m_types; }
    4545    Vector<String> typesForLegacyUnsafeBindings() final { return m_types; }
     46    String readOrigin() final { return { }; }
    4647    String readString(const String& type) final;
    4748    String readStringInCustomData(const String& type) final;
     
    5859    void write(const PasteboardImage&) final { }
    5960    void write(const PasteboardWebContent&) final { }
     61
     62    void writeCustomData(const PasteboardCustomData&) final { }
    6063
    6164    bool containsFiles() final { return false; }
  • trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm

    r223167 r223195  
    144144}
    145145
    146 Vector<String> Pasteboard::typesSafeForBindings()
    147 {
    148     Vector<String> types = platformStrategies()->pasteboardStrategy()->typesSafeForDOMToReadAndWrite(m_pasteboardName);
     146Vector<String> Pasteboard::typesSafeForBindings(const String& origin)
     147{
     148    Vector<String> types = platformStrategies()->pasteboardStrategy()->typesSafeForDOMToReadAndWrite(m_pasteboardName, origin);
    149149
    150150    // Enforce changeCount ourselves for security. We check after reading instead of before to be
     
    217217String Pasteboard::readStringInCustomData(const String& type)
    218218{
    219     auto buffer = readBufferForTypeWithSecurityCheck(PasteboardCustomData::cocoaType());
    220     if (!buffer)
    221         return { };
    222 
    223     // Enforce changeCount ourselves for security. We check after reading instead of before to be
    224     // sure it doesn't change between our testing the change count and accessing the data.
    225     if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
    226         return { };
    227 
    228     return PasteboardCustomData::fromSharedBuffer(*buffer).sameOriginCustomData.get(type);
     219    return readCustomData().sameOriginCustomData.get(type);
     220}
     221
     222String Pasteboard::readOrigin()
     223{
     224    return readCustomData().origin;
     225}
     226
     227const PasteboardCustomData& Pasteboard::readCustomData()
     228{
     229    if (m_customDataCache)
     230        return *m_customDataCache;
     231
     232    if (auto buffer = readBufferForTypeWithSecurityCheck(PasteboardCustomData::cocoaType()))
     233        m_customDataCache = PasteboardCustomData::fromSharedBuffer(*buffer);
     234    else
     235        m_customDataCache = PasteboardCustomData { };
     236    return *m_customDataCache;
    229237}
    230238
  • trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp

    r222702 r223195  
    256256}
    257257
    258 Vector<String> Pasteboard::typesSafeForBindings()
     258Vector<String> Pasteboard::typesSafeForBindings(const String&)
    259259{
    260260    notImplemented(); // webkit.org/b/177633: [GTK] Move to new Pasteboard API
     
    285285
    286286    return types;
     287}
     288
     289String Pasteboard::readOrigin()
     290{
     291    notImplemented(); // webkit.org/b/177633: [GTK] Move to new Pasteboard API
     292    return { };
    287293}
    288294
  • trunk/Source/WebCore/platform/gtk/PlatformPasteboardGtk.cpp

    r222595 r223195  
    4747}
    4848
    49 Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite() const
     49Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite(const String&) const
    5050{
    5151    return { };
  • trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm

    r222761 r223195  
    344344}
    345345
    346 Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite() const
     346static const char originKeyForTeamData[] = "com.apple.WebKit.drag-and-drop-team-data.origin";
     347static const char customTypesKeyForTeamData[] = "com.apple.WebKit.drag-and-drop-team-data.custom-types";
     348
     349Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite(const String& origin) const
    347350{
    348351    ListHashSet<String> domPasteboardTypes;
     
    355358            continue;
    356359
    357         id customTypes = [(NSDictionary *)teamDataObject objectForKey:@(PasteboardCustomData::cocoaType())];
     360        id originInTeamData = [(NSDictionary *)teamDataObject objectForKey:@(originKeyForTeamData)];
     361        if (![originInTeamData isKindOfClass:[NSString class]])
     362            continue;
     363        if (String((NSString *)originInTeamData) != origin)
     364            continue;
     365
     366        id customTypes = [(NSDictionary *)teamDataObject objectForKey:@(customTypesKeyForTeamData)];
    358367        if (![customTypes isKindOfClass:[NSArray class]])
    359368            continue;
     
    364373
    365374    if (NSData *serializedCustomData = [m_pasteboard dataForPasteboardType:@(PasteboardCustomData::cocoaType())]) {
    366         auto buffer = SharedBuffer::create(serializedCustomData);
    367         for (auto& type : PasteboardCustomData::fromSharedBuffer(buffer.get()).orderedTypes)
    368             domPasteboardTypes.add(type);
     375        auto data = PasteboardCustomData::fromSharedBuffer(SharedBuffer::create(serializedCustomData).get());
     376        if (data.origin == origin) {
     377            for (auto& type : data.orderedTypes)
     378                domPasteboardTypes.add(type);
     379        }
    369380    }
    370381
     
    403414            for (auto& type : data.orderedTypes)
    404415                [typesAsNSArray addObject:type];
    405             [representationsToRegister setTeamData:[NSKeyedArchiver archivedDataWithRootObject:@{ @(PasteboardCustomData::cocoaType()) : typesAsNSArray }]];
     416            [representationsToRegister setTeamData:[NSKeyedArchiver archivedDataWithRootObject:@{
     417                @(originKeyForTeamData) : data.origin, @(customTypesKeyForTeamData) : typesAsNSArray }]];
    406418            [representationsToRegister addData:serializedSharedBuffer.get() forType:@(PasteboardCustomData::cocoaType())];
    407419        }
     
    449461}
    450462
    451 Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite() const
     463Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite(const String&) const
    452464{
    453465    return { };
     
    517529{
    518530    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:index];
    519 
    520531    RetainPtr<NSArray> pasteboardItem = [m_pasteboard valuesForPasteboardType:type inItemSet:indexSet];
    521532
    522533    if (![pasteboardItem count])
    523         return URL();
     534        return { };
    524535
    525536    id value = [pasteboardItem objectAtIndex:0];
    526     ASSERT([value isKindOfClass:[NSURL class]]);
    527     if (![value isKindOfClass:[NSURL class]])
    528         return URL();
    529 
    530     if (!allowReadingURLAtIndex((NSURL *)value, index))
     537    NSURL *url = nil;
     538    if ([value isKindOfClass:[NSData class]]) {
     539        id plist = [NSPropertyListSerialization propertyListWithData:(NSData *)value options:NSPropertyListImmutable format:NULL error:NULL];
     540        if (![plist isKindOfClass:[NSArray class]])
     541            return { };
     542        NSArray *plistArray = (NSArray *)plist;
     543        if (plistArray.count < 2)
     544            return { };
     545        if (plistArray.count == 2)
     546            url = [NSURL URLWithString:plistArray[0]];
     547        else // The first string is the relative URL.
     548            url = [NSURL URLWithString:plistArray[0] relativeToURL:[NSURL URLWithString:plistArray[1]]];
     549    } else {
     550        ASSERT([value isKindOfClass:[NSURL class]]);
     551        if (![value isKindOfClass:[NSURL class]])
     552            return { };
     553        url = (NSURL *)value;
     554    }
     555
     556    if (!allowReadingURLAtIndex(url, index))
    531557        return { };
    532558
    533559#if PLATFORM(IOS) && !(PLATFORM(WATCHOS) || PLATFORM(APPLETV))
    534     title = [value _title];
     560    title = [url _title];
    535561#else
    536562    UNUSED_PARAM(title);
    537563#endif
    538564
    539     return (NSURL *)value;
     565    return url;
    540566}
    541567
  • trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm

    r222761 r223195  
    108108}
    109109
    110 Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite() const
     110Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite(const String& origin) const
    111111{
    112112    ListHashSet<String> domPasteboardTypes;
    113113    if (NSData *serializedCustomData = [m_pasteboard dataForType:@(PasteboardCustomData::cocoaType())]) {
    114         auto buffer = SharedBuffer::create(serializedCustomData);
    115         for (auto& type : PasteboardCustomData::fromSharedBuffer(buffer.get()).orderedTypes)
    116             domPasteboardTypes.add(type);
     114        auto data = PasteboardCustomData::fromSharedBuffer(SharedBuffer::create(serializedCustomData).get());
     115        if (data.origin == origin) {
     116            for (auto& type : data.orderedTypes)
     117                domPasteboardTypes.add(type);
     118        }
    117119    }
    118120
  • trunk/Source/WebCore/platform/win/PasteboardWin.cpp

    r222702 r223195  
    238238}
    239239
    240 Vector<String> Pasteboard::typesSafeForBindings()
     240Vector<String> Pasteboard::typesSafeForBindings(const String&)
    241241{
    242242    notImplemented();
     
    276276    copyToVector(results, vector);
    277277    return vector;
     278}
     279
     280String Pasteboard::readOrigin()
     281{
     282    notImplemented();
     283    return { };
    278284}
    279285
  • trunk/Source/WebCore/platform/wpe/PasteboardWPE.cpp

    r222699 r223195  
    5050}
    5151
    52 Vector<String> Pasteboard::typesSafeForBindings()
     52Vector<String> Pasteboard::typesSafeForBindings(const String&)
    5353{
    5454    notImplemented();
     
    6161    platformStrategies()->pasteboardStrategy()->getTypes(types);
    6262    return types;
     63}
     64
     65String Pasteboard::readOrigin()
     66{
     67    notImplemented(); // webkit.org/b/177633: [GTK] Move to new Pasteboard API
     68    return { };
    6369}
    6470
  • trunk/Source/WebCore/platform/wpe/PlatformPasteboardWPE.cpp

    r222595 r223195  
    117117}
    118118
    119 Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite() const
     119Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite(const String&) const
    120120{
    121121    return { };
  • trunk/Source/WebKit/ChangeLog

    r223192 r223195  
     12017-10-11  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Sanitize URL in pasteboard for other applications and cross origin content
     4        https://bugs.webkit.org/show_bug.cgi?id=178060
     5        <rdar://problem/34874518>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Plubmed the origin identifier through IPC from Pasteboard in WebContent process to PlatformPasteboard in UIProcess.
     10
     11        * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
     12        (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite):
     13        * UIProcess/WebPasteboardProxy.cpp:
     14        (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite):
     15        * UIProcess/WebPasteboardProxy.h:
     16        * UIProcess/WebPasteboardProxy.messages.in:
     17        * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
     18        (WebKit::WebPlatformStrategies::typesSafeForDOMToReadAndWrite):
     19        * WebProcess/WebCoreSupport/WebPlatformStrategies.h:
     20
    1212017-10-11  Chris Dumez  <cdumez@apple.com>
    222
  • trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm

    r222839 r223195  
    160160}
    161161
    162 void WebPasteboardProxy::typesSafeForDOMToReadAndWrite(const String& pasteboardName, Vector<String>& types)
    163 {
    164     types = PlatformPasteboard(pasteboardName).typesSafeForDOMToReadAndWrite();
     162void WebPasteboardProxy::typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin, Vector<String>& types)
     163{
     164    types = PlatformPasteboard(pasteboardName).typesSafeForDOMToReadAndWrite(origin);
    165165}
    166166
  • trunk/Source/WebKit/UIProcess/WebPasteboardProxy.cpp

    r222595 r223195  
    6464#if !PLATFORM(COCOA)
    6565
    66 void WebPasteboardProxy::typesSafeForDOMToReadAndWrite(const String&, Vector<String>& types)
     66void WebPasteboardProxy::typesSafeForDOMToReadAndWrite(const String&, const String&, Vector<String>& types)
    6767{
    6868    types = { };
  • trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h

    r222656 r223195  
    100100
    101101    void writeCustomData(const WebCore::PasteboardCustomData&, const String& pasteboardName, uint64_t& newChangeCount);
    102     void typesSafeForDOMToReadAndWrite(const String& pasteboardName, Vector<String>& types);
     102    void typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin, Vector<String>& types);
    103103
    104104#if PLATFORM(GTK)
  • trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in

    r222656 r223195  
    3737
    3838    WriteCustomData(struct WebCore::PasteboardCustomData data, String pasteboardName) -> (uint64_t changeCount)
    39     TypesSafeForDOMToReadAndWrite(String pasteboardName) -> (Vector<String> types)
     39    TypesSafeForDOMToReadAndWrite(String pasteboardName, String origin) -> (Vector<String> types)
    4040
    4141#if PLATFORM(COCOA)
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp

    r222938 r223195  
    406406#endif // PLATFORM(WPE)
    407407
    408 Vector<String> WebPlatformStrategies::typesSafeForDOMToReadAndWrite(const String& pasteboardName)
     408Vector<String> WebPlatformStrategies::typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin)
    409409{
    410410    Vector<String> types;
    411     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::TypesSafeForDOMToReadAndWrite(pasteboardName), Messages::WebPasteboardProxy::TypesSafeForDOMToReadAndWrite::Reply(types), 0);
     411    WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::TypesSafeForDOMToReadAndWrite(pasteboardName, origin), Messages::WebPasteboardProxy::TypesSafeForDOMToReadAndWrite::Reply(types), 0);
    412412    return types;
    413413}
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h

    r222938 r223195  
    9898#endif
    9999
    100     Vector<String> typesSafeForDOMToReadAndWrite(const String& pasteboardName) override;
     100    Vector<String> typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin) override;
    101101    long writeCustomData(const WebCore::PasteboardCustomData&, const String&) override;
    102102};
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r223192 r223195  
     12017-10-11  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Sanitize URL in pasteboard for other applications and cross origin content
     4        https://bugs.webkit.org/show_bug.cgi?id=178060
     5        <rdar://problem/34874518>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * WebCoreSupport/WebPlatformStrategies.h:
     10        * WebCoreSupport/WebPlatformStrategies.mm:
     11        (WebPlatformStrategies::typesSafeForDOMToReadAndWrite):
     12
    1132017-10-11  Chris Dumez  <cdumez@apple.com>
    214
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h

    r222938 r223195  
    8282
    8383    long writeCustomData(const WebCore::PasteboardCustomData&, const String& pasteboardName) override;
    84     Vector<String> typesSafeForDOMToReadAndWrite(const String& pasteboardName) override;
     84    Vector<String> typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin) override;
    8585
    8686    long addTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName) override;
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm

    r222938 r223195  
    179179}
    180180
    181 Vector<String> WebPlatformStrategies::typesSafeForDOMToReadAndWrite(const String& pasteboardName)
    182 {
    183     return PlatformPasteboard(pasteboardName).typesSafeForDOMToReadAndWrite();
     181Vector<String> WebPlatformStrategies::typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin)
     182{
     183    return PlatformPasteboard(pasteboardName).typesSafeForDOMToReadAndWrite(origin);
    184184}
    185185
  • trunk/Tools/ChangeLog

    r223192 r223195  
     12017-10-11  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Sanitize URL in pasteboard for other applications and cross origin content
     4        https://bugs.webkit.org/show_bug.cgi?id=178060
     5        <rdar://problem/34874518>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Added API tests for sanitizing URLs copied from web content, and that the original URL is exposed to the web content.
     10
     11        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     12        * TestWebKitAPI/Tests/WebKitCocoa/CopyURL.mm: Added.
     13        (readURLFromPasteboard): A helper function.
     14        * TestWebKitAPI/Tests/WebKitCocoa/copy-url.html: Added.
     15        * TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
     16        (DataInteractionTests.DataTransferGetDataWhenDroppingCustomData): Rebaselined. https://www.apple.com is no longer
     17        normalized to https://www.apple.com/ by NSURL / UIPasteboard as expected.
     18        (DataInteractionTests.DataTransferSetDataValidURL): Added.
     19        (DataInteractionTests.DataTransferSetDataUnescapedURL): Added.
     20        (DataInteractionTests.qDataTransferSetDataInvalidURL): Added.
     21
    1222017-10-11  Chris Dumez  <cdumez@apple.com>
    223
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r222839 r223195  
    546546                9B270FEE1DDC2C0B002D53F3 /* closed-shadow-tree-test.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B270FED1DDC25FD002D53F3 /* closed-shadow-tree-test.html */; };
    547547                9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
     548                9B62630C1F8C25C8007EE29B /* copy-url.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B62630B1F8C2510007EE29B /* copy-url.html */; };
     549                9B7A37C41F8AEBA5004AA228 /* CopyURL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */; };
    548550                9B7D740F1F8378770006C432 /* paste-rtfd.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B7D740E1F8377E60006C432 /* paste-rtfd.html */; };
    549551                9BD4239A1E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */; };
     
    842844                                CD0BD0A81F79982D001AB2CF /* ContextMenuImgWithVideo.html in Copy Resources */,
    843845                                5C2936961D5C00ED00DEAB1E /* CookieMessage.html in Copy Resources */,
     846                                9B62630C1F8C25C8007EE29B /* copy-url.html in Copy Resources */,
    844847                                7AEAD4811E20122700416EFE /* CrossPartitionFileSchemeAccess.html in Copy Resources */,
    845848                                F4AB578A1F65165400DB0DA1 /* custom-draggable-div.html in Copy Resources */,
     
    15101513                9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = "<group>"; };
    15111514                9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; };
     1515                9B62630B1F8C2510007EE29B /* copy-url.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "copy-url.html"; sourceTree = "<group>"; };
    15121516                9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstResponderScrollingPosition.mm; sourceTree = "<group>"; };
     1517                9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CopyURL.mm; sourceTree = "<group>"; };
    15131518                9B7D740E1F8377E60006C432 /* paste-rtfd.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "paste-rtfd.html"; sourceTree = "<group>"; };
    15141519                9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AttributedSubstringForProposedRangeWithImage.mm; sourceTree = "<group>"; };
     
    19831988                                5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */,
    19841989                                9999108A1F393C8B008AD455 /* Copying.mm */,
     1990                                9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */,
    19851991                                2DC4CF761D2D9DD800ECCC94 /* DataDetection.mm */,
    19861992                                CEC16EA41EE863BF00DE479A /* DecidePolicyForNavigationAction.mm */,
     
    22312237                                A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */,
    22322238                                5C2936941D5BFD1900DEAB1E /* CookieMessage.html */,
     2239                                9B62630B1F8C2510007EE29B /* copy-url.html */,
    22332240                                F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */,
    22342241                                F486B1CF1F6794FF00F34BDD /* DataTransfer-setDragImage.html */,
     
    32243231                                51D1249B1E785425002B2820 /* CookieManager.cpp in Sources */,
    32253232                                9999108B1F393C96008AD455 /* Copying.mm in Sources */,
     3233                                9B7A37C41F8AEBA5004AA228 /* CopyURL.mm in Sources */,
    32263234                                7CCE7EAC1A411A3400447C4C /* Counters.cpp in Sources */,
    32273235                                7AEAD47F1E20116C00416EFE /* CrossPartitionFileSchemeAccess.mm in Sources */,
  • trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm

    r222743 r223195  
    15221522            @"text/html" : @"<b>bold text</b>",
    15231523            @"bar/html" : @"<i>italic text</i>",
    1524             @"text/uri-list" : @"https://www.apple.com/",
     1524            @"text/uri-list" : @"https://www.apple.com",
    15251525            @"baz/uri-list" : @"https://www.webkit.org"
    15261526        }
     
    16461646}
    16471647
     1648TEST(DataInteractionTests, DataTransferSetDataValidURL)
     1649{
     1650    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     1651    [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"];
     1652    auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
     1653
     1654    [webView stringByEvaluatingJavaScript:@"select(rich)"];
     1655    [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'https://webkit.org/b/123' }"];
     1656    [webView stringByEvaluatingJavaScript:@"writeCustomData = true"];
     1657
     1658    __block bool done = false;
     1659    [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
     1660    {
     1661        EXPECT_EQ(1UL, session.items.count);
     1662        auto *item = session.items[0].itemProvider;
     1663        EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]);
     1664        EXPECT_TRUE([item canLoadObjectOfClass: [NSURL class]]);
     1665        [item loadObjectOfClass:[NSURL class] completionHandler:^(id<NSItemProviderReading> url, NSError *error) {
     1666            EXPECT_TRUE([url isKindOfClass: [NSURL class]]);
     1667            EXPECT_WK_STREQ([(NSURL *)url absoluteString], @"https://webkit.org/b/123");
     1668            done = true;
     1669        }];
     1670        return session.items;
     1671    }];
     1672    [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)];
     1673
     1674    checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{
     1675        @"dragover": @{
     1676            @"text/uri-list": @"",
     1677        },
     1678        @"drop": @{
     1679            @"text/uri-list": @"https://webkit.org/b/123",
     1680        }
     1681    });
     1682    TestWebKitAPI::Util::run(&done);
     1683}
     1684
     1685TEST(DataInteractionTests, DataTransferSetDataUnescapedURL)
     1686{
     1687    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     1688    [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"];
     1689    auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
     1690
     1691    [webView stringByEvaluatingJavaScript:@"select(rich)"];
     1692    [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'http://webkit.org/b/\u4F60\u597D;?x=8 + 6' }"];
     1693    [webView stringByEvaluatingJavaScript:@"writeCustomData = true"];
     1694
     1695    __block bool done = false;
     1696    [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
     1697    {
     1698        EXPECT_EQ(1UL, session.items.count);
     1699        auto *item = session.items[0].itemProvider;
     1700        EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]);
     1701        EXPECT_TRUE([item canLoadObjectOfClass: [NSURL class]]);
     1702        [item loadObjectOfClass:[NSURL class] completionHandler:^(id<NSItemProviderReading> url, NSError *error) {
     1703            EXPECT_TRUE([url isKindOfClass: [NSURL class]]);
     1704            EXPECT_WK_STREQ([(NSURL *)url absoluteString], @"http://webkit.org/b/%E4%BD%A0%E5%A5%BD;?x=8%20+%206");
     1705            done = true;
     1706        }];
     1707        return session.items;
     1708    }];
     1709    [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)];
     1710
     1711    checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{
     1712        @"dragover": @{
     1713            @"text/uri-list": @"",
     1714        },
     1715        @"drop": @{
     1716            @"text/uri-list": @"http://webkit.org/b/\u4F60\u597D;?x=8 + 6",
     1717        }
     1718    });
     1719    TestWebKitAPI::Util::run(&done);
     1720}
     1721
     1722TEST(DataInteractionTests, DataTransferSetDataInvalidURL)
     1723{
     1724    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     1725    [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"];
     1726    auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
     1727
     1728    [webView stringByEvaluatingJavaScript:@"select(rich)"];
     1729    [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'some random string' }"];
     1730    [webView stringByEvaluatingJavaScript:@"writeCustomData = true"];
     1731
     1732    [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)];
     1733    NSArray *registeredTypes = [simulator.get().sourceItemProviders.firstObject registeredTypeIdentifiers];
     1734    EXPECT_FALSE([registeredTypes containsObject:(NSString *)kUTTypeURL]);
     1735    checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{
     1736        @"dragover": @{
     1737            @"text/uri-list": @"",
     1738        },
     1739        @"drop": @{
     1740            @"text/uri-list": @"some random string",
     1741        }
     1742    });
     1743}
     1744
    16481745#endif // __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300
    16491746
Note: See TracChangeset for help on using the changeset viewer.