From 53c0f726fe4f3f757ebe86dc2e109d9634e6d5f0 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 24 Feb 2016 20:04:37 +0100 Subject: [PATCH] Bug 1250572 - Force a parent object in MessagePort/Channel and in StructuredCloneHolder, r=smaug --- dom/base/StructuredCloneHolder.cpp | 5 +++- dom/messagechannel/MessageChannel.cpp | 24 ++++++++++-------- dom/messagechannel/MessageChannel.h | 12 ++++----- dom/messagechannel/MessagePort.cpp | 36 +++++++++++---------------- dom/messagechannel/MessagePort.h | 9 ++++--- dom/workers/RuntimeService.cpp | 5 ++-- dom/workers/WorkerPrivate.cpp | 8 +++--- dom/workers/XMLHttpRequest.cpp | 20 +++++++++++++-- 8 files changed, 67 insertions(+), 52 deletions(-) diff --git a/dom/base/StructuredCloneHolder.cpp b/dom/base/StructuredCloneHolder.cpp index 3540a00adc97..f0da5380931b 100644 --- a/dom/base/StructuredCloneHolder.cpp +++ b/dom/base/StructuredCloneHolder.cpp @@ -295,6 +295,7 @@ StructuredCloneHolder::Read(nsISupports* aParent, { MOZ_ASSERT_IF(mSupportedContext == SameProcessSameThread, mCreationThread == NS_GetCurrentThread()); + MOZ_ASSERT(aParent); mozilla::AutoRestore guard(mParent); mParent = aParent; @@ -1044,9 +1045,11 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx, MOZ_ASSERT(aExtraData < mPortIdentifiers.Length()); const MessagePortIdentifier& portIdentifier = mPortIdentifiers[aExtraData]; + nsCOMPtr global = do_QueryInterface(mParent); + ErrorResult rv; RefPtr port = - MessagePort::Create(mParent, portIdentifier, rv); + MessagePort::Create(global, portIdentifier, rv); if (NS_WARN_IF(rv.Failed())) { return false; } diff --git a/dom/messagechannel/MessageChannel.cpp b/dom/messagechannel/MessageChannel.cpp index edb86107f24c..a0604ae4a47c 100644 --- a/dom/messagechannel/MessageChannel.cpp +++ b/dom/messagechannel/MessageChannel.cpp @@ -13,14 +13,14 @@ #include "mozilla/dom/WorkerRunnable.h" #include "nsContentUtils.h" #include "nsIDocument.h" +#include "nsIGlobalObject.h" #include "nsIPrincipal.h" -#include "nsPIDOMWindow.h" #include "nsServiceManagerUtils.h" namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MessageChannel, mWindow, mPort1, mPort2) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MessageChannel, mGlobal, mPort1, mPort2) NS_IMPL_CYCLE_COLLECTING_ADDREF(MessageChannel) NS_IMPL_CYCLE_COLLECTING_RELEASE(MessageChannel) @@ -29,9 +29,10 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageChannel) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END -MessageChannel::MessageChannel(nsPIDOMWindowInner* aWindow) - : mWindow(aWindow) +MessageChannel::MessageChannel(nsIGlobalObject* aGlobal) + : mGlobal(aGlobal) { + MOZ_ASSERT(aGlobal); } MessageChannel::~MessageChannel() @@ -47,14 +48,15 @@ MessageChannel::WrapObject(JSContext* aCx, JS::Handle aGivenProto) /* static */ already_AddRefed MessageChannel::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { - // window can be null in workers. - nsCOMPtr window = do_QueryInterface(aGlobal.GetAsSupports()); - return Constructor(window, aRv); + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + return Constructor(global, aRv); } /* static */ already_AddRefed -MessageChannel::Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv) +MessageChannel::Constructor(nsIGlobalObject* aGlobal, ErrorResult& aRv) { + MOZ_ASSERT(aGlobal); + nsID portUUID1; aRv = nsContentUtils::GenerateUUIDInPlace(portUUID1); if (aRv.Failed()) { @@ -67,14 +69,14 @@ MessageChannel::Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv) return nullptr; } - RefPtr channel = new MessageChannel(aWindow); + RefPtr channel = new MessageChannel(aGlobal); - channel->mPort1 = MessagePort::Create(aWindow, portUUID1, portUUID2, aRv); + channel->mPort1 = MessagePort::Create(aGlobal, portUUID1, portUUID2, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } - channel->mPort2 = MessagePort::Create(aWindow, portUUID2, portUUID1, aRv); + channel->mPort2 = MessagePort::Create(aGlobal, portUUID2, portUUID1, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } diff --git a/dom/messagechannel/MessageChannel.h b/dom/messagechannel/MessageChannel.h index 506e00b277ab..a9c9521810b1 100644 --- a/dom/messagechannel/MessageChannel.h +++ b/dom/messagechannel/MessageChannel.h @@ -14,7 +14,7 @@ #include "nsWrapperCache.h" #include "nsCOMPtr.h" -class nsPIDOMWindowInner; +class nsIGlobalObject; namespace mozilla { namespace dom { @@ -28,10 +28,10 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MessageChannel) - nsPIDOMWindowInner* + nsIGlobalObject* GetParentObject() const { - return mWindow; + return mGlobal; } virtual JSObject* @@ -41,7 +41,7 @@ public: Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); static already_AddRefed - Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv); + Constructor(nsIGlobalObject* aGlobal, ErrorResult& aRv); MessagePort* Port1() const @@ -56,10 +56,10 @@ public: } private: - explicit MessageChannel(nsPIDOMWindowInner* aWindow); + explicit MessageChannel(nsIGlobalObject* aGlobal); ~MessageChannel(); - nsCOMPtr mWindow; + nsCOMPtr mGlobal; RefPtr mPort1; RefPtr mPort2; diff --git a/dom/messagechannel/MessagePort.cpp b/dom/messagechannel/MessagePort.cpp index b2a716e6b5fd..bcd27c749768 100644 --- a/dom/messagechannel/MessagePort.cpp +++ b/dom/messagechannel/MessagePort.cpp @@ -86,15 +86,8 @@ private: nsresult DispatchMessage() const { - nsCOMPtr globalObject; - - if (NS_IsMainThread()) { - globalObject = do_QueryInterface(mPort->GetParentObject()); - } else { - WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); - MOZ_ASSERT(workerPrivate); - globalObject = workerPrivate->GlobalScope(); - } + nsCOMPtr globalObject = mPort->GetParentObject(); + MOZ_ASSERT(globalObject); AutoJSAPI jsapi; if (!globalObject || !jsapi.Init(globalObject)) { @@ -259,20 +252,17 @@ NS_IMPL_ISUPPORTS(ForceCloseHelper, nsIIPCBackgroundChildCreateCallback) } // namespace -MessagePort::MessagePort(nsISupports* aSupports) - : mInnerID(0) +MessagePort::MessagePort(nsIGlobalObject* aGlobal) + : DOMEventTargetHelper(aGlobal) + , mInnerID(0) , mMessageQueueEnabled(false) , mIsKeptAlive(false) { + MOZ_ASSERT(aGlobal); + mIdentifier = new MessagePortIdentifier(); mIdentifier->neutered() = true; mIdentifier->sequenceId() = 0; - - nsCOMPtr globalObject = do_QueryInterface(aSupports); - if (NS_WARN_IF(!globalObject)) { - return; - } - BindToOwner(globalObject); } MessagePort::~MessagePort() @@ -282,21 +272,25 @@ MessagePort::~MessagePort() } /* static */ already_AddRefed -MessagePort::Create(nsISupports* aSupport, const nsID& aUUID, +MessagePort::Create(nsIGlobalObject* aGlobal, const nsID& aUUID, const nsID& aDestinationUUID, ErrorResult& aRv) { - RefPtr mp = new MessagePort(aSupport); + MOZ_ASSERT(aGlobal); + + RefPtr mp = new MessagePort(aGlobal); mp->Initialize(aUUID, aDestinationUUID, 1 /* 0 is an invalid sequence ID */, false /* Neutered */, eStateUnshippedEntangled, aRv); return mp.forget(); } /* static */ already_AddRefed -MessagePort::Create(nsISupports* aSupport, +MessagePort::Create(nsIGlobalObject* aGlobal, const MessagePortIdentifier& aIdentifier, ErrorResult& aRv) { - RefPtr mp = new MessagePort(aSupport); + MOZ_ASSERT(aGlobal); + + RefPtr mp = new MessagePort(aGlobal); mp->Initialize(aIdentifier.uuid(), aIdentifier.destinationUuid(), aIdentifier.sequenceId(), aIdentifier.neutered(), eStateEntangling, aRv); diff --git a/dom/messagechannel/MessagePort.h b/dom/messagechannel/MessagePort.h index 81c7e06cf6ea..6d26cd1fc62a 100644 --- a/dom/messagechannel/MessagePort.h +++ b/dom/messagechannel/MessagePort.h @@ -16,7 +16,7 @@ #undef PostMessage #endif -class nsPIDOMWindowInner; +class nsIGlobalObject; namespace mozilla { namespace dom { @@ -45,11 +45,12 @@ public: DOMEventTargetHelper) static already_AddRefed - Create(nsISupports* aSupport, const nsID& aUUID, + Create(nsIGlobalObject* aGlobal, const nsID& aUUID, const nsID& aDestinationUUID, ErrorResult& aRv); static already_AddRefed - Create(nsISupports* aSupport, const MessagePortIdentifier& aIdentifier, + Create(nsIGlobalObject* aGlobal, + const MessagePortIdentifier& aIdentifier, ErrorResult& aRv); // For IPC. @@ -88,7 +89,7 @@ public: void Closed(); private: - explicit MessagePort(nsISupports* nsISupports); + explicit MessagePort(nsIGlobalObject* aGlobal); ~MessagePort(); enum State { diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 0b62638e38da..6dd090d27a2b 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -2386,13 +2386,14 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx, // We don't actually care about this MessageChannel, but we use it to 'steal' // its 2 connected ports. - RefPtr channel = MessageChannel::Constructor(window, rv); + nsCOMPtr global = do_QueryInterface(window); + RefPtr channel = MessageChannel::Constructor(global, rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } RefPtr sharedWorker = new SharedWorker(window, workerPrivate, - channel->Port1()); + channel->Port1()); if (!workerPrivate->RegisterSharedWorker(aCx, sharedWorker, channel->Port2())) { diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 9f9a860ef917..3564c5d24fbd 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -672,10 +672,8 @@ public: DispatchDOMEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate, DOMEventTargetHelper* aTarget, bool aIsMainThread) { - nsCOMPtr parent; - if (aIsMainThread) { - parent = do_QueryInterface(aTarget->GetParentObject()); - } + nsCOMPtr parent = do_QueryInterface(aTarget->GetParentObject()); + MOZ_ASSERT(parent); JS::Rooted messageData(aCx); ErrorResult rv; @@ -6384,7 +6382,7 @@ WorkerPrivate::ConnectMessagePort(JSContext* aCx, // This MessagePortIdentifier is used to create a new port, still connected // with the other one, but in the worker thread. ErrorResult rv; - RefPtr port = MessagePort::Create(nullptr, aIdentifier, rv); + RefPtr port = MessagePort::Create(globalScope, aIdentifier, rv); if (NS_WARN_IF(rv.Failed())) { return false; } diff --git a/dom/workers/XMLHttpRequest.cpp b/dom/workers/XMLHttpRequest.cpp index 7b70712bbe99..89eb37047fad 100644 --- a/dom/workers/XMLHttpRequest.cpp +++ b/dom/workers/XMLHttpRequest.cpp @@ -26,6 +26,7 @@ #include "nsVariant.h" #include "RuntimeService.h" +#include "WorkerScope.h" #include "WorkerPrivate.h" #include "WorkerRunnable.h" #include "XMLHttpRequestUpload.h" @@ -1336,7 +1337,12 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) ErrorResult rv; JS::Rooted response(aCx); - Read(nullptr, aCx, &response, rv); + + GlobalObject globalObj(aCx, aWorkerPrivate->GlobalScope()->GetWrapper()); + nsCOMPtr global = + do_QueryInterface(globalObj.GetAsSupports()); + + Read(global, aCx, &response, rv); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); return false; @@ -1513,8 +1519,18 @@ SendRunnable::MainThreadRun() ErrorResult rv; + JS::Rooted globalObject(cx, JS::CurrentGlobalOrNull(cx)); + if (NS_WARN_IF(!globalObject)) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr parent = xpc::NativeGlobal(globalObject); + if (NS_WARN_IF(!parent)) { + return NS_ERROR_FAILURE; + } + JS::Rooted body(cx); - Read(nullptr, cx, &body, rv); + Read(parent, cx, &body, rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); }