<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[260793] trunk/Source/WebKit</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/260793">260793</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2020-04-27 15:50:09 -0700 (Mon, 27 Apr 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>Prevent WebPasteboardProxy IPC messages from unconditionally requesting pasteboard types
https://bugs.webkit.org/show_bug.cgi?id=211061
<rdar://problem/62088185>

Reviewed by Tim Horton.

Tighten IPC message handling in WebPasteboardProxy, such that a web content process is unable to arbitrarily
request pasteboard types (and other metadata that depends on pasteboard types, such as the number of files
on the pasteboard).

This extends the mechanisms added in <a href="http://trac.webkit.org/projects/webkit/changeset/259151">r259151</a> by distinguishing between allowing the web process to request
type information from the pasteboard, and allowing the web process to request both types and data. In the
case of drag and drop, the former is required by the web process from the moment the drag session enters
the platform web view; however, the latter is required only after a drop is performed.

We utilize this new check, `canAccessPasteboardTypes`, in seven existing IPC message handlers that either
directly return the list of types, or return metadata from which pasteboard types may be deduced.

See below for more details; covered by existing API and layout tests.

* UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
(WebKit::WebPasteboardProxy::grantAccessToCurrentTypes):
(WebKit::WebPasteboardProxy::grantAccessToCurrentData):

Split the pasteboard access check into two helpers: one to determine whether the web process is allowed to
request pasteboard types, and another to determine whether the web process is allowed to request pasteboard
data (in addition to types).

(WebKit::WebPasteboardProxy::grantAccess):
(WebKit::WebPasteboardProxy::revokeAccess):

Refactor these to use `PasteboardAccessInformation`; see below for more details.

(WebKit::WebPasteboardProxy::canAccessPasteboardTypes const):

Return true as long as the accessType is nonnull; this is because either `Types` or `TypesAndData` is
sufficient for access to pasteboard types.

(WebKit::WebPasteboardProxy::canAccessPasteboardData const):
(WebKit::WebPasteboardProxy::accessType const):

Add a private helper method to return the access type (`nullopt` for no access, `PasteboardAccessType::Types`
for access to types only, and `PasteboardAccessType::TypesAndData` for access to data in addition to types)
for the given named pasteboard.

(WebKit::WebPasteboardProxy::didModifyContentsOfPasteboard):

Refactor this to use `PasteboardAccessInformation`.

(WebKit::WebPasteboardProxy::getPasteboardTypes):
(WebKit::WebPasteboardProxy::getPasteboardPathnamesForType):

Adopt canAccessPasteboardTypes here, and update the FIXME to state that we should really be using
canAccessPasteboardData instead. This is blocked on refactoring some more drag and drop code, such
that accessing the list of file names on the pasteboard isn't necessary before the drop is handled.

(WebKit::WebPasteboardProxy::containsURLStringSuitableForLoading):
(WebKit::WebPasteboardProxy::getNumberOfFiles):
(WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite):
(WebKit::WebPasteboardProxy::allPasteboardItemInfo):
(WebKit::WebPasteboardProxy::informationForItemAtIndex):
(WebKit::WebPasteboardProxy::getPasteboardItemsCount):
(WebKit::WebPasteboardProxy::containsStringSafeForDOMToReadForType):

Adopt the canAccessPasteboardTypes check in various places.

(WebKit::WebPasteboardProxy::PasteboardAccessInformation::grantAccess):
(WebKit::WebPasteboardProxy::PasteboardAccessInformation::revokeAccess):
(WebKit::WebPasteboardProxy::PasteboardAccessInformation::accessType const):

Introduce PasteboardAccessInformation, which replaces the current `std::pair<uint64_t, WeakHashSet<WebProcessProxy>>`
that is used to represent which web processes are allowed to access certain changeCounts, for a given pasteboard name.
Instead of maintaining a changeCount and set of processes, we now maintain a changeCount and list of (process, access
type) pairs. Each item in this list tracks whether the process that has been granted access should be allowed to read
only pasteboard types, or both types and data.

(WebKit::WebPasteboardProxy::revokeAccessToAllData): Deleted.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::dragEntered):
(WebKit::WebPageProxy::dragUpdated):

When updating the drag session (i.e. as the user drags over the web view), ensure that the web content
process is able to request pasteboard types.

* UIProcess/WebPasteboardProxy.cpp:
(WebKit::WebPasteboardProxy::allPasteboardItemInfo):
(WebKit::WebPasteboardProxy::informationForItemAtIndex):
(WebKit::WebPasteboardProxy::getPasteboardItemsCount):
(WebKit::WebPasteboardProxy::containsStringSafeForDOMToReadForType):
(WebKit::WebPasteboardProxy::containsURLStringSuitableForLoading):

