From 6ef9eed5984a3a454d82896a867fb0fb90cf717b Mon Sep 17 00:00:00 2001 From: Edgar Chen Date: Mon, 15 May 2023 19:12:19 +0000 Subject: [PATCH] Bug 1832701 - Part 2: Add IPCTransferable for clipboard write parameters; r=nika Move IPCTransferable* into a separated file to avoid circular dependency and use `hg cp` in order to keep the history. Differential Revision: https://phabricator.services.mozilla.com/D178070 --- dom/base/nsContentUtils.cpp | 46 ++++++++++++++ dom/base/nsContentUtils.h | 11 ++++ dom/ipc/ContentParent.cpp | 24 ++------ dom/ipc/ContentParent.h | 8 +-- dom/ipc/DOMTypes.ipdlh | 56 ----------------- dom/ipc/IPCTransferable.ipdlh | 85 ++++++++++++++++++++++++++ dom/ipc/PBrowser.ipdl | 2 + dom/ipc/PContent.ipdl | 8 +-- dom/ipc/moz.build | 1 + widget/ClipboardWriteRequestChild.cpp | 18 ++---- widget/ClipboardWriteRequestParent.cpp | 22 ++----- widget/ClipboardWriteRequestParent.h | 7 +-- widget/PClipboardWriteRequest.ipdl | 8 +-- widget/nsClipboardProxy.cpp | 25 ++------ 14 files changed, 171 insertions(+), 150 deletions(-) create mode 100644 dom/ipc/IPCTransferable.ipdlh diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 5c4c53c71e60d..ad22e037191f9 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7944,6 +7944,28 @@ nsresult nsContentUtils::IPCTransferableDataToTransferable( return NS_OK; } +nsresult nsContentUtils::IPCTransferableToTransferable( + const IPCTransferable& aIPCTransferable, bool aAddDataFlavor, + nsITransferable* aTransferable, const bool aFilterUnknownFlavors) { + nsresult rv = + IPCTransferableDataToTransferable(aIPCTransferable.data(), aAddDataFlavor, + aTransferable, aFilterUnknownFlavors); + NS_ENSURE_SUCCESS(rv, rv); + + aTransferable->SetIsPrivateData(aIPCTransferable.isPrivateData()); + aTransferable->SetRequestingPrincipal(aIPCTransferable.requestingPrincipal()); + if (aIPCTransferable.cookieJarSettings().isSome()) { + nsCOMPtr cookieJarSettings; + net::CookieJarSettings::Deserialize( + aIPCTransferable.cookieJarSettings().ref(), + getter_AddRefs(cookieJarSettings)); + aTransferable->SetCookieJarSettings(cookieJarSettings); + } + aTransferable->SetContentPolicyType(aIPCTransferable.contentPolicyType()); + aTransferable->SetReferrerInfo(aIPCTransferable.referrerInfo()); + return NS_OK; +} + nsresult nsContentUtils::IPCTransferableDataItemToVariant( const IPCTransferableDataItem& aItem, nsIWritableVariant* aVariant) { MOZ_ASSERT(aVariant); @@ -8279,6 +8301,30 @@ void nsContentUtils::TransferableToIPCTransferableData( } } +void nsContentUtils::TransferableToIPCTransferable( + nsITransferable* aTransferable, IPCTransferable* aIPCTransferable, + bool aInSyncMessage, mozilla::dom::ContentParent* aParent) { + IPCTransferableData ipcTransferableData; + TransferableToIPCTransferableData(aTransferable, &ipcTransferableData, + aInSyncMessage, aParent); + + Maybe cookieJarSettingsArgs; + if (nsCOMPtr cookieJarSettings = + aTransferable->GetCookieJarSettings()) { + net::CookieJarSettingsArgs args; + net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(args); + cookieJarSettingsArgs = Some(std::move(args)); + } + + aIPCTransferable->data() = std::move(ipcTransferableData); + aIPCTransferable->isPrivateData() = aTransferable->GetIsPrivateData(); + aIPCTransferable->requestingPrincipal() = + aTransferable->GetRequestingPrincipal(); + aIPCTransferable->cookieJarSettings() = std::move(cookieJarSettingsArgs); + aIPCTransferable->contentPolicyType() = aTransferable->GetContentPolicyType(); + aIPCTransferable->referrerInfo() = aTransferable->GetReferrerInfo(); +} + Maybe nsContentUtils::GetSurfaceData(DataSourceSurface& aSurface, size_t* aLength, int32_t* aStride) { diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 6a8d0b0393083..ccd0e86055a98 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -182,6 +182,7 @@ class Element; class Event; class EventTarget; class HTMLInputElement; +class IPCTransferable; class IPCTransferableData; class IPCTransferableDataImageContainer; class IPCTransferableDataItem; @@ -2872,6 +2873,11 @@ class nsContentUtils { const nsContentPolicyType& aContentPolicyType, bool aAddDataFlavor, nsITransferable* aTransferable, const bool aFilterUnknownFlavors); + static nsresult IPCTransferableToTransferable( + const mozilla::dom::IPCTransferable& aIPCTransferable, + bool aAddDataFlavor, nsITransferable* aTransferable, + const bool aFilterUnknownFlavors); + static nsresult IPCTransferableDataItemToVariant( const mozilla::dom::IPCTransferableDataItem& aItem, nsIWritableVariant* aVariant); @@ -2886,6 +2892,11 @@ class nsContentUtils { mozilla::dom::IPCTransferableData* aTransferableData, bool aInSyncMessage, mozilla::dom::ContentParent* aParent); + static void TransferableToIPCTransferable( + nsITransferable* aTransferable, + mozilla::dom::IPCTransferable* aIPCTransferable, bool aInSyncMessage, + mozilla::dom::ContentParent* aParent); + /* * Get the pixel data from the given source surface and return it as a * BigBuffer. The length and stride will be assigned from the surface. diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 8ee3e51eba634..367dfa4f3119c 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -3467,16 +3467,13 @@ void ContentParent::OnVarChanged(const GfxVarUpdate& aVar) { } mozilla::ipc::IPCResult ContentParent::RecvSetClipboard( - const IPCTransferableData& aTransferableData, const bool& aIsPrivateData, - nsIPrincipal* aRequestingPrincipal, - mozilla::Maybe aCookieJarSettingsArgs, - const nsContentPolicyType& aContentPolicyType, - nsIReferrerInfo* aReferrerInfo, const int32_t& aWhichClipboard) { + const IPCTransferable& aTransferable, const int32_t& aWhichClipboard) { // aRequestingPrincipal is allowed to be nullptr here. - if (!ValidatePrincipal(aRequestingPrincipal, + if (!ValidatePrincipal(aTransferable.requestingPrincipal(), {ValidatePrincipalOptions::AllowNullPtr})) { - LogAndAssertFailedPrincipalValidationInfo(aRequestingPrincipal, __func__); + LogAndAssertFailedPrincipalValidationInfo( + aTransferable.requestingPrincipal(), __func__); } nsresult rv; @@ -3487,18 +3484,9 @@ mozilla::ipc::IPCResult ContentParent::RecvSetClipboard( do_CreateInstance("@mozilla.org/widget/transferable;1", &rv); NS_ENSURE_SUCCESS(rv, IPC_OK()); trans->Init(nullptr); - trans->SetReferrerInfo(aReferrerInfo); - if (aCookieJarSettingsArgs.isSome()) { - nsCOMPtr cookieJarSettings; - net::CookieJarSettings::Deserialize(aCookieJarSettingsArgs.ref(), - getter_AddRefs(cookieJarSettings)); - trans->SetCookieJarSettings(cookieJarSettings); - } - - rv = nsContentUtils::IPCTransferableDataToTransferable( - aTransferableData, aIsPrivateData, aRequestingPrincipal, - aContentPolicyType, true /* aAddDataFlavor */, trans, + rv = nsContentUtils::IPCTransferableToTransferable( + aTransferable, true /* aAddDataFlavor */, trans, true /* aFilterUnknownFlavors */); NS_ENSURE_SUCCESS(rv, IPC_OK()); diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index d4a7f4bc0ac21..2821746c9b420 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -994,12 +994,8 @@ class ContentParent final : public PContentParent, mozilla::ipc::IPCResult RecvGetGfxVars(nsTArray* aVars); - mozilla::ipc::IPCResult RecvSetClipboard( - const IPCTransferableData& aTransferableData, const bool& aIsPrivateData, - nsIPrincipal* aRequestingPrincipal, - mozilla::Maybe aCookieJarSettingsArgs, - const nsContentPolicyType& aContentPolicyType, - nsIReferrerInfo* aReferrerInfo, const int32_t& aWhichClipboard); + mozilla::ipc::IPCResult RecvSetClipboard(const IPCTransferable& aTransferable, + const int32_t& aWhichClipboard); mozilla::ipc::IPCResult RecvGetClipboard( nsTArray&& aTypes, const int32_t& aWhichClipboard, diff --git a/dom/ipc/DOMTypes.ipdlh b/dom/ipc/DOMTypes.ipdlh index 236ffc764827c..2b546a9a3ebd6 100644 --- a/dom/ipc/DOMTypes.ipdlh +++ b/dom/ipc/DOMTypes.ipdlh @@ -100,62 +100,6 @@ struct MessageData { MessageDataType data; }; -struct IPCTransferableDataString -{ - BigBuffer data; -}; - -struct IPCTransferableDataCString -{ - BigBuffer data; -}; - -struct IPCTransferableDataInputStream -{ - // NOTE: Editor currently relies on these input streams being synchronous, so - // we can't safely serialize them using IPCStream (see bug 1778565). Instead, - // they're serialized as a `BigBuffer`, and converted to a nsStringInputStream - // on the receiving side. If we are able to use async streams reliably in the - // future, we could consider switching the code which adds `nsIInputStream`s - // to the transferable to use `BlobImpl` instead, for more consistency between - // image formats. - BigBuffer data; -}; - -struct IPCTransferableDataImageContainer -{ - BigBuffer data; - uint32_t width; - uint32_t height; - uint32_t stride; - SurfaceFormat format; -}; - -struct IPCTransferableDataBlob -{ - IPCBlob blob; -}; - -union IPCTransferableDataType -{ - IPCTransferableDataString; - IPCTransferableDataCString; - IPCTransferableDataInputStream; - IPCTransferableDataImageContainer; - IPCTransferableDataBlob; -}; - -struct IPCTransferableDataItem -{ - nsCString flavor; - IPCTransferableDataType data; -}; - -struct IPCTransferableData -{ - IPCTransferableDataItem[] items; -}; - struct ScreenDetails { LayoutDeviceIntRect rect; DesktopIntRect rectDisplayPix; diff --git a/dom/ipc/IPCTransferable.ipdlh b/dom/ipc/IPCTransferable.ipdlh new file mode 100644 index 0000000000000..7809e46fe2e98 --- /dev/null +++ b/dom/ipc/IPCTransferable.ipdlh @@ -0,0 +1,85 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include IPCBlob; +include NeckoChannelParams; + +using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h"; +[RefCounted] using class nsIPrincipal from "nsIPrincipal.h"; +[RefCounted] using class nsIReferrerInfo from "nsIReferrerInfo.h"; +[MoveOnly] using class mozilla::ipc::BigBuffer from "mozilla/ipc/BigBuffer.h"; + +namespace mozilla { +namespace dom { + +struct IPCTransferableDataString +{ + BigBuffer data; +}; + +struct IPCTransferableDataCString +{ + BigBuffer data; +}; + +struct IPCTransferableDataInputStream +{ + // NOTE: Editor currently relies on these input streams being synchronous, so + // we can't safely serialize them using IPCStream (see bug 1778565). Instead, + // they're serialized as a `BigBuffer`, and converted to a nsStringInputStream + // on the receiving side. If we are able to use async streams reliably in the + // future, we could consider switching the code which adds `nsIInputStream`s + // to the transferable to use `BlobImpl` instead, for more consistency between + // image formats. + BigBuffer data; +}; + +struct IPCTransferableDataImageContainer +{ + BigBuffer data; + uint32_t width; + uint32_t height; + uint32_t stride; + SurfaceFormat format; +}; + +struct IPCTransferableDataBlob +{ + IPCBlob blob; +}; + +union IPCTransferableDataType +{ + IPCTransferableDataString; + IPCTransferableDataCString; + IPCTransferableDataInputStream; + IPCTransferableDataImageContainer; + IPCTransferableDataBlob; +}; + +struct IPCTransferableDataItem +{ + nsCString flavor; + IPCTransferableDataType data; +}; + +struct IPCTransferableData +{ + IPCTransferableDataItem[] items; +}; + +struct IPCTransferable +{ + IPCTransferableData data; + bool isPrivateData; + nullable nsIPrincipal requestingPrincipal; + CookieJarSettingsArgs? cookieJarSettings; + nsContentPolicyType contentPolicyType; + nullable nsIReferrerInfo referrerInfo; +}; + +} // namespace dom +} // namespace mozilla diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 245aa6b3aaaf3..84f91e2eba1ec 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -23,6 +23,7 @@ include NeckoChannelParams; include WindowGlobalTypes; include IPCBlob; include IPCStream; +include IPCTransferable; include URIParams; include PPrintingTypes; include PTabContext; @@ -864,6 +865,7 @@ child: * Call PasteTransferable via a controller on the content process * to handle the command content event, "pasteTransferable". */ + // XXX Do we really need data other than IPCTransferableData? See bug 1833172. async PasteTransferable(IPCTransferableData aTransferableData, bool aIsPrivateData, nullable nsIPrincipal aRequestingPrincipal, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index a6ea2a7ef8da3..6a806da36360e 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -48,6 +48,7 @@ include DOMTypes; include WindowGlobalTypes; include IPCBlob; include IPCStream; +include IPCTransferable; include PPrintingTypes; include PTabContext; include ProtocolTypes; @@ -1217,12 +1218,7 @@ parent: bool fromChromeContext, ClonedMessageData stack); // Places the items within dataTransfer on the clipboard. - async SetClipboard(IPCTransferableData aTransferableData, - bool aIsPrivateData, - nullable nsIPrincipal aRequestingPrincipal, - CookieJarSettingsArgs? cookieJarSettings, - nsContentPolicyType aContentPolicyType, - nullable nsIReferrerInfo aReferrerInfo, + async SetClipboard(IPCTransferable aTransferable, int32_t aWhichClipboard); // Given a list of supported types, returns the clipboard data for the diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 6bccd1000f69d..32ac8710c20d1 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -168,6 +168,7 @@ PREPROCESSED_IPDL_SOURCES += [ IPDL_SOURCES += [ "DOMTypes.ipdlh", + "IPCTransferable.ipdlh", "MemoryReportTypes.ipdlh", "PColorPicker.ipdl", "PContentPermission.ipdlh", diff --git a/widget/ClipboardWriteRequestChild.cpp b/widget/ClipboardWriteRequestChild.cpp index 2e5f2bd62fd4b..20daf01c5d3e5 100644 --- a/widget/ClipboardWriteRequestChild.cpp +++ b/widget/ClipboardWriteRequestChild.cpp @@ -32,20 +32,10 @@ ClipboardWriteRequestChild::SetData(nsITransferable* aTransferable, #endif mIsValid = false; - IPCTransferableData ipcTransferableData; - nsContentUtils::TransferableToIPCTransferableData( - aTransferable, &ipcTransferableData, false, nullptr); - Maybe cookieJarSettingsArgs; - if (nsCOMPtr cookieJarSettings = - aTransferable->GetCookieJarSettings()) { - net::CookieJarSettingsArgs args; - net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(args); - cookieJarSettingsArgs = Some(std::move(args)); - } - SendSetData(std::move(ipcTransferableData), aTransferable->GetIsPrivateData(), - aTransferable->GetRequestingPrincipal(), cookieJarSettingsArgs, - aTransferable->GetContentPolicyType(), - aTransferable->GetReferrerInfo()); + IPCTransferable ipcTransferable; + nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcTransferable, + false, nullptr); + SendSetData(std::move(ipcTransferable)); return NS_OK; } diff --git a/widget/ClipboardWriteRequestParent.cpp b/widget/ClipboardWriteRequestParent.cpp index 8cf751ee547a2..c7d99c61ce08a 100644 --- a/widget/ClipboardWriteRequestParent.cpp +++ b/widget/ClipboardWriteRequestParent.cpp @@ -55,16 +55,12 @@ NS_IMETHODIMP ClipboardWriteRequestParent::OnComplete(nsresult aResult) { } IPCResult ClipboardWriteRequestParent::RecvSetData( - const IPCTransferableData& aTransferableData, const bool& aIsPrivateData, - nsIPrincipal* aRequestingPrincipal, - Maybe aCookieJarSettingsArgs, - const nsContentPolicyType& aContentPolicyType, - nsIReferrerInfo* aReferrerInfo) { + const IPCTransferable& aTransferable) { if (!mManager->ValidatePrincipal( - aRequestingPrincipal, + aTransferable.requestingPrincipal(), {ContentParent::ValidatePrincipalOptions::AllowNullPtr})) { ContentParent::LogAndAssertFailedPrincipalValidationInfo( - aRequestingPrincipal, __func__); + aTransferable.requestingPrincipal(), __func__); } if (!mAsyncSetClipboardData) { @@ -80,16 +76,8 @@ IPCResult ClipboardWriteRequestParent::RecvSetData( } trans->Init(nullptr); - trans->SetReferrerInfo(aReferrerInfo); - if (aCookieJarSettingsArgs.isSome()) { - nsCOMPtr cookieJarSettings; - net::CookieJarSettings::Deserialize(aCookieJarSettingsArgs.ref(), - getter_AddRefs(cookieJarSettings)); - trans->SetCookieJarSettings(cookieJarSettings); - } - rv = nsContentUtils::IPCTransferableDataToTransferable( - aTransferableData, aIsPrivateData, aRequestingPrincipal, - aContentPolicyType, true /* aAddDataFlavor */, trans, + rv = nsContentUtils::IPCTransferableToTransferable( + aTransferable, true /* aAddDataFlavor */, trans, true /* aFilterUnknownFlavors */); if (NS_FAILED(rv)) { mAsyncSetClipboardData->Abort(rv); diff --git a/widget/ClipboardWriteRequestParent.h b/widget/ClipboardWriteRequestParent.h index cd7b0b0c99f78..07c09ded43383 100644 --- a/widget/ClipboardWriteRequestParent.h +++ b/widget/ClipboardWriteRequestParent.h @@ -29,12 +29,7 @@ class ClipboardWriteRequestParent final nsresult Init(const int32_t& aClipboardType); - IPCResult RecvSetData(const IPCTransferableData& aTransferableData, - const bool& aIsPrivateData, - nsIPrincipal* aRequestingPrincipal, - Maybe aCookieJarSettingsArgs, - const nsContentPolicyType& aContentPolicyType, - nsIReferrerInfo* aReferrerInfo); + IPCResult RecvSetData(const IPCTransferable& aTransferable); IPCResult Recv__delete__(nsresult aReason); void ActorDestroy(ActorDestroyReason aReason) override final; diff --git a/widget/PClipboardWriteRequest.ipdl b/widget/PClipboardWriteRequest.ipdl index cc5e30f2f0619..54b7c9a136be8 100644 --- a/widget/PClipboardWriteRequest.ipdl +++ b/widget/PClipboardWriteRequest.ipdl @@ -5,6 +5,7 @@ include protocol PContent; include DOMTypes; +include IPCTransferable; include NeckoChannelParams; using nsContentPolicyType from "nsIContentPolicy.h"; @@ -15,12 +16,7 @@ protocol PClipboardWriteRequest { manager PContent; parent: - async SetData(IPCTransferableData aTransferableData, - bool aIsPrivateData, - nullable nsIPrincipal aRequestingPrincipal, - CookieJarSettingsArgs? cookieJarSettings, - nsContentPolicyType aContentPolicyType, - nullable nsIReferrerInfo aReferrerInfo); + async SetData(IPCTransferable aTransferable); both: async __delete__(nsresult aResult); diff --git a/widget/nsClipboardProxy.cpp b/widget/nsClipboardProxy.cpp index bd46f6d94f3a6..04e5cdc7d518f 100644 --- a/widget/nsClipboardProxy.cpp +++ b/widget/nsClipboardProxy.cpp @@ -35,27 +35,10 @@ nsClipboardProxy::SetData(nsITransferable* aTransferable, #endif ContentChild* child = ContentChild::GetSingleton(); - - IPCTransferableData ipcTransferableData; - nsContentUtils::TransferableToIPCTransferableData( - aTransferable, &ipcTransferableData, false, nullptr); - - Maybe cookieJarSettingsArgs; - if (nsCOMPtr cookieJarSettings = - aTransferable->GetCookieJarSettings()) { - mozilla::net::CookieJarSettingsArgs args; - mozilla::net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(args); - cookieJarSettingsArgs = Some(args); - } - bool isPrivateData = aTransferable->GetIsPrivateData(); - nsCOMPtr requestingPrincipal = - aTransferable->GetRequestingPrincipal(); - nsContentPolicyType contentPolicyType = aTransferable->GetContentPolicyType(); - nsCOMPtr referrerInfo = aTransferable->GetReferrerInfo(); - child->SendSetClipboard(std::move(ipcTransferableData), isPrivateData, - requestingPrincipal, cookieJarSettingsArgs, - contentPolicyType, referrerInfo, aWhichClipboard); - + IPCTransferable ipcTransferable; + nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcTransferable, + false, nullptr); + child->SendSetClipboard(std::move(ipcTransferable), aWhichClipboard); return NS_OK; }