From 81a3ef4473665794875d278abb47262040ed0d95 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 14 Jan 2015 11:52:21 +0000 Subject: [PATCH] Bug 966439 - BroadcastChannel API - patch 9 - Fix a memory leak of Files, r=bent --- dom/broadcastchannel/BroadcastChannel.cpp | 16 +++++++++-- dom/broadcastchannel/BroadcastChannel.h | 9 ++++-- .../BroadcastChannelChild.cpp | 28 +++++++++++-------- .../BroadcastChannelService.cpp | 4 +++ .../BroadcastChannelService.h | 4 +++ 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index 70bee21c61a..52ca1d774df 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -21,6 +21,10 @@ #include "nsServiceManagerUtils.h" #include "nsISupportsPrimitives.h" +#ifdef XP_WIN +#undef PostMessage +#endif + namespace mozilla { using namespace ipc; @@ -416,7 +420,7 @@ BroadcastChannel::BroadcastChannel(nsPIDOMWindow* aWindow, const nsAString& aChannel) : DOMEventTargetHelper(aWindow) , mWorkerFeature(nullptr) - , mPrincipalInfo(aPrincipalInfo) + , mPrincipalInfo(new PrincipalInfo(aPrincipalInfo)) , mOrigin(aOrigin) , mChannel(aChannel) , mIsKeptAlive(false) @@ -558,6 +562,14 @@ BroadcastChannel::PostMessageInternal(JSContext* aCx, return; } + const nsTArray>& blobs = data->mClosure.mBlobs; + for (uint32_t i = 0, len = blobs.Length(); i < len; ++i) { + if (!blobs[i]->Impl()->MayBeClonedToOtherThreads()) { + aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); + return; + } + } + PostMessageData(data); } @@ -618,7 +630,7 @@ BroadcastChannel::ActorCreated(PBackgroundChild* aActor) } PBroadcastChannelChild* actor = - aActor->SendPBroadcastChannelConstructor(mPrincipalInfo, mOrigin, mChannel); + aActor->SendPBroadcastChannelConstructor(*mPrincipalInfo, mOrigin, mChannel); mActor = static_cast(actor); MOZ_ASSERT(mActor); diff --git a/dom/broadcastchannel/BroadcastChannel.h b/dom/broadcastchannel/BroadcastChannel.h index 4ca72036c71..5c44c53ddfc 100644 --- a/dom/broadcastchannel/BroadcastChannel.h +++ b/dom/broadcastchannel/BroadcastChannel.h @@ -8,7 +8,6 @@ #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" -#include "mozilla/ipc/PBackgroundSharedTypes.h" #include "nsIIPCBackgroundChildCreateCallback.h" #include "nsIObserver.h" #include "nsTArray.h" @@ -17,6 +16,11 @@ class nsPIDOMWindow; namespace mozilla { + +namespace ipc { +class PrincipalInfo; +} + namespace dom { namespace workers { @@ -104,7 +108,8 @@ private: workers::WorkerFeature* mWorkerFeature; - PrincipalInfo mPrincipalInfo; + nsAutoPtr mPrincipalInfo; + nsString mOrigin; nsString mChannel; diff --git a/dom/broadcastchannel/BroadcastChannelChild.cpp b/dom/broadcastchannel/BroadcastChannelChild.cpp index ea54c5869a5..3bd8cf3ba7a 100644 --- a/dom/broadcastchannel/BroadcastChannelChild.cpp +++ b/dom/broadcastchannel/BroadcastChannelChild.cpp @@ -41,6 +41,21 @@ BroadcastChannelChild::~BroadcastChannelChild() bool BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData) { + // Make sure to retrieve all blobs from the message before returning to avoid + // leaking their actors. + nsTArray> files; + if (!aData.blobsChild().IsEmpty()) { + files.SetCapacity(aData.blobsChild().Length()); + + for (uint32_t i = 0, len = aData.blobsChild().Length(); i < len; ++i) { + nsRefPtr impl = + static_cast(aData.blobsChild()[i])->GetBlobImpl(); + + nsRefPtr file = new File(mBC ? mBC->GetOwner() : nullptr, impl); + files.AppendElement(file); + } + } + nsCOMPtr helper = mBC; nsCOMPtr eventTarget = do_QueryInterface(helper); @@ -78,18 +93,7 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData) StructuredCloneData cloneData; cloneData.mData = buffer.data; cloneData.mDataLength = buffer.dataLength; - - if (!aData.blobsChild().IsEmpty()) { - cloneData.mClosure.mBlobs.SetCapacity(aData.blobsChild().Length()); - - for (uint32_t i = 0, len = aData.blobsChild().Length(); i < len; ++i) { - nsRefPtr impl = - static_cast(aData.blobsChild()[i])->GetBlobImpl(); - - nsRefPtr blob = new File(mBC->GetOwner(), impl); - cloneData.mClosure.mBlobs.AppendElement(blob); - } - } + cloneData.mClosure.mBlobs.SwapElements(files); JS::Rooted value(cx, JS::NullValue()); if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) { diff --git a/dom/broadcastchannel/BroadcastChannelService.cpp b/dom/broadcastchannel/BroadcastChannelService.cpp index d63c6cbfc7d..41a8b22d296 100644 --- a/dom/broadcastchannel/BroadcastChannelService.cpp +++ b/dom/broadcastchannel/BroadcastChannelService.cpp @@ -7,6 +7,10 @@ #include "BroadcastChannelParent.h" #include "mozilla/ipc/BackgroundParent.h" +#ifdef XP_WIN +#undef PostMessage +#endif + namespace mozilla { using namespace ipc; diff --git a/dom/broadcastchannel/BroadcastChannelService.h b/dom/broadcastchannel/BroadcastChannelService.h index 01f60079a3e..871b0b44bc2 100644 --- a/dom/broadcastchannel/BroadcastChannelService.h +++ b/dom/broadcastchannel/BroadcastChannelService.h @@ -9,6 +9,10 @@ #include "nsHashKeys.h" #include "nsTHashtable.h" +#ifdef XP_WIN +#undef PostMessage +#endif + namespace mozilla { namespace dom {