Update these method signatures.

* UIProcess/WebPasteboardProxy.h:
* UIProcess/WebPasteboardProxy.messages.in:

Mark more IPC messages as `WantsConnection` so that we can use the `IPC::Connection` argument in the message handlers.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessCocoaWebPasteboardProxyCocoamm">trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxycpp">trunk/Source/WebKit/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPasteboardProxycpp">trunk/Source/WebKit/UIProcess/WebPasteboardProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPasteboardProxyh">trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPasteboardProxymessagesin">trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (260792 => 260793)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2020-04-27 22:42:31 UTC (rev 260792)
+++ trunk/Source/WebKit/ChangeLog       2020-04-27 22:50:09 UTC (rev 260793)
</span><span class="lines">@@ -1,3 +1,103 @@
</span><ins>+2020-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Prevent WebPasteboardProxy IPC messages from unconditionally requesting pasteboard types
+        https://bugs.webkit.org/show_bug.cgi?id=211061
+        <rdar://problem/62088185>
+
+        Reviewed by Tim Horton.
+
+        Tighten IPC message handling in WebPasteboardProxy, such that a web content process is unable to arbitrarily
+        request pasteboard types (and other metadata that depends on pasteboard types, such as the number of files
+        on the pasteboard).
+
+        This extends the mechanisms added in r259151 by distinguishing between allowing the web process to request
+        type information from the pasteboard, and allowing the web process to request both types and data. In the
+        case of drag and drop, the former is required by the web process from the moment the drag session enters
+        the platform web view; however, the latter is required only after a drop is performed.
+
+        We utilize this new check, `canAccessPasteboardTypes`, in seven existing IPC message handlers that either
+        directly return the list of types, or return metadata from which pasteboard types may be deduced.
+
+        See below for more details; covered by existing API and layout tests.
+
+        * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
+        (WebKit::WebPasteboardProxy::grantAccessToCurrentTypes):
+        (WebKit::WebPasteboardProxy::grantAccessToCurrentData):
+
+        Split the pasteboard access check into two helpers: one to determine whether the web process is allowed to
+        request pasteboard types, and another to determine whether the web process is allowed to request pasteboard
+        data (in addition to types).
+
+        (WebKit::WebPasteboardProxy::grantAccess):
+        (WebKit::WebPasteboardProxy::revokeAccess):
+
+        Refactor these to use `PasteboardAccessInformation`; see below for more details.
+
+        (WebKit::WebPasteboardProxy::canAccessPasteboardTypes const):
+
+        Return true as long as the accessType is nonnull; this is because either `Types` or `TypesAndData` is
+        sufficient for access to pasteboard types.
+
+        (WebKit::WebPasteboardProxy::canAccessPasteboardData const):
+        (WebKit::WebPasteboardProxy::accessType const):
+
+        Add a private helper method to return the access type (`nullopt` for no access, `PasteboardAccessType::Types`
+        for access to types only, and `PasteboardAccessType::TypesAndData` for access to data in addition to types)
+        for the given named pasteboard.
+
+        (WebKit::WebPasteboardProxy::didModifyContentsOfPasteboard):
+
+        Refactor this to use `PasteboardAccessInformation`.
+
+        (WebKit::WebPasteboardProxy::getPasteboardTypes):
+        (WebKit::WebPasteboardProxy::getPasteboardPathnamesForType):
+
+        Adopt canAccessPasteboardTypes here, and update the FIXME to state that we should really be using
+        canAccessPasteboardData instead. This is blocked on refactoring some more drag and drop code, such
+        that accessing the list of file names on the pasteboard isn't necessary before the drop is handled.
+
+        (WebKit::WebPasteboardProxy::containsURLStringSuitableForLoading):
+        (WebKit::WebPasteboardProxy::getNumberOfFiles):
+        (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite):
+        (WebKit::WebPasteboardProxy::allPasteboardItemInfo):
+        (WebKit::WebPasteboardProxy::informationForItemAtIndex):
+        (WebKit::WebPasteboardProxy::getPasteboardItemsCount):
+        (WebKit::WebPasteboardProxy::containsStringSafeForDOMToReadForType):
+
+        Adopt the canAccessPasteboardTypes check in various places.
+
+        (WebKit::WebPasteboardProxy::PasteboardAccessInformation::grantAccess):
+        (WebKit::WebPasteboardProxy::PasteboardAccessInformation::revokeAccess):
+        (WebKit::WebPasteboardProxy::PasteboardAccessInformation::accessType const):
+
+        Introduce PasteboardAccessInformation, which replaces the current `std::pair<uint64_t, WeakHashSet<WebProcessProxy>>`
+        that is used to represent which web processes are allowed to access certain changeCounts, for a given pasteboard name.
+        Instead of maintaining a changeCount and set of processes, we now maintain a changeCount and list of (process, access
+        type) pairs. Each item in this list tracks whether the process that has been granted access should be allowed to read
+        only pasteboard types, or both types and data.
+
+        (WebKit::WebPasteboardProxy::revokeAccessToAllData): Deleted.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::dragEntered):
+        (WebKit::WebPageProxy::dragUpdated):
+
+        When updating the drag session (i.e. as the user drags over the web view), ensure that the web content
+        process is able to request pasteboard types.
+
+        * UIProcess/WebPasteboardProxy.cpp:
+        (WebKit::WebPasteboardProxy::allPasteboardItemInfo):
+        (WebKit::WebPasteboardProxy::informationForItemAtIndex):
+        (WebKit::WebPasteboardProxy::getPasteboardItemsCount):
+        (WebKit::WebPasteboardProxy::containsStringSafeForDOMToReadForType):
+        (WebKit::WebPasteboardProxy::containsURLStringSuitableForLoading):
+
+        Update these method signatures.
+
+        * UIProcess/WebPasteboardProxy.h:
+        * UIProcess/WebPasteboardProxy.messages.in:
+
+        Mark more IPC messages as `WantsConnection` so that we can use the `IPC::Connection` argument in the message handlers.
+
</ins><span class="cx"> 2020-04-27  Alex Christensen  <achristensen@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Stop waiting for a BinarySemaphore on the main thread in the NetworkProcess
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessCocoaWebPasteboardProxyCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm (260792 => 260793)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm   2020-04-27 22:42:31 UTC (rev 260792)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm      2020-04-27 22:50:09 UTC (rev 260793)
</span><span class="lines">@@ -45,8 +45,18 @@
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><ins>+void WebPasteboardProxy::grantAccessToCurrentTypes(WebProcessProxy& process, const String& pasteboardName)
+{
+    grantAccess(process, pasteboardName, PasteboardAccessType::Types);
+}
+
</ins><span class="cx"> void WebPasteboardProxy::grantAccessToCurrentData(WebProcessProxy& process, const String& pasteboardName)
</span><span class="cx"> {
</span><ins>+    grantAccess(process, pasteboardName, PasteboardAccessType::TypesAndData);
+}
+
+void WebPasteboardProxy::grantAccess(WebProcessProxy& process, const String& pasteboardName, PasteboardAccessType type)
+{
</ins><span class="cx">     if (!m_webProcessProxyList.contains(&process))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -56,29 +66,38 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     auto changeCount = PlatformPasteboard(pasteboardName).changeCount();
</span><del>-    auto changeCountsAndProcesses = m_pasteboardNameToChangeCountAndProcessesMap.find(pasteboardName);
-    if (changeCountsAndProcesses != m_pasteboardNameToChangeCountAndProcessesMap.end() && changeCountsAndProcesses->value.first == changeCount) {
-        changeCountsAndProcesses->value.second.add(process);
</del><ins>+    auto changeCountsAndProcesses = m_pasteboardNameToAccessInformationMap.find(pasteboardName);
+    if (changeCountsAndProcesses != m_pasteboardNameToAccessInformationMap.end() && changeCountsAndProcesses->value.changeCount == changeCount) {
+        changeCountsAndProcesses->value.grantAccess(process, type);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WeakHashSet<WebProcessProxy> processes;
-    processes.add(process);
-    m_pasteboardNameToChangeCountAndProcessesMap.set(pasteboardName, std::make_pair(changeCount, WTFMove(processes)));
</del><ins>+    m_pasteboardNameToAccessInformationMap.set(pasteboardName, PasteboardAccessInformation { changeCount, {{ makeWeakPtr(process), type }} });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::revokeAccessToAllData(WebProcessProxy& process)
</del><ins>+void WebPasteboardProxy::revokeAccess(WebProcessProxy& process)
</ins><span class="cx"> {
</span><del>-    for (auto& changeCountAndProcesses : m_pasteboardNameToChangeCountAndProcessesMap.values())
-        changeCountAndProcesses.second.remove(process);
</del><ins>+    for (auto& changeCountAndProcesses : m_pasteboardNameToAccessInformationMap.values())
+        changeCountAndProcesses.revokeAccess(process);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WebPasteboardProxy::canAccessPasteboardTypes(IPC::Connection& connection, const String& pasteboardName) const
+{
+    return !!accessType(connection, pasteboardName);
+}
+
</ins><span class="cx"> bool WebPasteboardProxy::canAccessPasteboardData(IPC::Connection& connection, const String& pasteboardName) const
</span><span class="cx"> {
</span><del>-    MESSAGE_CHECK_WITH_RETURN_VALUE(!pasteboardName.isEmpty(), false);
</del><ins>+    auto type = accessType(connection, pasteboardName);
+    return type && *type == PasteboardAccessType::TypesAndData;
+}
</ins><span class="cx"> 
</span><ins>+Optional<WebPasteboardProxy::PasteboardAccessType> WebPasteboardProxy::accessType(IPC::Connection& connection, const String& pasteboardName) const
+{
+    MESSAGE_CHECK_WITH_RETURN_VALUE(!pasteboardName.isEmpty(), WTF::nullopt);
+
</ins><span class="cx">     auto* process = webProcessProxyForConnection(connection);
</span><del>-    MESSAGE_CHECK_WITH_RETURN_VALUE(process, false);
</del><ins>+    MESSAGE_CHECK_WITH_RETURN_VALUE(process, WTF::nullopt);
</ins><span class="cx"> 
</span><span class="cx">     for (auto* page : process->pages()) {
</span><span class="cx">         auto& preferences = page->preferences();
</span><span class="lines">@@ -91,15 +110,18 @@
</span><span class="cx">         // allowed unmitigated pasteboard access from script. As such, there is no security
</span><span class="cx">         // benefit in limiting the scope of pasteboard data access to only the web page that
</span><span class="cx">         // enables programmatic pasteboard access.
</span><del>-        return true;
</del><ins>+        return PasteboardAccessType::TypesAndData;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto changeCountAndProcesses = m_pasteboardNameToChangeCountAndProcessesMap.find(pasteboardName);
-    if (changeCountAndProcesses == m_pasteboardNameToChangeCountAndProcessesMap.end())
-        return false;
</del><ins>+    auto changeCountAndProcesses = m_pasteboardNameToAccessInformationMap.find(pasteboardName);
+    if (changeCountAndProcesses == m_pasteboardNameToAccessInformationMap.end())
+        return WTF::nullopt;
</ins><span class="cx"> 
</span><del>-    auto& [changeCount, processes] = changeCountAndProcesses->value;
-    return changeCount == PlatformPasteboard(pasteboardName).changeCount() && processes.contains(*process);
</del><ins>+    auto& information = changeCountAndProcesses->value;
+    if (information.changeCount != PlatformPasteboard(pasteboardName).changeCount())
+        return WTF::nullopt;
+
+    return information.accessType(*process);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPasteboardProxy::didModifyContentsOfPasteboard(IPC::Connection& connection, const String& pasteboardName, int64_t previousChangeCount, int64_t newChangeCount)
</span><span class="lines">@@ -107,16 +129,18 @@
</span><span class="cx">     auto* process = webProcessProxyForConnection(connection);
</span><span class="cx">     MESSAGE_CHECK(process);
</span><span class="cx"> 
</span><del>-    auto changeCountAndProcesses = m_pasteboardNameToChangeCountAndProcessesMap.find(pasteboardName);
-    if (changeCountAndProcesses != m_pasteboardNameToChangeCountAndProcessesMap.end() && previousChangeCount == changeCountAndProcesses->value.first) {
-        WeakHashSet<WebProcessProxy> processes;
-        processes.add(process);
-        changeCountAndProcesses->value = std::make_pair(newChangeCount, WTFMove(processes));
</del><ins>+    auto changeCountAndProcesses = m_pasteboardNameToAccessInformationMap.find(pasteboardName);
+    if (changeCountAndProcesses != m_pasteboardNameToAccessInformationMap.end() && previousChangeCount == changeCountAndProcesses->value.changeCount) {
+        if (auto accessType = changeCountAndProcesses->value.accessType(*process))
+            changeCountAndProcesses->value = PasteboardAccessInformation { newChangeCount, {{ makeWeakPtr(*process), *accessType }} };
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::getPasteboardTypes(const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::getPasteboardTypes(IPC::Connection& connection, const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
</ins><span class="cx"> {
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler({ });
+
</ins><span class="cx">     Vector<String> pasteboardTypes;
</span><span class="cx">     PlatformPasteboard(pasteboardName).getTypes(pasteboardTypes);
</span><span class="cx">     completionHandler(WTFMove(pasteboardTypes));
</span><span class="lines">@@ -127,7 +151,10 @@
</span><span class="cx"> {
</span><span class="cx">     MESSAGE_CHECK_COMPLETION(!pasteboardType.isEmpty(), completionHandler({ }, { }));
</span><span class="cx"> 
</span><del>-    // FIXME: This should consult canAccessPasteboardData() as well, and avoid responding with file paths if it returns false.
</del><ins>+    // FIXME: This should consult canAccessPasteboardData() instead, and avoid responding with file paths if it returns false.
+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler({ }, { });
+
</ins><span class="cx">     Vector<String> pathnames;
</span><span class="cx">     SandboxExtension::HandleArray sandboxExtensions;
</span><span class="cx">     if (webProcessProxyForConnection(connection)) {
</span><span class="lines">@@ -274,8 +301,11 @@
</span><span class="cx">     completionHandler(newChangeCount);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::containsURLStringSuitableForLoading(const String& pasteboardName, CompletionHandler<void(bool)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::containsURLStringSuitableForLoading(IPC::Connection& connection, const String& pasteboardName, CompletionHandler<void(bool)>&& completionHandler)
</ins><span class="cx"> {
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler(false);
+
</ins><span class="cx">     completionHandler(PlatformPasteboard(pasteboardName).containsURLStringSuitableForLoading());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -313,8 +343,11 @@
</span><span class="cx">     completionHandler(newChangeCount);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::getNumberOfFiles(const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::getNumberOfFiles(IPC::Connection& connection, const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
</ins><span class="cx"> {
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler(0);
+
</ins><span class="cx">     completionHandler(PlatformPasteboard(pasteboardName).numberOfFiles());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -322,6 +355,9 @@
</span><span class="cx"> {
</span><span class="cx">     MESSAGE_CHECK_COMPLETION(!origin.isNull(), completionHandler({ }));
</span><span class="cx"> 
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler({ });
+
</ins><span class="cx">     completionHandler(PlatformPasteboard(pasteboardName).typesSafeForDOMToReadAndWrite(origin));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -335,18 +371,27 @@
</span><span class="cx">     completionHandler(newChangeCount);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::allPasteboardItemInfo(const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<Vector<PasteboardItemInfo>>&&)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::allPasteboardItemInfo(IPC::Connection& connection, const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<Vector<PasteboardItemInfo>>&&)>&& completionHandler)
</ins><span class="cx"> {
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler({ });
+
</ins><span class="cx">     completionHandler(PlatformPasteboard(pasteboardName).allPasteboardItemInfo(changeCount));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::informationForItemAtIndex(size_t index, const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<PasteboardItemInfo>&&)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::informationForItemAtIndex(IPC::Connection& connection, size_t index, const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<PasteboardItemInfo>&&)>&& completionHandler)
</ins><span class="cx"> {
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler(WTF::nullopt);
+
</ins><span class="cx">     completionHandler(PlatformPasteboard(pasteboardName).informationForItemAtIndex(index, changeCount));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::getPasteboardItemsCount(const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::getPasteboardItemsCount(IPC::Connection& connection, const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
</ins><span class="cx"> {
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler(0);
+
</ins><span class="cx">     completionHandler(PlatformPasteboard(pasteboardName).count());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -393,8 +438,11 @@
</span><span class="cx">     completionHandler(WTFMove(handle), size);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::containsStringSafeForDOMToReadForType(const String& type, const String& pasteboardName, CompletionHandler<void(bool)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::containsStringSafeForDOMToReadForType(IPC::Connection& connection, const String& type, const String& pasteboardName, CompletionHandler<void(bool)>&& completionHandler)
</ins><span class="cx"> {
</span><ins>+    if (!canAccessPasteboardTypes(connection, pasteboardName))
+        return completionHandler(false);
+
</ins><span class="cx">     completionHandler(PlatformPasteboard(pasteboardName).containsStringSafeForDOMToReadForType(type));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -444,6 +492,44 @@
</span><span class="cx"> 
</span><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span><span class="cx"> 
</span><ins>+void WebPasteboardProxy::PasteboardAccessInformation::grantAccess(WebProcessProxy& process, PasteboardAccessType type)
+{
+    auto matchIndex = processes.findMatching([&](auto& processAndType) {
+        return processAndType.first == &process;
+    });
+
+    if (matchIndex == notFound) {
+        processes.append({ makeWeakPtr(process), type });
+        return;
+    }
+
+    if (type == PasteboardAccessType::TypesAndData)
+        processes[matchIndex].second = type;
+
+    processes.removeAllMatching([](auto& processAndType) {
+        return !processAndType.first;
+    });
+}
+
+void WebPasteboardProxy::PasteboardAccessInformation::revokeAccess(WebProcessProxy& process)
+{
+    processes.removeFirstMatching([&](auto& processAndType) {
+        return processAndType.first == &process;
+    });
+}
+
+Optional<WebPasteboardProxy::PasteboardAccessType> WebPasteboardProxy::PasteboardAccessInformation::accessType(WebProcessProxy& process) const
+{
+    auto matchIndex = processes.findMatching([&](auto& processAndType) {
+        return processAndType.first == &process;
+    });
+
+    if (matchIndex == notFound)
+        return WTF::nullopt;
+
+    return processes[matchIndex].second;
+}
+
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #undef MESSAGE_CHECK_COMPLETION
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (260792 => 260793)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp   2020-04-27 22:42:31 UTC (rev 260792)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp      2020-04-27 22:50:09 UTC (rev 260793)
</span><span class="lines">@@ -2392,6 +2392,9 @@
</span><span class="cx"> #if ENABLE(DRAG_SUPPORT)
</span><span class="cx"> void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(COCOA)
+    WebPasteboardProxy::singleton().grantAccessToCurrentTypes(m_process.get(), dragStorageName);
+#endif
</ins><span class="cx">     launchInitialProcessIfNecessary();
</span><span class="cx">     performDragControllerAction(DragControllerAction::Entered, dragData, dragStorageName, { }, { });
</span><span class="cx"> }
</span><span class="lines">@@ -2398,6 +2401,9 @@
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(COCOA)
+    WebPasteboardProxy::singleton().grantAccessToCurrentTypes(m_process.get(), dragStorageName);
+#endif
</ins><span class="cx">     performDragControllerAction(DragControllerAction::Updated, dragData, dragStorageName, { }, { });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -7671,7 +7677,7 @@
</span><span class="cx">     pageClient().clearAllEditCommands();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    WebPasteboardProxy::singleton().revokeAccessToAllData(m_process.get());
</del><ins>+    WebPasteboardProxy::singleton().revokeAccess(m_process.get());
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     auto resetStateReason = terminationReason == ProcessTerminationReason::NavigationSwap ? ResetStateReason::NavigationSwap : ResetStateReason::WebProcessExited;
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPasteboardProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.cpp (260792 => 260793)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.cpp     2020-04-27 22:42:31 UTC (rev 260792)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.cpp        2020-04-27 22:50:09 UTC (rev 260793)
</span><span class="lines">@@ -89,17 +89,17 @@
</span><span class="cx">     completionHandler(0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::allPasteboardItemInfo(const String&, int64_t, CompletionHandler<void(Optional<Vector<WebCore::PasteboardItemInfo>>&&)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::allPasteboardItemInfo(IPC::Connection&, const String&, int64_t, CompletionHandler<void(Optional<Vector<WebCore::PasteboardItemInfo>>&&)>&& completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     completionHandler(WTF::nullopt);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::informationForItemAtIndex(size_t, const String&, int64_t, CompletionHandler<void(Optional<WebCore::PasteboardItemInfo>&&)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::informationForItemAtIndex(IPC::Connection&, size_t, const String&, int64_t, CompletionHandler<void(Optional<WebCore::PasteboardItemInfo>&&)>&& completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     completionHandler(WTF::nullopt);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::getPasteboardItemsCount(const String&, CompletionHandler<void(uint64_t)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::getPasteboardItemsCount(IPC::Connection&, const String&, CompletionHandler<void(uint64_t)>&& completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     completionHandler(0);
</span><span class="cx"> }
</span><span class="lines">@@ -123,12 +123,12 @@
</span><span class="cx"> 
</span><span class="cx"> #endif // !USE(LIBWPE)
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::containsStringSafeForDOMToReadForType(const String&, const String&, CompletionHandler<void(bool)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::containsStringSafeForDOMToReadForType(IPC::Connection&, const String&, const String&, CompletionHandler<void(bool)>&& completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     completionHandler(false);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPasteboardProxy::containsURLStringSuitableForLoading(const String&, CompletionHandler<void(bool)>&& completionHandler)
</del><ins>+void WebPasteboardProxy::containsURLStringSuitableForLoading(IPC::Connection&, const String&, CompletionHandler<void(bool)>&& completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     completionHandler(false);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPasteboardProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h (260792 => 260793)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h       2020-04-27 22:42:31 UTC (rev 260792)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h  2020-04-27 22:50:09 UTC (rev 260793)
</span><span class="lines">@@ -59,8 +59,9 @@
</span><span class="cx">     void removeWebProcessProxy(WebProcessProxy&);
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    void revokeAccessToAllData(WebProcessProxy&);
</del><ins>+    void revokeAccess(WebProcessProxy&);
</ins><span class="cx">     void grantAccessToCurrentData(WebProcessProxy&, const String& pasteboardName);
</span><ins>+    void grantAccessToCurrentTypes(WebProcessProxy&, const String& pasteboardName);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(GTK)
</span><span class="lines">@@ -86,8 +87,8 @@
</span><span class="cx">     void updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName);
</span><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    void getNumberOfFiles(const String& pasteboardName, CompletionHandler<void(uint64_t)>&&);
-    void getPasteboardTypes(const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&&);
</del><ins>+    void getNumberOfFiles(IPC::Connection&, const String& pasteboardName, CompletionHandler<void(uint64_t)>&&);
+    void getPasteboardTypes(IPC::Connection&, const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&&);
</ins><span class="cx">     void getPasteboardPathnamesForType(IPC::Connection&, const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(Vector<String>&& pathnames, SandboxExtension::HandleArray&&)>&&);
</span><span class="cx">     void getPasteboardStringForType(IPC::Connection&, const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(String&&)>&&);
</span><span class="cx">     void getPasteboardStringsForType(IPC::Connection&, const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(Vector<String>&&)>&&);
</span><span class="lines">@@ -106,14 +107,14 @@
</span><span class="cx">     void readStringFromPasteboard(IPC::Connection&, size_t index, const String& pasteboardType, const String& pasteboardName, CompletionHandler<void(String&&)>&&);
</span><span class="cx">     void readURLFromPasteboard(IPC::Connection&, size_t index, const String& pasteboardName, CompletionHandler<void(String&& url, String&& title)>&&);
</span><span class="cx">     void readBufferFromPasteboard(IPC::Connection&, size_t index, const String& pasteboardType, const String& pasteboardName, CompletionHandler<void(SharedMemory::Handle&&, uint64_t size)>&&);
</span><del>-    void getPasteboardItemsCount(const String& pasteboardName, CompletionHandler<void(uint64_t)>&&);
-    void informationForItemAtIndex(size_t index, const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<WebCore::PasteboardItemInfo>&&)>&&);
-    void allPasteboardItemInfo(const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<Vector<WebCore::PasteboardItemInfo>>&&)>&&);
</del><ins>+    void getPasteboardItemsCount(IPC::Connection&, const String& pasteboardName, CompletionHandler<void(uint64_t)>&&);
+    void informationForItemAtIndex(IPC::Connection&, size_t index, const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<WebCore::PasteboardItemInfo>&&)>&&);
+    void allPasteboardItemInfo(IPC::Connection&, const String& pasteboardName, int64_t changeCount, CompletionHandler<void(Optional<Vector<WebCore::PasteboardItemInfo>>&&)>&&);
</ins><span class="cx"> 
</span><span class="cx">     void writeCustomData(IPC::Connection&, const Vector<WebCore::PasteboardCustomData>&, const String& pasteboardName, CompletionHandler<void(int64_t)>&&);
</span><span class="cx">     void typesSafeForDOMToReadAndWrite(IPC::Connection&, const String& pasteboardName, const String& origin, CompletionHandler<void(Vector<String>&&)>&&);
</span><del>-    void containsStringSafeForDOMToReadForType(const String&, const String& pasteboardName, CompletionHandler<void(bool)>&&);
-    void containsURLStringSuitableForLoading(const String& pasteboardName, CompletionHandler<void(bool)>&&);
</del><ins>+    void containsStringSafeForDOMToReadForType(IPC::Connection&, const String&, const String& pasteboardName, CompletionHandler<void(bool)>&&);
+    void containsURLStringSuitableForLoading(IPC::Connection&, const String& pasteboardName, CompletionHandler<void(bool)>&&);
</ins><span class="cx">     void urlStringSuitableForLoading(IPC::Connection&, const String& pasteboardName, CompletionHandler<void(String&& url, String&& title)>&&);
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(GTK)
</span><span class="lines">@@ -131,14 +132,27 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><ins>+    bool canAccessPasteboardTypes(IPC::Connection&, const String& pasteboardName) const;
</ins><span class="cx">     bool canAccessPasteboardData(IPC::Connection&, const String& pasteboardName) const;
</span><span class="cx">     void didModifyContentsOfPasteboard(IPC::Connection&, const String& pasteboardName, int64_t previousChangeCount, int64_t newChangeCount);
</span><ins>+
+    enum class PasteboardAccessType : uint8_t { Types, TypesAndData };
+    Optional<PasteboardAccessType> accessType(IPC::Connection&, const String& pasteboardName) const;
+    void grantAccess(WebProcessProxy&, const String& pasteboardName, PasteboardAccessType);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     WebProcessProxyList m_webProcessProxyList;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    HashMap<String, std::pair<int64_t, WeakHashSet<WebProcessProxy>>> m_pasteboardNameToChangeCountAndProcessesMap;
</del><ins>+    struct PasteboardAccessInformation {
+        int64_t changeCount { 0 };
+        Vector<std::pair<WeakPtr<WebProcessProxy>, PasteboardAccessType>> processes;
+
+        void grantAccess(WebProcessProxy&, PasteboardAccessType);
+        void revokeAccess(WebProcessProxy&);
+        Optional<PasteboardAccessType> accessType(WebProcessProxy&) const;
+    };
+    HashMap<String, PasteboardAccessInformation> m_pasteboardNameToAccessInformationMap;
</ins><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPasteboardProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in (260792 => 260793)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in     2020-04-27 22:42:31 UTC (rev 260792)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in        2020-04-27 22:50:09 UTC (rev 260793)
</span><span class="lines">@@ -31,18 +31,18 @@
</span><span class="cx"> 
</span><span class="cx">     WriteCustomData(Vector<WebCore::PasteboardCustomData> data, String pasteboardName) -> (int64_t changeCount) Synchronous WantsConnection
</span><span class="cx">     TypesSafeForDOMToReadAndWrite(String pasteboardName, String origin) -> (Vector<String> types) Synchronous WantsConnection
</span><del>-    AllPasteboardItemInfo(String pasteboardName, int64_t changeCount) -> (Optional<Vector<WebCore::PasteboardItemInfo>> allInfo) Synchronous
-    InformationForItemAtIndex(uint64_t index, String pasteboardName, int64_t changeCount) -> (Optional<WebCore::PasteboardItemInfo> info) Synchronous
-    GetPasteboardItemsCount(String pasteboardName) -> (uint64_t itemsCount) Synchronous
</del><ins>+    AllPasteboardItemInfo(String pasteboardName, int64_t changeCount) -> (Optional<Vector<WebCore::PasteboardItemInfo>> allInfo) Synchronous WantsConnection
+    InformationForItemAtIndex(uint64_t index, String pasteboardName, int64_t changeCount) -> (Optional<WebCore::PasteboardItemInfo> info) Synchronous WantsConnection
+    GetPasteboardItemsCount(String pasteboardName) -> (uint64_t itemsCount) Synchronous WantsConnection
</ins><span class="cx">     ReadStringFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (String string) Synchronous WantsConnection
</span><span class="cx">     ReadURLFromPasteboard(uint64_t index, String pasteboardName) -> (String url, String title) Synchronous WantsConnection
</span><span class="cx">     ReadBufferFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (WebKit::SharedMemory::Handle handle, uint64_t size) Synchronous WantsConnection
</span><del>-    ContainsStringSafeForDOMToReadForType(String type, String pasteboardName) -> (bool result) Synchronous
</del><ins>+    ContainsStringSafeForDOMToReadForType(String type, String pasteboardName) -> (bool result) Synchronous WantsConnection
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     # Pasteboard messages.
</span><del>-    GetNumberOfFiles(String pasteboardName) -> (uint64_t numberOfFiles) Synchronous
-    GetPasteboardTypes(String pasteboardName) -> (Vector<String> types) Synchronous
</del><ins>+    GetNumberOfFiles(String pasteboardName) -> (uint64_t numberOfFiles) Synchronous WantsConnection
+    GetPasteboardTypes(String pasteboardName) -> (Vector<String> types) Synchronous WantsConnection
</ins><span class="cx">     GetPasteboardPathnamesForType(String pasteboardName, String pasteboardType) -> (Vector<String> pathnames, WebKit::SandboxExtension::HandleArray sandboxExtensions) Synchronous WantsConnection
</span><span class="cx">     GetPasteboardStringForType(String pasteboardName, String pasteboardType) -> (String string) Synchronous WantsConnection
</span><span class="cx">     GetPasteboardStringsForType(String pasteboardName, String pasteboardType) -> (Vector<String> strings) Synchronous WantsConnection
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">     SetPasteboardColor(String pasteboardName, WebCore::Color color) -> (int64_t changeCount) Synchronous WantsConnection
</span><span class="cx">     SetPasteboardStringForType(String pasteboardName, String pasteboardType, String string) -> (int64_t changeCount) Synchronous WantsConnection
</span><span class="cx">     SetPasteboardBufferForType(String pasteboardName, String pasteboardType, WebKit::SharedMemory::Handle handle, uint64_t size) -> (int64_t changeCount) Synchronous WantsConnection
</span><del>-    ContainsURLStringSuitableForLoading(String pasteboardName) -> (bool result) Synchronous
</del><ins>+    ContainsURLStringSuitableForLoading(String pasteboardName) -> (bool result) Synchronous WantsConnection
</ins><span class="cx">     URLStringSuitableForLoading(String pasteboardName) -> (String url, String title) Synchronous WantsConnection
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>