Skip to content
Permalink
Browse files
Sanitize URL in pasteboard for other applications and cross origin co…
…ntent

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:


Canonical link: https://commits.webkit.org/194427@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223195 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
rniwa committed Oct 11, 2017
1 parent 7729f19 commit 7f2ccbd55e8b3ed12e8d9db235ff336124674e1b
Showing 56 changed files with 1,220 additions and 125 deletions.
@@ -1,3 +1,35 @@
2017-10-11 Ryosuke Niwa <rniwa@webkit.org>

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.

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:

2017-10-11 Andy Estes <aestes@apple.com>

[Payment Request] Implement Apple Pay merchant validation
@@ -74,6 +74,7 @@ editing/pasteboard/data-transfer-get-data-on-drop-plain-text.html [ Skip ]
editing/pasteboard/data-transfer-get-data-on-drop-rich-text.html [ Skip ]
editing/pasteboard/data-transfer-get-data-on-drop-url.html [ Skip ]
editing/pasteboard/data-transfer-is-unique-for-dragenter-and-dragleave.html [ Skip ]
editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html [ Skip ]
editing/pasteboard/drag-end-crash-accessing-item-list.html [ Skip ]
editing/pasteboard/data-transfer-item-list-add-file-on-drag.html [ Skip ]
editing/pasteboard/data-transfer-items-drop-file.html [ Skip ]
@@ -0,0 +1,12 @@
This tests calling getData returns the same malformed URL string set by setData

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS event.clipboardData.getData("text/URI-list") is "some bad URL"
PASS JSON.stringify(event.clipboardData.types) is "[\"text/uri-list\"]"
PASS JSON.stringify(Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type}))) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<body>
<script src="../../resources/js-test-pre.js"></script>
<div id="container">
<button onclick="runTest()">1. Copy</button>
<div id="source" oncopy="copy(event)" contenteditable>some text</div>
<div id="destination" onpaste="paste(event)" contenteditable>2. Paste here</div>
</div>
<script>

description('This tests calling getData returns the same malformed URL string set by setData');
jsTestIsAsync = true;

function runTest() {
document.getElementById('source').focus();
document.execCommand('selectAll');
document.execCommand('copy');
document.getElementById('destination').focus();
if (window.testRunner)
document.execCommand('paste');
}

function copy(event) {
event.clipboardData.setData('url', 'some bad URL');
event.preventDefault();
}

function paste(event) {
shouldBeEqualToString('event.clipboardData.getData("text/URI-list")', 'some bad URL');
shouldBeEqualToString('JSON.stringify(event.clipboardData.types)', '["text/uri-list"]');
shouldBeEqualToString('JSON.stringify(Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type})))',
'[{"kind":"string","type":"text/uri-list"}]');
document.getElementById('container').remove();
finishJSTest();
}

if (window.testRunner && window.internals) {
internals.settings.setCustomPasteboardDataEnabled(true);
runTest();
}

</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -14,7 +14,7 @@ Rich text
"foo/🤔👌🙃": "🤔👌🙃",
"text/html": "<b>年年年</b>",
"bar/מקור השם עברית": "<i>מקור השם עברית</i>",
"text/uri-list": "https://www.apple.com/",
"text/uri-list": "https://www.apple.com",
"baz/年年年": "https://www.webkit.org",
"text/rtf": "AAAAAAAAAAA"
}
@@ -5,7 +5,7 @@ Rich text
"foo/🤔👌🙃": "🤔👌🙃",
"text/html": "<b>年年年</b>",
"bar/מקור השם עברית": "<i>מקור השם עברית</i>",
"text/uri-list": "https://www.apple.com/",
"text/uri-list": "https://www.apple.com",
"baz/年年年": "https://www.webkit.org",
"text/rtf": "AAAAAAAAAAA"
}
@@ -0,0 +1,15 @@
This tests calling setData with a malformed URL in a null origin document. The malformed value should not be readable in another document

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS urlReadInSameDocument is "hello, world"
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"
PASS event.clipboardData.getData("url") is ""
PASS JSON.stringify(event.clipboardData.types) is "[]"
PASS JSON.stringify(Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type}))) is "[]"
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,15 @@
This tests calling setData with a malformed URL in a null origin document. The malformed value should not be readable in another document

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS urlReadInSameDocument is "hello, world"
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"
PASS event.clipboardData.getData("url") is ""
PASS JSON.stringify(event.clipboardData.types) is "[]"
PASS JSON.stringify(Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type}))) is "[]"
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<body>
<script src="../../resources/js-test-pre.js"></script>
<script>

description('This tests calling setData with a malformed URL in a null origin document. The malformed value should not be readable in another document');
jsTestIsAsync = true;

if (window.internals)
internals.settings.setCustomPasteboardDataEnabled(true);

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.src = `data:text/html;charset=utf-8,<!DOCTYPE html>
<button onclick="runTest()">1. Copy</button>
<div><br></div>
<div id="source" oncopy="copy(event)" contenteditable>some text</div>
<div id="destination" onpaste="paste(event)" contenteditable>2. Paste here</div>
<script>
function copy(event) {
event.clipboardData.setData('url', 'hello, world');
event.preventDefault();
}
function paste(event) {
parent.postMessage({
url: event.clipboardData.getData('url'),
types: event.clipboardData.types,
items: Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type})),
}, '*');
}
function runTest() {
document.body.getBoundingClientRect();
document.getElementById('source').focus();
document.execCommand('selectAll');
document.execCommand('copy');
document.getElementById('destination').focus();
if (window.testRunner)
document.execCommand('paste');
}
if (window.testRunner)
setTimeout(runTest, 10);
</scri` + 'pt>';

