From b13b3b72d290d9199e6a009f6be25ec815f8644e Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 6 Feb 2020 13:46:25 +0000 Subject: [PATCH] Bug 1611855 - Worklet must be part of the same parent's agentCluster - part 2 - CloneDataPolicy in writing, r=smaug Differential Revision: https://phabricator.services.mozilla.com/D61182 --HG-- extra : moz-landing-system : lando --- docshell/base/BrowsingContext.cpp | 2 +- dom/base/PostMessageEvent.h | 4 +-- dom/base/StructuredCloneHolder.cpp | 32 +++++++++---------- dom/base/StructuredCloneHolder.h | 22 +++++++------ dom/base/nsFrameMessageManager.cpp | 2 +- dom/clients/api/Client.cpp | 2 +- dom/ipc/SharedMessageBody.cpp | 6 +++- dom/ipc/StructuredCloneData.cpp | 8 ++--- dom/ipc/StructuredCloneData.h | 15 ++++++--- dom/serviceworkers/ServiceWorker.cpp | 2 +- js/public/StructuredClone.h | 8 ++--- js/rust/src/sc.rs | 2 +- js/src/vm/StructuredClone.cpp | 17 +++++----- .../messagemanager/MessageManagerFuzzer.cpp | 3 +- 14 files changed, 70 insertions(+), 55 deletions(-) diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index 22fa9f8bf960..891c156f0ecc 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -1146,7 +1146,7 @@ void BrowsingContext::PostMessageMoz(JSContext* aCx, } ipc::StructuredCloneData message; - message.Write(aCx, aMessage, transferArray, aError); + message.Write(aCx, aMessage, transferArray, JS::CloneDataPolicy(), aError); if (NS_WARN_IF(aError.Failed())) { return; } diff --git a/dom/base/PostMessageEvent.h b/dom/base/PostMessageEvent.h index a2ded5c11296..eae9f61df421 100644 --- a/dom/base/PostMessageEvent.h +++ b/dom/base/PostMessageEvent.h @@ -55,8 +55,8 @@ class PostMessageEvent final : public Runnable { aScriptLocation, aIsFromPrivateWindow, Nothing()) {} void Write(JSContext* aCx, JS::Handle aMessage, - JS::Handle aTransfer, JS::CloneDataPolicy aClonePolicy, - ErrorResult& aError) { + JS::Handle aTransfer, + const JS::CloneDataPolicy& aClonePolicy, ErrorResult& aError) { mHolder.construct( StructuredCloneHolder::CloningSupported, StructuredCloneHolder::TransferringSupported, diff --git a/dom/base/StructuredCloneHolder.cpp b/dom/base/StructuredCloneHolder.cpp index 8da6fab51e49..cb0989f2b459 100644 --- a/dom/base/StructuredCloneHolder.cpp +++ b/dom/base/StructuredCloneHolder.cpp @@ -177,10 +177,10 @@ bool StructuredCloneHolderBase::Write(JSContext* aCx, return Write(aCx, aValue, JS::UndefinedHandleValue, JS::CloneDataPolicy()); } -bool StructuredCloneHolderBase::Write(JSContext* aCx, - JS::Handle aValue, - JS::Handle aTransfer, - JS::CloneDataPolicy aCloneDataPolicy) { +bool StructuredCloneHolderBase::Write( + JSContext* aCx, JS::Handle aValue, + JS::Handle aTransfer, + const JS::CloneDataPolicy& aCloneDataPolicy) { MOZ_ASSERT(!mBuffer, "Double Write is not allowed"); MOZ_ASSERT(!mClearCalled, "This method cannot be called after Clear."); @@ -201,9 +201,9 @@ bool StructuredCloneHolderBase::Read(JSContext* aCx, return Read(aCx, aValue, JS::CloneDataPolicy()); } -bool StructuredCloneHolderBase::Read(JSContext* aCx, - JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy) { +bool StructuredCloneHolderBase::Read( + JSContext* aCx, JS::MutableHandle aValue, + const JS::CloneDataPolicy& aCloneDataPolicy) { MOZ_ASSERT(mBuffer, "Read() without Write() is not allowed."); MOZ_ASSERT(!mClearCalled, "This method cannot be called after Clear."); @@ -268,10 +268,10 @@ void StructuredCloneHolder::Write(JSContext* aCx, JS::Handle aValue, void StructuredCloneHolder::Write(JSContext* aCx, JS::Handle aValue, JS::Handle aTransfer, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv) { if (!StructuredCloneHolderBase::Write(aCx, aValue, aTransfer, - cloneDataPolicy)) { + aCloneDataPolicy)) { aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); return; } @@ -285,7 +285,7 @@ void StructuredCloneHolder::Read(nsIGlobalObject* aGlobal, JSContext* aCx, void StructuredCloneHolder::Read(nsIGlobalObject* aGlobal, JSContext* aCx, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv) { MOZ_ASSERT(aGlobal); @@ -308,12 +308,10 @@ void StructuredCloneHolder::Read(nsIGlobalObject* aGlobal, JSContext* aCx, } } -void StructuredCloneHolder::ReadFromBuffer(nsIGlobalObject* aGlobal, - JSContext* aCx, - JSStructuredCloneData& aBuffer, - JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, - ErrorResult& aRv) { +void StructuredCloneHolder::ReadFromBuffer( + nsIGlobalObject* aGlobal, JSContext* aCx, JSStructuredCloneData& aBuffer, + JS::MutableHandle aValue, + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv) { ReadFromBuffer(aGlobal, aCx, aBuffer, JS_STRUCTURED_CLONE_VERSION, aValue, aCloneDataPolicy, aRv); } @@ -321,7 +319,7 @@ void StructuredCloneHolder::ReadFromBuffer(nsIGlobalObject* aGlobal, void StructuredCloneHolder::ReadFromBuffer( nsIGlobalObject* aGlobal, JSContext* aCx, JSStructuredCloneData& aBuffer, uint32_t aAlgorithmVersion, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, ErrorResult& aRv) { + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv) { MOZ_ASSERT(!mBuffer, "ReadFromBuffer() must be called without a Write()."); mozilla::AutoRestore guard(mGlobal); diff --git a/dom/base/StructuredCloneHolder.h b/dom/base/StructuredCloneHolder.h index af32b455ff11..ea5ee6b5230b 100644 --- a/dom/base/StructuredCloneHolder.h +++ b/dom/base/StructuredCloneHolder.h @@ -102,7 +102,7 @@ class StructuredCloneHolderBase { // of cloning policy. bool Write(JSContext* aCx, JS::Handle aValue, JS::Handle aTransfer, - JS::CloneDataPolicy aCloneDataPolicy); + const JS::CloneDataPolicy& aCloneDataPolicy); // If Write() has been called, this method retrieves data and stores it into // aValue. @@ -110,7 +110,7 @@ class StructuredCloneHolderBase { // Like Read() but it supports handling of clone policy. bool Read(JSContext* aCx, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy); + const JS::CloneDataPolicy& aCloneDataPolicy); bool HasData() const { return !!mBuffer; } @@ -164,18 +164,20 @@ class StructuredCloneHolder : public StructuredCloneHolderBase { // Normally you should just use Write() and Read(). - void Write(JSContext* aCx, JS::Handle aValue, ErrorResult& aRv); + virtual void Write(JSContext* aCx, JS::Handle aValue, + ErrorResult& aRv); - void Write(JSContext* aCx, JS::Handle aValue, - JS::Handle aTransfer, - JS::CloneDataPolicy aCloneDataPolicy, ErrorResult& aRv); + virtual void Write(JSContext* aCx, JS::Handle aValue, + JS::Handle aTransfer, + const JS::CloneDataPolicy& aCloneDataPolicy, + ErrorResult& aRv); void Read(nsIGlobalObject* aGlobal, JSContext* aCx, JS::MutableHandle aValue, ErrorResult& aRv); void Read(nsIGlobalObject* aGlobal, JSContext* aCx, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, ErrorResult& aRv); + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv); // Call this method to know if this object is keeping some DOM object alive. bool HasClonedDOMObjects() const { @@ -295,13 +297,15 @@ class StructuredCloneHolder : public StructuredCloneHolderBase { void ReadFromBuffer(nsIGlobalObject* aGlobal, JSContext* aCx, JSStructuredCloneData& aBuffer, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, ErrorResult& aRv); + const JS::CloneDataPolicy& aCloneDataPolicy, + ErrorResult& aRv); void ReadFromBuffer(nsIGlobalObject* aGlobal, JSContext* aCx, JSStructuredCloneData& aBuffer, uint32_t aAlgorithmVersion, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, ErrorResult& aRv); + const JS::CloneDataPolicy& aCloneDataPolicy, + ErrorResult& aRv); void SameProcessScopeRequired(bool* aSameProcessScopeRequired); diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index ea3cebc2c0db..8fa22fb328e8 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -387,7 +387,7 @@ bool nsFrameMessageManager::GetParamsForMessage(JSContext* aCx, JS::RootedValue v(aCx, aValue); JS::RootedValue t(aCx, aTransfer); ErrorResult rv; - aData.Write(aCx, v, t, rv); + aData.Write(aCx, v, t, JS::CloneDataPolicy(), rv); if (!rv.Failed()) { return true; } diff --git a/dom/clients/api/Client.cpp b/dom/clients/api/Client.cpp index 5086ba2d970e..da808633d68e 100644 --- a/dom/clients/api/Client.cpp +++ b/dom/clients/api/Client.cpp @@ -104,7 +104,7 @@ void Client::PostMessage(JSContext* aCx, JS::Handle aMessage, } StructuredCloneData data; - data.Write(aCx, aMessage, transferable, aRv); + data.Write(aCx, aMessage, transferable, JS::CloneDataPolicy(), aRv); if (aRv.Failed()) { return; } diff --git a/dom/ipc/SharedMessageBody.cpp b/dom/ipc/SharedMessageBody.cpp index 6b3cb11d42a4..3df78a2bc436 100644 --- a/dom/ipc/SharedMessageBody.cpp +++ b/dom/ipc/SharedMessageBody.cpp @@ -32,9 +32,13 @@ void SharedMessageBody::Write(JSContext* aCx, JS::Handle aValue, MOZ_ASSERT(!mCloneData && !mRefData); MOZ_ASSERT(aRefMessageBodyService); + JS::CloneDataPolicy cloneDataPolicy; + // TODO: this is going to change in the next patches. + cloneDataPolicy.allowIntraClusterClonableSharedObjects(); + mCloneData = MakeUnique( JS::StructuredCloneScope::UnknownDestination, mSupportsTransferring); - mCloneData->Write(aCx, aValue, aTransfers, aRv); + mCloneData->Write(aCx, aValue, aTransfers, cloneDataPolicy, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } diff --git a/dom/ipc/StructuredCloneData.cpp b/dom/ipc/StructuredCloneData.cpp index f5f860eb3fb8..a44903bec4e0 100644 --- a/dom/ipc/StructuredCloneData.cpp +++ b/dom/ipc/StructuredCloneData.cpp @@ -107,7 +107,7 @@ void StructuredCloneData::Read(JSContext* aCx, void StructuredCloneData::Read(JSContext* aCx, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv) { MOZ_ASSERT(mInitialized); @@ -119,16 +119,16 @@ void StructuredCloneData::Read(JSContext* aCx, void StructuredCloneData::Write(JSContext* aCx, JS::Handle aValue, ErrorResult& aRv) { - Write(aCx, aValue, JS::UndefinedHandleValue, aRv); + Write(aCx, aValue, JS::UndefinedHandleValue, JS::CloneDataPolicy(), aRv); } void StructuredCloneData::Write(JSContext* aCx, JS::Handle aValue, JS::Handle aTransfer, + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv) { MOZ_ASSERT(!mInitialized); - StructuredCloneHolder::Write(aCx, aValue, aTransfer, JS::CloneDataPolicy(), - aRv); + StructuredCloneHolder::Write(aCx, aValue, aTransfer, aCloneDataPolicy, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } diff --git a/dom/ipc/StructuredCloneData.h b/dom/ipc/StructuredCloneData.h index 8db7ed44688a..9d5384c754d1 100644 --- a/dom/ipc/StructuredCloneData.h +++ b/dom/ipc/StructuredCloneData.h @@ -177,12 +177,19 @@ class StructuredCloneData : public StructuredCloneHolder { ErrorResult& aRv); void Read(JSContext* aCx, JS::MutableHandle aValue, - JS::CloneDataPolicy aCloneDataPolicy, ErrorResult& aRv); - - void Write(JSContext* aCx, JS::Handle aValue, ErrorResult& aRv); + const JS::CloneDataPolicy& aCloneDataPolicy, ErrorResult& aRv); + // Write with no transfer objects and with the default CloneDataPolicy. With + // a default CloneDataPolicy, read and write will not be considered as part of + // the same agent cluster and shared memory objects will not be supported. void Write(JSContext* aCx, JS::Handle aValue, - JS::Handle aTransfers, ErrorResult& aRv); + ErrorResult& aRv) override; + + // The most generic Write method, with tansfers and CloneDataPolicy. + void Write(JSContext* aCx, JS::Handle aValue, + JS::Handle aTransfers, + const JS::CloneDataPolicy& aCloneDataPolicy, + ErrorResult& aRv) override; // Actor-varying methods to convert the structured clone stored in this holder // by a previous call to Write() into ClonedMessageData IPC representation. diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp index 26780d7d88da..cba10dce8198 100644 --- a/dom/serviceworkers/ServiceWorker.cpp +++ b/dom/serviceworkers/ServiceWorker.cpp @@ -205,7 +205,7 @@ void ServiceWorker::PostMessage(JSContext* aCx, JS::Handle aMessage, } RefPtr data = new ServiceWorkerCloneData(); - data->Write(aCx, aMessage, transferable, aRv); + data->Write(aCx, aMessage, transferable, JS::CloneDataPolicy(), aRv); if (aRv.Failed()) { return; } diff --git a/js/public/StructuredClone.h b/js/public/StructuredClone.h index 0fe61f5403b8..df262d3e2c23 100644 --- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -562,7 +562,7 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API JSStructuredCloneData { JS_PUBLIC_API bool JS_ReadStructuredClone( JSContext* cx, JSStructuredCloneData& data, uint32_t version, JS::StructuredCloneScope scope, JS::MutableHandleValue vp, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* optionalCallbacks, void* closure); /** @@ -575,7 +575,7 @@ JS_PUBLIC_API bool JS_ReadStructuredClone( */ JS_PUBLIC_API bool JS_WriteStructuredClone( JSContext* cx, JS::HandleValue v, JSStructuredCloneData* data, - JS::StructuredCloneScope scope, JS::CloneDataPolicy cloneDataPolicy, + JS::StructuredCloneScope scope, const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* optionalCallbacks, void* closure, JS::HandleValue transferable); @@ -651,7 +651,7 @@ class JS_PUBLIC_API JSAutoStructuredCloneBuffer { } bool read(JSContext* cx, JS::MutableHandleValue vp, - JS::CloneDataPolicy cloneDataPolicy = JS::CloneDataPolicy(), + const JS::CloneDataPolicy& cloneDataPolicy = JS::CloneDataPolicy(), const JSStructuredCloneCallbacks* optionalCallbacks = nullptr, void* closure = nullptr); @@ -660,7 +660,7 @@ class JS_PUBLIC_API JSAutoStructuredCloneBuffer { void* closure = nullptr); bool write(JSContext* cx, JS::HandleValue v, JS::HandleValue transferable, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* optionalCallbacks = nullptr, void* closure = nullptr); diff --git a/js/rust/src/sc.rs b/js/rust/src/sc.rs index 61958c8ce24b..52f2d38f903d 100644 --- a/js/rust/src/sc.rs +++ b/js/rust/src/sc.rs @@ -57,7 +57,7 @@ impl StructuredCloneBuffer { callbacks: &jsapi::JSStructuredCloneCallbacks) -> Result<(), ()> { if unsafe { - (*self.raw).read(Runtime::get(), vp, jsapi::JS::CloneDataPolicy{ allowIntraClusterClonableSharedObjects_: false }, callbacks, ptr::null_mut()) + (*self.raw).read(Runtime::get(), vp, &jsapi::JS::CloneDataPolicy{ allowIntraClusterClonableSharedObjects_: false }, callbacks, ptr::null_mut()) } { Ok(()) } else { diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 1a5c7e2e9415..39a34c7e695a 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -388,7 +388,7 @@ class SCInput { struct JSStructuredCloneReader { public: explicit JSStructuredCloneReader(SCInput& in, JS::StructuredCloneScope scope, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* cb, void* cbClosure) : in(in), @@ -466,7 +466,7 @@ struct JSStructuredCloneWriter { public: explicit JSStructuredCloneWriter(JSContext* cx, JS::StructuredCloneScope scope, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* cb, void* cbClosure, const Value& tVal) : out(cx, scope), @@ -626,7 +626,7 @@ static void ReportDataCloneError(JSContext* cx, bool WriteStructuredClone(JSContext* cx, HandleValue v, JSStructuredCloneData* bufp, JS::StructuredCloneScope scope, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* cb, void* cbClosure, const Value& transferable) { JSStructuredCloneWriter w(cx, scope, cloneDataPolicy, cb, cbClosure, @@ -643,7 +643,7 @@ bool WriteStructuredClone(JSContext* cx, HandleValue v, bool ReadStructuredClone(JSContext* cx, JSStructuredCloneData& data, JS::StructuredCloneScope scope, MutableHandleValue vp, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* cb, void* cbClosure) { SCInput in(cx, data); @@ -3057,7 +3057,7 @@ using namespace js; JS_PUBLIC_API bool JS_ReadStructuredClone( JSContext* cx, JSStructuredCloneData& buf, uint32_t version, JS::StructuredCloneScope scope, MutableHandleValue vp, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* optionalCallbacks, void* closure) { AssertHeapIsIdle(); CHECK_THREAD(cx); @@ -3074,7 +3074,7 @@ JS_PUBLIC_API bool JS_ReadStructuredClone( JS_PUBLIC_API bool JS_WriteStructuredClone( JSContext* cx, HandleValue value, JSStructuredCloneData* bufp, - JS::StructuredCloneScope scope, JS::CloneDataPolicy cloneDataPolicy, + JS::StructuredCloneScope scope, const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* optionalCallbacks, void* closure, HandleValue transferable) { AssertHeapIsIdle(); @@ -3190,7 +3190,8 @@ void JSAutoStructuredCloneBuffer::steal( } bool JSAutoStructuredCloneBuffer::read( - JSContext* cx, MutableHandleValue vp, JS::CloneDataPolicy cloneDataPolicy, + JSContext* cx, MutableHandleValue vp, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* optionalCallbacks, void* closure) { MOZ_ASSERT(cx); return !!JS_ReadStructuredClone(cx, data_, version_, data_.scope(), vp, @@ -3207,7 +3208,7 @@ bool JSAutoStructuredCloneBuffer::write( bool JSAutoStructuredCloneBuffer::write( JSContext* cx, HandleValue value, HandleValue transferable, - JS::CloneDataPolicy cloneDataPolicy, + const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* optionalCallbacks, void* closure) { clear(); bool ok = diff --git a/tools/fuzzing/messagemanager/MessageManagerFuzzer.cpp b/tools/fuzzing/messagemanager/MessageManagerFuzzer.cpp index c297c19771b4..bc9ac6b6fb05 100644 --- a/tools/fuzzing/messagemanager/MessageManagerFuzzer.cpp +++ b/tools/fuzzing/messagemanager/MessageManagerFuzzer.cpp @@ -235,7 +235,8 @@ bool MessageManagerFuzzer::Mutate(JSContext* aCx, const nsAString& aMessageName, /* Write mutated StructuredCloneData. */ ipc::StructuredCloneData mutatedStructuredCloneData; - mutatedStructuredCloneData.Write(aCx, scdMutationContent, t, rv); + mutatedStructuredCloneData.Write(aCx, scdMutationContent, t, + JS::CloneDataPolicy(), rv); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); JS_ClearPendingException(aCx);