From 31852ebd7e49f2de202d9730169efd64a916effd Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Wed, 29 Apr 2015 20:39:59 -0700 Subject: [PATCH] Bug 803783 - Send message manager results via structured clone (r=bent) --- dom/base/nsFrameMessageManager.cpp | 52 +++++++++++++++---------- dom/base/nsFrameMessageManager.h | 13 +++++-- dom/base/nsInProcessTabChildGlobal.cpp | 4 +- dom/base/nsInProcessTabChildGlobal.h | 4 +- dom/ipc/ContentBridgeParent.cpp | 2 +- dom/ipc/ContentBridgeParent.h | 3 +- dom/ipc/ContentParent.cpp | 4 +- dom/ipc/ContentParent.h | 5 ++- dom/ipc/PBrowser.ipdl | 5 ++- dom/ipc/PContent.ipdl | 5 ++- dom/ipc/PContentBridge.ipdl | 3 +- dom/ipc/TabChild.cpp | 6 +-- dom/ipc/TabChild.h | 3 +- dom/ipc/TabParent.cpp | 12 +++--- dom/ipc/TabParent.h | 7 ++-- dom/ipc/nsIContentParent.cpp | 4 +- dom/ipc/nsIContentParent.h | 6 ++- ipc/glue/IPCMessageUtils.h | 54 ++++++++++++++++++++++++++ 18 files changed, 137 insertions(+), 55 deletions(-) diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index b441bec95c0..36910703324 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -688,7 +688,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName, objects = &aObjects.toObject(); } - InfallibleTArray retval; + nsTArray retval; sSendingSyncMessage |= aIsSync; bool rv = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects, @@ -706,15 +706,13 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName, NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY); for (uint32_t i = 0; i < len; ++i) { - if (retval[i].IsEmpty()) { - continue; - } - JS::Rooted ret(aCx); - if (!JS_ParseJSON(aCx, static_cast(retval[i].get()), - retval[i].Length(), &ret)) { + if (!JS_ReadStructuredClone(aCx, retval[i].data, retval[i].dataLength, + JS_STRUCTURED_CLONE_VERSION, &ret, nullptr, nullptr)) { + MOZ_ASSERT(false, "Unable to read structured clone in SendMessage"); return NS_ERROR_UNEXPECTED; } + NS_ENSURE_TRUE(JS_DefineElement(aCx, dataArray, i, ret, JSPROP_ENUMERATE), NS_ERROR_OUT_OF_MEMORY); } @@ -1002,10 +1000,10 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget, const StructuredCloneData* aCloneData, mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal) + nsTArray* aRetVal) { return ReceiveMessage(aTarget, aTargetFrameLoader, mClosed, aMessage, aIsSync, - aCloneData, aCpows, aPrincipal, aJSONRetVal); + aCloneData, aCpows, aPrincipal, aRetVal); } nsresult @@ -1017,7 +1015,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget, const StructuredCloneData* aCloneData, mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal) + nsTArray* aRetVal) { nsAutoTObserverArray* listeners = mListeners.Get(aMessage); @@ -1191,13 +1189,25 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget, JS::HandleValueArray(argv), &rval)) { continue; } - if (aJSONRetVal) { - nsString json; - if (!JS_Stringify(cx, &rval, JS::NullPtr(), JS::NullHandleValue, - JSONCreator, &json)) { + if (aRetVal) { + JSAutoStructuredCloneBuffer buffer; + if (!buffer.write(cx, rval)) { + nsString msg = aMessage + NS_LITERAL_STRING(": message reply cannot be cloned. Are you trying to send an XPCOM object?"); + + nsCOMPtr console(do_GetService(NS_CONSOLESERVICE_CONTRACTID)); + if (console) { + nsCOMPtr error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); + error->Init(msg, EmptyString(), EmptyString(), + 0, 0, nsIScriptError::warningFlag, "chrome javascript"); + console->LogMessage(error); + } + + JS_ClearPendingException(cx); continue; } - aJSONRetVal->AppendElement(json); + + OwningSerializedStructuredCloneBuffer* data = aRetVal->AppendElement(); + buffer.steal(&data->data, &data->dataLength); } } } @@ -1207,7 +1217,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget, aTargetClosed, aMessage, aIsSync, aCloneData, aCpows, aPrincipal, - aJSONRetVal) : NS_OK; + aRetVal) : NS_OK; } void @@ -1872,7 +1882,7 @@ public: const mozilla::dom::StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal, + nsTArray* aRetVal, bool aIsSync) override { mozilla::dom::ContentChild* cc = @@ -1890,10 +1900,10 @@ public: } if (aIsSync) { return cc->SendSyncMessage(PromiseFlatString(aMessage), data, cpows, - IPC::Principal(aPrincipal), aJSONRetVal); + IPC::Principal(aPrincipal), aRetVal); } return cc->SendRpcMessage(PromiseFlatString(aMessage), data, cpows, - IPC::Principal(aPrincipal), aJSONRetVal); + IPC::Principal(aPrincipal), aRetVal); } virtual bool DoSendAsyncMessage(JSContext* aCx, @@ -1963,7 +1973,7 @@ public: const mozilla::dom::StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal, + nsTArray* aRetVal, bool aIsSync) override { SameProcessMessageQueue* queue = SameProcessMessageQueue::Get(); @@ -1973,7 +1983,7 @@ public: SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows); nsRefPtr ppm = nsFrameMessageManager::sSameProcessParentManager; ppm->ReceiveMessage(static_cast(ppm.get()), nullptr, aMessage, - true, &aData, &cpows, aPrincipal, aJSONRetVal); + true, &aData, &cpows, aPrincipal, aRetVal); } return true; } diff --git a/dom/base/nsFrameMessageManager.h b/dom/base/nsFrameMessageManager.h index e58b63dbfad..c0aef1a36ca 100644 --- a/dom/base/nsFrameMessageManager.h +++ b/dom/base/nsFrameMessageManager.h @@ -34,6 +34,9 @@ class nsIFrameLoader; namespace mozilla { + +struct OwningSerializedStructuredCloneBuffer; + namespace dom { class nsIContentParent; @@ -54,6 +57,9 @@ enum MessageManagerFlags { class MessageManagerCallback { +protected: + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; + public: virtual ~MessageManagerCallback() {} @@ -67,7 +73,7 @@ public: const StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal, + nsTArray* aRetVal, bool aIsSync) { return true; @@ -161,6 +167,7 @@ class nsFrameMessageManager final : public nsIContentFrameMessageManager, { friend class mozilla::dom::MessageManagerReporter; typedef mozilla::dom::StructuredCloneData StructuredCloneData; + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; public: nsFrameMessageManager(mozilla::dom::ipc::MessageManagerCallback* aCallback, nsFrameMessageManager* aParentManager, @@ -233,7 +240,7 @@ public: const nsAString& aMessage, bool aIsSync, const StructuredCloneData* aCloneData, mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal); + nsTArray* aRetVal); void AddChildManager(nsFrameMessageManager* aManager); void RemoveChildManager(nsFrameMessageManager* aManager) @@ -298,7 +305,7 @@ private: bool aTargetClosed, const nsAString& aMessage, bool aIsSync, const StructuredCloneData* aCloneData, mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal); + nsTArray* aRetVal); NS_IMETHOD LoadScript(const nsAString& aURL, bool aAllowDelayedLoad, diff --git a/dom/base/nsInProcessTabChildGlobal.cpp b/dom/base/nsInProcessTabChildGlobal.cpp index c48a5a6f16e..53d9f7c2199 100644 --- a/dom/base/nsInProcessTabChildGlobal.cpp +++ b/dom/base/nsInProcessTabChildGlobal.cpp @@ -33,7 +33,7 @@ nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx, const dom::StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal, + nsTArray* aRetVal, bool aIsSync) { SameProcessMessageQueue* queue = SameProcessMessageQueue::Get(); @@ -44,7 +44,7 @@ nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx, nsRefPtr mm = mChromeMessageManager; nsCOMPtr fl = GetFrameLoader(); mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, &cpows, aPrincipal, - aJSONRetVal); + aRetVal); } return true; } diff --git a/dom/base/nsInProcessTabChildGlobal.h b/dom/base/nsInProcessTabChildGlobal.h index 8360cee29e0..e8c2d83d338 100644 --- a/dom/base/nsInProcessTabChildGlobal.h +++ b/dom/base/nsInProcessTabChildGlobal.h @@ -35,6 +35,8 @@ class nsInProcessTabChildGlobal : public mozilla::DOMEventTargetHelper, public nsSupportsWeakReference, public mozilla::dom::ipc::MessageManagerCallback { + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; + public: nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner, nsFrameMessageManager* aChrome); @@ -84,7 +86,7 @@ public: const mozilla::dom::StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal, + nsTArray* aRetVal, bool aIsSync) override; virtual bool DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage, diff --git a/dom/ipc/ContentBridgeParent.cpp b/dom/ipc/ContentBridgeParent.cpp index 0301796b543..c21a8e4c065 100644 --- a/dom/ipc/ContentBridgeParent.cpp +++ b/dom/ipc/ContentBridgeParent.cpp @@ -76,7 +76,7 @@ ContentBridgeParent::RecvSyncMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) + nsTArray* aRetvals) { return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows), aPrincipal, aRetvals); diff --git a/dom/ipc/ContentBridgeParent.h b/dom/ipc/ContentBridgeParent.h index fac5dfdec54..8c0944213a6 100644 --- a/dom/ipc/ContentBridgeParent.h +++ b/dom/ipc/ContentBridgeParent.h @@ -19,6 +19,7 @@ class ContentBridgeParent : public PContentBridgeParent , public nsIContentParent , public nsIObserver { + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; public: explicit ContentBridgeParent(Transport* aTransport); @@ -80,7 +81,7 @@ protected: const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) override; + nsTArray* aRetvals) override; virtual bool RecvAsyncMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index cdede4a14e2..d0791e43b04 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -4173,7 +4173,7 @@ ContentParent::RecvSyncMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) + nsTArray* aRetvals) { return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows), aPrincipal, aRetvals); @@ -4184,7 +4184,7 @@ ContentParent::RecvRpcMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) + nsTArray* aRetvals) { return nsIContentParent::RecvRpcMessage(aMsg, aData, Move(aCpows), aPrincipal, aRetvals); diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index f46d0b34ead..a79fc5158fe 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -77,6 +77,7 @@ class ContentParent final : public PContentParent typedef mozilla::ipc::TestShellParent TestShellParent; typedef mozilla::ipc::URIParams URIParams; typedef mozilla::dom::ClonedMessageData ClonedMessageData; + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; public: #ifdef MOZ_NUWA_PROCESS @@ -714,12 +715,12 @@ private: const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) override; + nsTArray* aRetvals) override; virtual bool RecvRpcMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) override; + nsTArray* aRetvals) override; virtual bool RecvAsyncMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 703d00c5138..8bef1b72bbf 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -59,6 +59,7 @@ using mozilla::WritingMode from "mozilla/WritingModes.h"; using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h"; using nsIWidget::TouchPointerState from "nsIWidget.h"; using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h"; +using struct mozilla::OwningSerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h"; namespace mozilla { namespace dom { @@ -147,11 +148,11 @@ parent: sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) - returns (nsString[] retval); + returns (OwningSerializedStructuredCloneBuffer[] retval); prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) - returns (nsString[] retval); + returns (OwningSerializedStructuredCloneBuffer[] retval); /** * The IME sequence number (seqno) parameter is used to make sure diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 88fd413e251..73ed17d2044 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -90,6 +90,7 @@ using gfxIntSize from "nsSize.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h"; using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h"; +using struct mozilla::OwningSerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h"; union ChromeRegistryItem { @@ -795,11 +796,11 @@ parent: sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) - returns (nsString[] retval); + returns (OwningSerializedStructuredCloneBuffer[] retval); prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) - returns (nsString[] retval); + returns (OwningSerializedStructuredCloneBuffer[] retval); ShowAlertNotification(nsString imageUrl, nsString title, diff --git a/dom/ipc/PContentBridge.ipdl b/dom/ipc/PContentBridge.ipdl index a98e083ae1f..0003a6f095a 100644 --- a/dom/ipc/PContentBridge.ipdl +++ b/dom/ipc/PContentBridge.ipdl @@ -16,6 +16,7 @@ include PTabContext; using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h"; +using struct mozilla::OwningSerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h"; namespace mozilla { namespace dom { @@ -39,7 +40,7 @@ prio(normal upto urgent) sync protocol PContentBridge parent: sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) - returns (nsString[] retval); + returns (OwningSerializedStructuredCloneBuffer[] retval); both: // Both the parent and the child can construct the PBrowser. // See the comment in PContent::PBrowser(). diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 6df91a12c5c..234bb8aa1c6 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -3060,7 +3060,7 @@ TabChild::DoSendBlockingMessage(JSContext* aCx, const StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal, + nsTArray* aRetVal, bool aIsSync) { ClonedMessageData data; @@ -3073,11 +3073,11 @@ TabChild::DoSendBlockingMessage(JSContext* aCx, } if (aIsSync) { return SendSyncMessage(PromiseFlatString(aMessage), data, cpows, - Principal(aPrincipal), aJSONRetVal); + Principal(aPrincipal), aRetVal); } return SendRpcMessage(PromiseFlatString(aMessage), data, cpows, - Principal(aPrincipal), aJSONRetVal); + Principal(aPrincipal), aRetVal); } bool diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 2ca3af02619..eda6fbb9ab4 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -243,6 +243,7 @@ class TabChild final : public TabChildBase, public nsITooltipListener { typedef mozilla::dom::ClonedMessageData ClonedMessageData; + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; typedef mozilla::layout::RenderFrameChild RenderFrameChild; typedef mozilla::layers::APZEventState APZEventState; typedef mozilla::layers::SetTargetAPZCCallback SetTargetAPZCCallback; @@ -297,7 +298,7 @@ public: const mozilla::dom::StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal, + nsTArray* aRetVal, bool aIsSync) override; virtual bool DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index f7c72ef3ea9..4ef8c9315fc 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1639,7 +1639,7 @@ TabParent::RecvSyncMessage(const nsString& aMessage, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aJSONRetVal) + nsTArray* aRetVal) { // FIXME Permission check for TabParent in Content process nsIPrincipal* principal = aPrincipal; @@ -1653,7 +1653,7 @@ TabParent::RecvSyncMessage(const nsString& aMessage, StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData); CrossProcessCpowHolder cpows(Manager(), aCpows); - return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal); + return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aRetVal); } bool @@ -1661,7 +1661,7 @@ TabParent::RecvRpcMessage(const nsString& aMessage, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aJSONRetVal) + nsTArray* aRetVal) { // FIXME Permission check for TabParent in Content process nsIPrincipal* principal = aPrincipal; @@ -1675,7 +1675,7 @@ TabParent::RecvRpcMessage(const nsString& aMessage, StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData); CrossProcessCpowHolder cpows(Manager(), aCpows); - return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal); + return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aRetVal); } bool @@ -2521,7 +2521,7 @@ TabParent::ReceiveMessage(const nsString& aMessage, const StructuredCloneData* aCloneData, CpowHolder* aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal) + nsTArray* aRetVal) { nsRefPtr frameLoader = GetFrameLoader(true); if (frameLoader && frameLoader->GetFrameMessageManager()) { @@ -2535,7 +2535,7 @@ TabParent::ReceiveMessage(const nsString& aMessage, aCloneData, aCpows, aPrincipal, - aJSONRetVal); + aRetVal); } return true; } diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 585825a0c63..d608c1eb1b5 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -78,6 +78,7 @@ class TabParent final : public PBrowserParent , public nsAPostRefreshObserver { typedef mozilla::dom::ClonedMessageData ClonedMessageData; + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; virtual ~TabParent(); @@ -149,12 +150,12 @@ public: const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aJSONRetVal) override; + nsTArray* aRetVal) override; virtual bool RecvRpcMessage(const nsString& aMessage, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aJSONRetVal) override; + nsTArray* aRetVal) override; virtual bool RecvAsyncMessage(const nsString& aMessage, const ClonedMessageData& aData, InfallibleTArray&& aCpows, @@ -424,7 +425,7 @@ protected: const StructuredCloneData* aCloneData, mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal, - InfallibleTArray* aJSONRetVal = nullptr); + nsTArray* aJSONRetVal = nullptr); virtual bool RecvAsyncAuthPrompt(const nsCString& aUri, const nsString& aRealm, diff --git a/dom/ipc/nsIContentParent.cpp b/dom/ipc/nsIContentParent.cpp index bbb61364227..f9d6c62182b 100644 --- a/dom/ipc/nsIContentParent.cpp +++ b/dom/ipc/nsIContentParent.cpp @@ -178,7 +178,7 @@ nsIContentParent::RecvSyncMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) + nsTArray* aRetvals) { // FIXME Permission check in Content process nsIPrincipal* principal = aPrincipal; @@ -205,7 +205,7 @@ nsIContentParent::RecvRpcMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals) + nsTArray* aRetvals) { // FIXME Permission check in Content process nsIPrincipal* principal = aPrincipal; diff --git a/dom/ipc/nsIContentParent.h b/dom/ipc/nsIContentParent.h index c4cd120dae5..1232e59b809 100644 --- a/dom/ipc/nsIContentParent.h +++ b/dom/ipc/nsIContentParent.h @@ -45,6 +45,8 @@ class nsIContentParent : public nsISupports , public mozilla::dom::ipc::MessageManagerCallback , public CPOWManagerGetter { + typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer; + public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTPARENT_IID) @@ -97,12 +99,12 @@ protected: // IPDL methods const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals); + nsTArray* aRetvals); virtual bool RecvRpcMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, const IPC::Principal& aPrincipal, - InfallibleTArray* aRetvals); + nsTArray* aRetvals); virtual bool RecvAsyncMessage(const nsString& aMsg, const ClonedMessageData& aData, InfallibleTArray&& aCpows, diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index 2ab91a142bb..4d66060f32c 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -87,6 +87,35 @@ struct SerializedStructuredCloneBuffer size_t dataLength; }; +struct OwningSerializedStructuredCloneBuffer : public SerializedStructuredCloneBuffer +{ + OwningSerializedStructuredCloneBuffer() + {} + + OwningSerializedStructuredCloneBuffer(const OwningSerializedStructuredCloneBuffer&) = delete; + + explicit OwningSerializedStructuredCloneBuffer(const JSAutoStructuredCloneBuffer& aOther) + : SerializedStructuredCloneBuffer(aOther) + {} + + ~OwningSerializedStructuredCloneBuffer() + { + if (data) { + js_free(data); + } + } + + OwningSerializedStructuredCloneBuffer& + operator=(const JSAutoStructuredCloneBuffer& aOther) + { + SerializedStructuredCloneBuffer::operator=(aOther); + return *this; + } + + OwningSerializedStructuredCloneBuffer& + operator=(const OwningSerializedStructuredCloneBuffer& aOther) = delete; +}; + } // namespace mozilla namespace IPC { @@ -744,6 +773,31 @@ struct ParamTraits } }; +template <> +struct ParamTraits + : public ParamTraits +{ + typedef mozilla::OwningSerializedStructuredCloneBuffer paramType; + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (!ParamTraits::Read(aMsg, aIter, aResult)) { + return false; + } + + if (aResult->data) { + uint64_t* data = static_cast(js_malloc(aResult->dataLength)); + if (!data) { + return false; + } + memcpy(data, aResult->data, aResult->dataLength); + aResult->data = data; + } + + return true; + } +}; + template <> struct ParamTraits : public BitFlagsEnumSerializer