onmessage = (event) => {
urlReadInSameDocument = event.data.url;
shouldBeEqualToString('urlReadInSameDocument', 'hello, world');
typesInSameDocument = event.data.types;
shouldBeEqualToString('JSON.stringify(typesInSameDocument)', '["text/uri-list"]');
itemsInSameDocument = event.data.items;
shouldBeEqualToString('JSON.stringify(itemsInSameDocument)', '[{"kind":"string","type":"text/uri-list"}]');
document.getElementById('destination').focus();
if (window.testRunner)
document.execCommand('paste');
}

function doPaste(event) {
shouldBeEqualToString('event.clipboardData.getData("url")', '');
shouldBeEqualToString('JSON.stringify(event.clipboardData.types)', '[]');
shouldBeEqualToString('JSON.stringify(Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type})))', '[]');
document.getElementById('destination').remove();
finishJSTest();
}

</script>
<div id="destination" onpaste="doPaste(event)" contenteditable>3. Paste here</div>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,15 @@
This tests calling setData with a malformed URL in a null origin document. The malformed value should not be readable in another document

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS urlReadInSameDocument is "http://webkit.org/b/🤔?x=8 + 6<"
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"
PASS event.clipboardData.getData("url") is "http://webkit.org/b/%F0%9F%A4%94?x=8%20+%206%3C"
PASS JSON.stringify(event.clipboardData.types) is "[\"text/uri-list\"]"
PASS JSON.stringify(Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type}))) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<body>
<script src="../../resources/js-test-pre.js"></script>
<script>

description('This tests calling setData with a malformed URL in a null origin document. The malformed value should not be readable in another document');
jsTestIsAsync = true;

if (window.internals)
internals.settings.setCustomPasteboardDataEnabled(true);

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.src = `data:text/html;charset=utf-8,<!DOCTYPE html>
<button onclick="runTest()">1. Copy</button>
<div><br></div>
<div id="source" oncopy="copy(event)" contenteditable>http://webkit.org/b/&#x1F914;?x=8 + 6<</div>
<div id="destination" onpaste="paste(event)" contenteditable>2. Paste here</div>
<script>
const originalURL = document.getElementById('source').textContent;
function copy(event) {
event.clipboardData.setData('url', originalURL);
event.preventDefault();
}
function paste(event) {
parent.postMessage({
originalURL,
url: event.clipboardData.getData('url'),
types: event.clipboardData.types,
items: Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type})),
}, '*');
}
function runTest() {
document.body.getBoundingClientRect();
document.getElementById('source').focus();
document.execCommand('selectAll');
document.execCommand('copy');
document.getElementById('destination').focus();
if (window.testRunner)
document.execCommand('paste');
}
if (window.testRunner)
runTest();
</scri` + 'pt>';

onmessage = (event) => {
originalURL = event.data.originalURL;
urlReadInSameDocument = event.data.url;
shouldBeEqualToString('urlReadInSameDocument', originalURL);
typesInSameDocument = event.data.types;
shouldBeEqualToString('JSON.stringify(typesInSameDocument)', '["text/uri-list"]');
itemsInSameDocument = event.data.items;
shouldBeEqualToString('JSON.stringify(itemsInSameDocument)', '[{"kind":"string","type":"text/uri-list"}]');
document.getElementById('destination').focus();
if (window.testRunner)
document.execCommand('paste');
}

function doPaste(event) {
shouldBeEqualToString('event.clipboardData.getData("url")', (new URL(originalURL)).href);
shouldBeEqualToString('JSON.stringify(event.clipboardData.types)', '["text/uri-list"]');
shouldBeEqualToString('JSON.stringify(Array.from(event.clipboardData.items).map((item) => ({kind: item.kind, type: item.type})))',
'[{"kind":"string","type":"text/uri-list"}]');
document.getElementById('destination').remove();
finishJSTest();
}

</script>
<div id="destination" onpaste="doPaste(event)" contenteditable>3. Paste here</div>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,38 @@
This tests calling setData to set a URL in a null origin document. The URL should be sanitized when reading in another document.
To manually test, drag and drop the "1. Drag this" above to "2. Drop here" and "3. Drop here".

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

dragstart in the null origin document:
PASS urlReadInSameDocument is "http://webkit.org/b/🤔?x=8 + 6"
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"

dragover in the null origin document:
PASS urlReadInSameDocument is ""
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"

drop in the null origin document:
PASS urlReadInSameDocument is "http://webkit.org/b/🤔?x=8 + 6"
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"

dragstart in the null origin document:
PASS urlReadInSameDocument is "http://webkit.org/b/🤔?x=8 + 6"
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"

dragover in the file URL document:
PASS urlReadInSameDocument is ""
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"

drop in the file URL document:
PASS urlReadInSameDocument is "http://webkit.org/b/%F0%9F%A4%94?x=8%20+%206"
PASS JSON.stringify(typesInSameDocument) is "[\"text/uri-list\"]"
PASS JSON.stringify(itemsInSameDocument) is "[{\"kind\":\"string\",\"type\":\"text/uri-list\"}]"
PASS successfullyParsed is true

TEST COMPLETE

0 comments on commit 7f2ccbd

Please sign in to comment.