Bug 1153613 - [e10s], ensure the buffer for the drag image is large enough for SourceSurfaceRawData::GuaranteePersistance() to succeed, r=mattwoodrow
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 14 Apr 2015 13:50:59 +0300
changeset 268828 18a3c813d1fb88b8e287eed6d2d4837052f0540a
parent 268827 2c35e6083edecc9626e75f0f29504ffdc0ea2cdf
child 268829 2add06aad422a5f3e84cc058b4f27c3d04824134
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1153613
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1153613 - [e10s], ensure the buffer for the drag image is large enough for SourceSurfaceRawData::GuaranteePersistance() to succeed, r=mattwoodrow
dom/ipc/TabParent.cpp
widget/nsDragServiceProxy.cpp
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2978,17 +2978,18 @@ TabParent::RecvInvokeDragSession(nsTArra
   if (Manager()->IsContentParent()) {
     nsCOMPtr<nsIDragService> dragService =
       do_GetService("@mozilla.org/widget/dragservice;1");
     if (dragService) {
       dragService->MaybeAddChildProcess(Manager()->AsContentParent());
     }
   }
 
-  if (aVisualDnDData.IsEmpty()) {
+  if (aVisualDnDData.IsEmpty() ||
+      (aVisualDnDData.Length() < aHeight * aStride)) {
     mDnDVisualization = nullptr;
   } else {
     mDnDVisualization =
       new mozilla::gfx::SourceSurfaceRawData();
     mozilla::gfx::SourceSurfaceRawData* raw =
       static_cast<mozilla::gfx::SourceSurfaceRawData*>(mDnDVisualization.get());
     raw->InitWrappingData(
       reinterpret_cast<uint8_t*>(const_cast<nsCString&>(aVisualDnDData).BeginWriting()),
--- a/widget/nsDragServiceProxy.cpp
+++ b/widget/nsDragServiceProxy.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDragServiceProxy.h"
 #include "nsIDocument.h"
 #include "nsISupportsPrimitives.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/UniquePtr.h"
 #include "mozilla/unused.h"
 #include "nsContentUtils.h"
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsDragServiceProxy, nsBaseDragService)
 
 nsDragServiceProxy::nsDragServiceProxy()
 {
 }
@@ -57,22 +58,29 @@ nsDragServiceProxy::InvokeDragSession(ns
     if (surface) {
       mozilla::RefPtr<mozilla::gfx::DataSourceSurface> dataSurface =
         surface->GetDataSurface();
       mozilla::gfx::DataSourceSurface::MappedSurface map;
       dataSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map);
       mozilla::gfx::IntSize size = dataSurface->GetSize();
       mozilla::CheckedInt32 requiredBytes =
         mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
-      size_t bufLen = requiredBytes.isValid() ? requiredBytes.value() : 0;
+      size_t maxBufLen = requiredBytes.isValid() ? requiredBytes.value() : 0;
       mozilla::gfx::SurfaceFormat format = dataSurface->GetFormat();
       // Surface data handling is totally nuts. This is the magic one needs to
       // know to access the data.
-      bufLen = bufLen - map.mStride + (size.width * BytesPerPixel(format));
-      nsDependentCString dragImage(reinterpret_cast<char*>(map.mData), bufLen);
+      size_t bufLen =
+        maxBufLen - map.mStride + (size.width * BytesPerPixel(format));
+
+      // nsDependentCString wants null-terminated string.
+      mozilla::UniquePtr<char[]> dragImageData(new char[maxBufLen + 1]);
+      memcpy(dragImageData.get(), reinterpret_cast<char*>(map.mData), bufLen);
+      memset(dragImageData.get() + bufLen, 0, maxBufLen - bufLen + 1);
+      nsDependentCString dragImage(dragImageData.get(), maxBufLen);
+
       mozilla::unused <<
         child->SendInvokeDragSession(dataTransfers, aActionType, dragImage,
                                      size.width, size.height, map.mStride,
                                      static_cast<uint8_t>(format),
                                      dragRect.x, dragRect.y);
       dataSurface->Unmap();
       StartDragSession();
       return NS_OK;