<!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>[167180] trunk/Source/WebKit2</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/167180">167180</a></dd>
<dt>Author</dt> <dd>ap@apple.com</dd>
<dt>Date</dt> <dd>2014-04-11 20:09:38 -0700 (Fri, 11 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Mac] Crashes when copying or pasting huge images
https://bugs.webkit.org/show_bug.cgi?id=131576
&lt;rdar://problem/12131833&gt;
&lt;rdar://problem/14427398&gt;

Reviewed by Darin Adler.

Added a few null checks for SharedMemory::create() return value in pasteboard code.
Error handling feels a bit sketchy, but
- I'm not sure what it should look like ideally;
- it matches the kind of error handling we already have in these functions;
- it appears to work reasonably well in practice. We get empty content, which
is not nice, but not particularly problematic either. When copying an animated GIF,
we also get the GIF in RTFD flavor, so even pasting into NSTextViews works!

* Platform/mac/SharedMemoryMac.cpp:
(WebKit::SharedMemory::createFromVMBuffer):
* UIProcess/mac/WebContextMac.mm:
(WebKit::WebContext::getPasteboardBufferForType):
(WebKit::WebContext::readBufferFromPasteboard):
* WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
(WebKit::WebPlatformStrategies::setBufferForType):

* WebProcess/WebCoreSupport/mac/WebDragClientMac.mm: (WebKit::WebDragClient::declareAndWriteDragImage):
Also renamed some variables to prevent name collisions with with nested scope.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2PlatformmacSharedMemoryMaccpp">trunk/Source/WebKit2/Platform/mac/SharedMemoryMac.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWebContextMacmm">trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebPlatformStrategiescpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportmacWebDragClientMacmm">trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (167179 => 167180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-04-12 02:49:02 UTC (rev 167179)
+++ trunk/Source/WebKit2/ChangeLog        2014-04-12 03:09:38 UTC (rev 167180)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2014-04-11  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        [Mac] Crashes when copying or pasting huge images
+        https://bugs.webkit.org/show_bug.cgi?id=131576
+        &lt;rdar://problem/12131833&gt;
+        &lt;rdar://problem/14427398&gt;
+
+        Reviewed by Darin Adler.
+
+        Added a few null checks for SharedMemory::create() return value in pasteboard code.
+        Error handling feels a bit sketchy, but
+        - I'm not sure what it should look like ideally;
+        - it matches the kind of error handling we already have in these functions;
+        - it appears to work reasonably well in practice. We get empty content, which
+        is not nice, but not particularly problematic either. When copying an animated GIF,
+        we also get the GIF in RTFD flavor, so even pasting into NSTextViews works!
+
+        * Platform/mac/SharedMemoryMac.cpp:
+        (WebKit::SharedMemory::createFromVMBuffer):
+        * UIProcess/mac/WebContextMac.mm:
+        (WebKit::WebContext::getPasteboardBufferForType):
+        (WebKit::WebContext::readBufferFromPasteboard):
+        * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
+        (WebKit::WebPlatformStrategies::setBufferForType):
+
+        * WebProcess/WebCoreSupport/mac/WebDragClientMac.mm: (WebKit::WebDragClient::declareAndWriteDragImage):
+        Also renamed some variables to prevent name collisions with with nested scope.
+
</ins><span class="cx"> 2014-04-11  Ryuan Choi  &lt;ryuan.choi@samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix on the EFL port after r167152
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformmacSharedMemoryMaccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Platform/mac/SharedMemoryMac.cpp (167179 => 167180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/mac/SharedMemoryMac.cpp        2014-04-12 02:49:02 UTC (rev 167179)
+++ trunk/Source/WebKit2/Platform/mac/SharedMemoryMac.cpp        2014-04-12 03:09:38 UTC (rev 167180)
</span><span class="lines">@@ -133,8 +133,9 @@
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ASSERT(memoryObjectSize &gt;= round_page(size));
</del><span class="cx">     if (memoryObjectSize &lt; round_page(size)) {
</span><ins>+        // There is a limit on how large a shared memory object can be (see &lt;rdar://problem/16595870&gt;).
+        LOG_ERROR(&quot;Failed to create a mach port for shared memory of size %lu (got %llu bytes).&quot;, round_page(size), memoryObjectSize);
</ins><span class="cx">         mach_port_deallocate(mach_task_self(), port);
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWebContextMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm (167179 => 167180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm        2014-04-12 02:49:02 UTC (rev 167179)
+++ trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm        2014-04-12 03:09:38 UTC (rev 167180)
</span><span class="lines">@@ -306,6 +306,8 @@
</span><span class="cx">         return;
</span><span class="cx">     size = buffer-&gt;size();
</span><span class="cx">     RefPtr&lt;SharedMemory&gt; sharedMemoryBuffer = SharedMemory::create(size);
</span><ins>+    if (!sharedMemoryBuffer)
+        return;
</ins><span class="cx">     memcpy(sharedMemoryBuffer-&gt;data(), buffer-&gt;data(), size);
</span><span class="cx">     sharedMemoryBuffer-&gt;createHandle(handle, SharedMemory::ReadOnly);
</span><span class="cx"> }
</span><span class="lines">@@ -399,6 +401,8 @@
</span><span class="cx">         return;
</span><span class="cx">     size = buffer-&gt;size();
</span><span class="cx">     RefPtr&lt;SharedMemory&gt; sharedMemoryBuffer = SharedMemory::create(size);
</span><ins>+    if (!sharedMemoryBuffer)
+        return;
</ins><span class="cx">     memcpy(sharedMemoryBuffer-&gt;data(), buffer-&gt;data(), size);
</span><span class="cx">     sharedMemoryBuffer-&gt;createHandle(handle, SharedMemory::ReadOnly);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebPlatformStrategiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp (167179 => 167180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp        2014-04-12 02:49:02 UTC (rev 167179)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp        2014-04-12 03:09:38 UTC (rev 167180)
</span><span class="lines">@@ -465,8 +465,12 @@
</span><span class="cx">     SharedMemory::Handle handle;
</span><span class="cx">     if (buffer) {
</span><span class="cx">         RefPtr&lt;SharedMemory&gt; sharedMemoryBuffer = SharedMemory::create(buffer-&gt;size());
</span><del>-        memcpy(sharedMemoryBuffer-&gt;data(), buffer-&gt;data(), buffer-&gt;size());
-        sharedMemoryBuffer-&gt;createHandle(handle, SharedMemory::ReadOnly);
</del><ins>+        // FIXME: Null check prevents crashing, but it is not great that we will have empty pasteboard content for this type,
+        // because we've already set the types.
+        if (sharedMemoryBuffer) {
+            memcpy(sharedMemoryBuffer-&gt;data(), buffer-&gt;data(), buffer-&gt;size());
+            sharedMemoryBuffer-&gt;createHandle(handle, SharedMemory::ReadOnly);
+        }
</ins><span class="cx">     }
</span><span class="cx">     uint64_t newChangeCount;
</span><span class="cx">     WebProcess::shared().parentProcessConnection()-&gt;sendSync(Messages::WebContext::SetPasteboardBufferForType(pasteboardName, pasteboardType, handle, buffer ? buffer-&gt;size() : 0),
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportmacWebDragClientMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm (167179 => 167180)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm        2014-04-12 02:49:02 UTC (rev 167179)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm        2014-04-12 03:09:38 UTC (rev 167180)
</span><span class="lines">@@ -126,6 +126,8 @@
</span><span class="cx">     SharedMemory::Handle imageHandle;
</span><span class="cx">     
</span><span class="cx">     RefPtr&lt;SharedMemory&gt; sharedMemoryBuffer = SharedMemory::create(imageBuffer-&gt;size());
</span><ins>+    if (!sharedMemoryBuffer)
+        return;
</ins><span class="cx">     memcpy(sharedMemoryBuffer-&gt;data(), imageBuffer-&gt;data(), imageSize);
</span><span class="cx">     sharedMemoryBuffer-&gt;createHandle(imageHandle, SharedMemory::ReadOnly);
</span><span class="cx">     
</span><span class="lines">@@ -133,11 +135,13 @@
</span><span class="cx">     SharedMemory::Handle archiveHandle;
</span><span class="cx">     size_t archiveSize = 0;
</span><span class="cx">     if (data) {
</span><del>-        RefPtr&lt;SharedBuffer&gt; buffer = SharedBuffer::wrapNSData((NSData *)data.get());
-        RefPtr&lt;SharedMemory&gt; sharedMemoryBuffer = SharedMemory::create(buffer-&gt;size());
-        archiveSize = buffer-&gt;size();
-        memcpy(sharedMemoryBuffer-&gt;data(), buffer-&gt;data(), archiveSize);
-        sharedMemoryBuffer-&gt;createHandle(archiveHandle, SharedMemory::ReadOnly);            
</del><ins>+        RefPtr&lt;SharedBuffer&gt; archiveBuffer = SharedBuffer::wrapNSData((NSData *)data.get());
+        RefPtr&lt;SharedMemory&gt; archiveSharedMemoryBuffer = SharedMemory::create(archiveBuffer-&gt;size());
+        if (!archiveSharedMemoryBuffer)
+            return;
+        archiveSize = archiveBuffer-&gt;size();
+        memcpy(archiveSharedMemoryBuffer-&gt;data(), archiveBuffer-&gt;data(), archiveSize);
+        archiveSharedMemoryBuffer-&gt;createHandle(archiveHandle, SharedMemory::ReadOnly);
</ins><span class="cx">     }
</span><span class="cx">     m_page-&gt;send(Messages::WebPageProxy::SetPromisedData(pasteboardName, imageHandle, imageSize, String([response suggestedFilename]), extension, title, String([[response URL] absoluteString]), userVisibleString((NSURL *)url), archiveHandle, archiveSize));
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>