mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1176034 - MessagePort should force a close() if the structured clone algorithm fails, r=bent
This commit is contained in:
parent
b0a98f661f
commit
0502aa5138
@ -238,7 +238,13 @@ PostMessageEvent::FreeTransferStructuredClone(uint32_t aTag,
|
|||||||
uint64_t aExtraData,
|
uint64_t aExtraData,
|
||||||
void* aClosure)
|
void* aClosure)
|
||||||
{
|
{
|
||||||
// Nothing to do.
|
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||||
|
MOZ_ASSERT(aClosure);
|
||||||
|
MOZ_ASSERT(!aContent);
|
||||||
|
|
||||||
|
StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(aClosure);
|
||||||
|
MessagePort::ForceClose(scInfo->event->GetPortIdentifier(aExtraData));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PostMessageEvent::PostMessageEvent(nsGlobalWindow* aSource,
|
PostMessageEvent::PostMessageEvent(nsGlobalWindow* aSource,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "mozilla/dom/WorkerScope.h"
|
#include "mozilla/dom/WorkerScope.h"
|
||||||
#include "mozilla/ipc/BackgroundChild.h"
|
#include "mozilla/ipc/BackgroundChild.h"
|
||||||
#include "mozilla/ipc/PBackgroundChild.h"
|
#include "mozilla/ipc/PBackgroundChild.h"
|
||||||
|
#include "mozilla/unused.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
@ -249,6 +250,50 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ForceCloseHelper final : public nsIIPCBackgroundChildCreateCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
static void ForceClose(const MessagePortIdentifier& aIdentifier)
|
||||||
|
{
|
||||||
|
PBackgroundChild* actor =
|
||||||
|
mozilla::ipc::BackgroundChild::GetForCurrentThread();
|
||||||
|
if (actor) {
|
||||||
|
unused << actor->SendMessagePortForceClose(aIdentifier.uuid(),
|
||||||
|
aIdentifier.destinationUuid(),
|
||||||
|
aIdentifier.sequenceId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<ForceCloseHelper> helper = new ForceCloseHelper(aIdentifier);
|
||||||
|
if (NS_WARN_IF(!mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread(helper))) {
|
||||||
|
MOZ_CRASH();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit ForceCloseHelper(const MessagePortIdentifier& aIdentifier)
|
||||||
|
: mIdentifier(aIdentifier)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~ForceCloseHelper() {}
|
||||||
|
|
||||||
|
void ActorFailed() override
|
||||||
|
{
|
||||||
|
MOZ_CRASH("Failed to create a PBackgroundChild actor!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorCreated(mozilla::ipc::PBackgroundChild* aActor)
|
||||||
|
{
|
||||||
|
ForceClose(mIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MessagePortIdentifier mIdentifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(ForceCloseHelper, nsIIPCBackgroundChildCreateCallback)
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
MessagePort::MessagePort(nsPIDOMWindow* aWindow)
|
MessagePort::MessagePort(nsPIDOMWindow* aWindow)
|
||||||
@ -863,5 +908,11 @@ MessagePort::RemoveDocFromBFCache()
|
|||||||
bfCacheEntry->RemoveFromBFCacheSync();
|
bfCacheEntry->RemoveFromBFCacheSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
MessagePort::ForceClose(const MessagePortIdentifier& aIdentifier)
|
||||||
|
{
|
||||||
|
ForceCloseHelper::ForceClose(aIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -86,6 +86,9 @@ public:
|
|||||||
Create(nsPIDOMWindow* aWindow, const MessagePortIdentifier& aIdentifier,
|
Create(nsPIDOMWindow* aWindow, const MessagePortIdentifier& aIdentifier,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
static void
|
||||||
|
ForceClose(const MessagePortIdentifier& aIdentifier);
|
||||||
|
|
||||||
virtual JSObject*
|
virtual JSObject*
|
||||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
@ -159,5 +159,19 @@ MessagePortParent::Close()
|
|||||||
mEntangled = false;
|
mEntangled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ bool
|
||||||
|
MessagePortParent::ForceClose(const nsID& aUUID,
|
||||||
|
const nsID& aDestinationUUID,
|
||||||
|
const uint32_t& aSequenceID)
|
||||||
|
{
|
||||||
|
MessagePortService* service = MessagePortService::Get();
|
||||||
|
if (!service) {
|
||||||
|
NS_WARNING("The service must exist if we want to close an existing MessagePort.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return service->ForceClose(aUUID, aDestinationUUID, aSequenceID);
|
||||||
|
}
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
} // mozilla namespace
|
} // mozilla namespace
|
||||||
|
@ -36,6 +36,10 @@ public:
|
|||||||
return mUUID;
|
return mUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ForceClose(const nsID& aUUID,
|
||||||
|
const nsID& aDestinationUUID,
|
||||||
|
const uint32_t& aSequenceID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool RecvPostMessages(nsTArray<MessagePortMessage>&& aMessages)
|
virtual bool RecvPostMessages(nsTArray<MessagePortMessage>&& aMessages)
|
||||||
override;
|
override;
|
||||||
|
@ -6,16 +6,27 @@
|
|||||||
#include "MessagePortService.h"
|
#include "MessagePortService.h"
|
||||||
#include "MessagePortParent.h"
|
#include "MessagePortParent.h"
|
||||||
#include "SharedMessagePortMessage.h"
|
#include "SharedMessagePortMessage.h"
|
||||||
|
#include "mozilla/ipc/BackgroundParent.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
using mozilla::ipc::AssertIsOnBackgroundThread;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
StaticRefPtr<MessagePortService> gInstance;
|
StaticRefPtr<MessagePortService> gInstance;
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsInMainProcess()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
class MessagePortService::MessagePortServiceData final
|
class MessagePortService::MessagePortServiceData final
|
||||||
@ -53,9 +64,21 @@ public:
|
|||||||
FallibleTArray<nsRefPtr<SharedMessagePortMessage>> mMessages;
|
FallibleTArray<nsRefPtr<SharedMessagePortMessage>> mMessages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* static */ MessagePortService*
|
||||||
|
MessagePortService::Get()
|
||||||
|
{
|
||||||
|
AssertIsInMainProcess();
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
return gInstance;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ MessagePortService*
|
/* static */ MessagePortService*
|
||||||
MessagePortService::GetOrCreate()
|
MessagePortService::GetOrCreate()
|
||||||
{
|
{
|
||||||
|
AssertIsInMainProcess();
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
if (!gInstance) {
|
if (!gInstance) {
|
||||||
gInstance = new MessagePortService();
|
gInstance = new MessagePortService();
|
||||||
}
|
}
|
||||||
@ -248,6 +271,12 @@ MessagePortService::CloseAll(const nsID& aUUID)
|
|||||||
|
|
||||||
CloseAll(destinationUUID);
|
CloseAll(destinationUUID);
|
||||||
|
|
||||||
|
// CloseAll calls itself recursively and it can happen that it deletes
|
||||||
|
// itself. Before continuing we must check if we are still alive.
|
||||||
|
if (!gInstance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
mPorts.EnumerateRead(CloseAllDebugCheck, const_cast<nsID*>(&aUUID));
|
mPorts.EnumerateRead(CloseAllDebugCheck, const_cast<nsID*>(&aUUID));
|
||||||
#endif
|
#endif
|
||||||
@ -324,5 +353,26 @@ MessagePortService::ParentDestroy(MessagePortParent* aParent)
|
|||||||
CloseAll(aParent->ID());
|
CloseAll(aParent->ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MessagePortService::ForceClose(const nsID& aUUID,
|
||||||
|
const nsID& aDestinationUUID,
|
||||||
|
const uint32_t& aSequenceID)
|
||||||
|
{
|
||||||
|
MessagePortServiceData* data;
|
||||||
|
if (!mPorts.Get(aUUID, &data)) {
|
||||||
|
NS_WARNING("Unknown MessagePort in ForceClose()");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data->mDestinationUUID.Equals(aDestinationUUID) ||
|
||||||
|
data->mSequenceID != aSequenceID) {
|
||||||
|
NS_WARNING("DestinationUUID and/or sequenceID do not match.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseAll(aUUID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
} // mozilla namespace
|
} // mozilla namespace
|
||||||
|
@ -20,6 +20,7 @@ class MessagePortService final
|
|||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(MessagePortService)
|
NS_INLINE_DECL_REFCOUNTING(MessagePortService)
|
||||||
|
|
||||||
|
static MessagePortService* Get();
|
||||||
static MessagePortService* GetOrCreate();
|
static MessagePortService* GetOrCreate();
|
||||||
|
|
||||||
bool RequestEntangling(MessagePortParent* aParent,
|
bool RequestEntangling(MessagePortParent* aParent,
|
||||||
@ -38,6 +39,10 @@ public:
|
|||||||
|
|
||||||
void ParentDestroy(MessagePortParent* aParent);
|
void ParentDestroy(MessagePortParent* aParent);
|
||||||
|
|
||||||
|
bool ForceClose(const nsID& aUUID,
|
||||||
|
const nsID& aDestinationUUID,
|
||||||
|
const uint32_t& aSequenceID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~MessagePortService() {}
|
~MessagePortService() {}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ ReadTransfer(JSContext* aCx, JSStructuredCloneReader* aReader,
|
|||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
nsRefPtr<MessagePort> port =
|
nsRefPtr<MessagePort> port =
|
||||||
MessagePort::Create(closure->mWindow,
|
MessagePort::Create(closure->mWindow,
|
||||||
closure->mClosure.mMessagePortIdentifiers[(uint32_t)aExtraData],
|
closure->mClosure.mMessagePortIdentifiers[aExtraData],
|
||||||
rv);
|
rv);
|
||||||
if (NS_WARN_IF(rv.Failed())) {
|
if (NS_WARN_IF(rv.Failed())) {
|
||||||
return false;
|
return false;
|
||||||
@ -195,13 +195,27 @@ WriteTransfer(JSContext* aCx, JS::Handle<JSObject*> aObj, void* aClosure,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FreeTransfer(uint32_t aTag, JS::TransferableOwnership aOwnership,
|
||||||
|
void* aContent, uint64_t aExtraData, void* aClosure)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aClosure);
|
||||||
|
auto* closure = static_cast<StructuredCloneClosureInternal*>(aClosure);
|
||||||
|
|
||||||
|
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||||
|
MOZ_ASSERT(!aContent);
|
||||||
|
MOZ_ASSERT(aExtraData < closure->mClosure.mMessagePortIdentifiers.Length());
|
||||||
|
MessagePort::ForceClose(closure->mClosure.mMessagePortIdentifiers[(uint32_t)aExtraData]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const JSStructuredCloneCallbacks gCallbacks = {
|
const JSStructuredCloneCallbacks gCallbacks = {
|
||||||
Read,
|
Read,
|
||||||
Write,
|
Write,
|
||||||
Error,
|
Error,
|
||||||
ReadTransfer,
|
ReadTransfer,
|
||||||
WriteTransfer,
|
WriteTransfer,
|
||||||
nullptr
|
FreeTransfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -23,3 +23,4 @@ support-files =
|
|||||||
[test_messageChannel_sharedWorker.html]
|
[test_messageChannel_sharedWorker.html]
|
||||||
[test_messageChannel_sharedWorker2.html]
|
[test_messageChannel_sharedWorker2.html]
|
||||||
[test_messageChannel_any.html]
|
[test_messageChannel_any.html]
|
||||||
|
[test_messageChannel_forceClose.html]
|
||||||
|
36
dom/messagechannel/tests/test_messageChannel_forceClose.html
Normal file
36
dom/messagechannel/tests/test_messageChannel_forceClose.html
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=1176034
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for Bug 1176034 - start/close</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1176034">Mozilla Bug 1176034</a>
|
||||||
|
<div id="content"></div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
var mc = new MessageChannel();
|
||||||
|
|
||||||
|
try {
|
||||||
|
postMessage(42, "*", [ mc.port1, window ]);
|
||||||
|
ok(false, "Something went wrong.");
|
||||||
|
} catch(e) {
|
||||||
|
ok(true, "PostMessage should fail and we should not leak.");
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTests);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -763,7 +763,14 @@ struct WorkerStructuredCloneCallbacks
|
|||||||
FreeTransfer(uint32_t aTag, JS::TransferableOwnership aOwnership,
|
FreeTransfer(uint32_t aTag, JS::TransferableOwnership aOwnership,
|
||||||
void *aContent, uint64_t aExtraData, void* aClosure)
|
void *aContent, uint64_t aExtraData, void* aClosure)
|
||||||
{
|
{
|
||||||
// Nothing to do.
|
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||||
|
MOZ_ASSERT(aClosure);
|
||||||
|
MOZ_ASSERT(!aContent);
|
||||||
|
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||||
|
|
||||||
|
MOZ_ASSERT(aExtraData < closure->mMessagePortIdentifiers.Length());
|
||||||
|
dom::MessagePort::ForceClose(closure->mMessagePortIdentifiers[aExtraData]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -588,6 +588,17 @@ BackgroundParentImpl::DeallocPMessagePortParent(PMessagePortParent* aActor)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BackgroundParentImpl::RecvMessagePortForceClose(const nsID& aUUID,
|
||||||
|
const nsID& aDestinationUUID,
|
||||||
|
const uint32_t& aSequenceID)
|
||||||
|
{
|
||||||
|
AssertIsInMainProcess();
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
return MessagePortParent::ForceClose(aUUID, aDestinationUUID, aSequenceID);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
@ -137,6 +137,11 @@ protected:
|
|||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
DeallocPMessagePortParent(PMessagePortParent* aActor) override;
|
DeallocPMessagePortParent(PMessagePortParent* aActor) override;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvMessagePortForceClose(const nsID& aUUID,
|
||||||
|
const nsID& aDestinationUUID,
|
||||||
|
const uint32_t& aSequenceID) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
@ -60,6 +60,8 @@ parent:
|
|||||||
|
|
||||||
PMessagePort(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
|
PMessagePort(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
|
||||||
|
|
||||||
|
MessagePortForceClose(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
|
||||||
|
|
||||||
child:
|
child:
|
||||||
PCache();
|
PCache();
|
||||||
PCacheStreamControl();
|
PCacheStreamControl();
|
||||||
|
Loading…
Reference in New Issue
Block a user